go-hep.org/x/hep@v0.38.1/xrootd/xrdproto/read/read.go (about) 1 // Copyright ©2018 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package read contains the structures describing request and response for read request. 6 // See xrootd protocol specification (http://xrootd.org/doc/dev45/XRdv310.pdf, p. 99) for details. 7 package read // import "go-hep.org/x/hep/xrootd/xrdproto/read" 8 9 import ( 10 "fmt" 11 12 "go-hep.org/x/hep/xrootd/internal/xrdenc" 13 "go-hep.org/x/hep/xrootd/xrdfs" 14 "go-hep.org/x/hep/xrootd/xrdproto" 15 ) 16 17 // RequestID is the id of the request, it is sent as part of message. 18 // See xrootd protocol specification for details: http://xrootd.org/doc/dev45/XRdv310.pdf, 2.3 Client Request Format. 19 const RequestID uint16 = 3013 20 21 // Response is a response for the read request, which contains the read data. 22 type Response struct { 23 Data []uint8 24 } 25 26 // MarshalXrd implements xrdproto.Marshaler. 27 func (o Response) MarshalXrd(wBuffer *xrdenc.WBuffer) error { 28 wBuffer.WriteBytes(o.Data) 29 return nil 30 } 31 32 // UnmarshalXrd implements xrdproto.Unmarshaler. 33 func (o *Response) UnmarshalXrd(rBuffer *xrdenc.RBuffer) error { 34 src := rBuffer.Len() 35 dst := len(o.Data) 36 if src > dst { 37 o.Data = make([]byte, src) 38 } 39 n := copy(o.Data, rBuffer.Bytes()) 40 o.Data = o.Data[:n] 41 return nil 42 } 43 44 // RespID implements xrdproto.Response.RespID. 45 func (resp *Response) RespID() uint16 { return RequestID } 46 47 // Request holds read request parameters. 48 type Request struct { 49 Handle xrdfs.FileHandle 50 Offset int64 51 Length int32 52 OptionalArgs *OptionalArgs 53 } 54 55 // Request holds optional read request parameters. 56 type OptionalArgs struct { 57 // PathID is the path id returned by bind request. 58 // The response data is sent to this path, if possible. 59 PathID xrdproto.PathID 60 _ [7]uint8 61 // ReadAhead is the slice of the pre-read requests. 62 ReadAheads []ReadAhead 63 } 64 65 // MarshalXrd implements xrdproto.Marshaler. 66 func (o OptionalArgs) MarshalXrd(wBuffer *xrdenc.WBuffer) error { 67 alen := len(o.ReadAheads)*16 + 8 68 wBuffer.WriteLen(alen) 69 wBuffer.WriteU8(uint8(o.PathID)) 70 wBuffer.Next(7) 71 for _, x := range o.ReadAheads { 72 err := x.MarshalXrd(wBuffer) 73 if err != nil { 74 return err 75 } 76 } 77 return nil 78 } 79 80 // UnmarshalXrd implements xrdproto.Unmarshaler. 81 func (o *OptionalArgs) UnmarshalXrd(rBuffer *xrdenc.RBuffer) error { 82 alen := rBuffer.ReadLen() 83 o.PathID = xrdproto.PathID(rBuffer.ReadU8()) 84 rBuffer.Skip(7) 85 if alen < 8 || (alen-8)%16 != 0 { 86 return fmt.Errorf("xrootd: invalid alen is specified: should be greater or equal to 8"+ 87 "and (alen - 8) should be dividable by 16, got: %v", alen) 88 } 89 if alen <= 8 { 90 return nil 91 } 92 o.ReadAheads = make([]ReadAhead, (alen-8)/16) 93 for i := range o.ReadAheads { 94 err := o.ReadAheads[i].UnmarshalXrd(rBuffer) 95 if err != nil { 96 return err 97 } 98 } 99 return nil 100 } 101 102 // ReadAhead is the pre-read request. It is considered only a hint 103 // and can be used to schedule the pre-reading of data that will be asked 104 // in the very near future. 105 type ReadAhead struct { 106 Handle xrdfs.FileHandle 107 Length int32 108 Offset int64 109 } 110 111 // MarshalXrd implements xrdproto.Marshaler. 112 func (o ReadAhead) MarshalXrd(wBuffer *xrdenc.WBuffer) error { 113 wBuffer.WriteBytes(o.Handle[:]) 114 wBuffer.WriteI32(o.Length) 115 wBuffer.WriteI64(o.Offset) 116 return nil 117 } 118 119 // UnmarshalXrd implements xrdproto.Unmarshaler. 120 func (o *ReadAhead) UnmarshalXrd(rBuffer *xrdenc.RBuffer) error { 121 rBuffer.ReadBytes(o.Handle[:]) 122 o.Length = rBuffer.ReadI32() 123 o.Offset = rBuffer.ReadI64() 124 return nil 125 } 126 127 // ReqID implements xrdproto.Request.ReqID. 128 func (req *Request) ReqID() uint16 { return RequestID } 129 130 // ShouldSign implements xrdproto.Request.ShouldSign. 131 func (req *Request) ShouldSign() bool { return false } 132 133 // MarshalXrd implements xrdproto.Marshaler. 134 func (o Request) MarshalXrd(wBuffer *xrdenc.WBuffer) error { 135 wBuffer.WriteBytes(o.Handle[:]) 136 wBuffer.WriteI64(o.Offset) 137 wBuffer.WriteI32(o.Length) 138 if o.OptionalArgs == nil { 139 wBuffer.WriteLen(0) 140 return nil 141 } 142 return o.OptionalArgs.MarshalXrd(wBuffer) 143 } 144 145 // UnmarshalXrd implements xrdproto.Unmarshaler. 146 func (o *Request) UnmarshalXrd(rBuffer *xrdenc.RBuffer) error { 147 rBuffer.ReadBytes(o.Handle[:]) 148 o.Offset = rBuffer.ReadI64() 149 o.Length = rBuffer.ReadI32() 150 if rBuffer.Len() > 4 { 151 o.OptionalArgs = &OptionalArgs{} 152 return o.OptionalArgs.UnmarshalXrd(rBuffer) 153 } 154 alen := rBuffer.ReadLen() 155 if alen == 0 { 156 return nil 157 } 158 return fmt.Errorf("xrootd: no data is passed after alen of %d", alen) 159 } 160 161 // PathID implements xrdproto.DataRequest.PathID. 162 func (o *Request) PathID() xrdproto.PathID { 163 if o.OptionalArgs == nil { 164 return 0 165 } 166 return o.OptionalArgs.PathID 167 } 168 169 // PathID implements xrdproto.DataRequest.SetPathID. 170 func (o *Request) SetPathID(pathID xrdproto.PathID) { 171 if o.OptionalArgs == nil { 172 o.OptionalArgs = &OptionalArgs{PathID: pathID} 173 return 174 } 175 o.OptionalArgs.PathID = pathID 176 } 177 178 // PathID implements xrdproto.DataRequest.Direction. 179 func (o *Request) Direction() xrdproto.DataRequestDirection { 180 return xrdproto.DataRequestRead 181 } 182 183 // PathID implements xrdproto.DataRequest.PathData. 184 func (o *Request) PathData() []byte { 185 return nil 186 } 187 188 var ( 189 _ xrdproto.DataRequest = (*Request)(nil) 190 )