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  )