go-hep.org/x/hep@v0.38.1/groot/rcont/refarray.go (about)

     1  // Copyright ©2017 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 rcont
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  
    11  	"go-hep.org/x/hep/groot/rbase"
    12  	"go-hep.org/x/hep/groot/rbytes"
    13  	"go-hep.org/x/hep/groot/root"
    14  	"go-hep.org/x/hep/groot/rtypes"
    15  	"go-hep.org/x/hep/groot/rvers"
    16  )
    17  
    18  type RefArray struct {
    19  	obj  rbase.Object
    20  	name string
    21  	// pid   *rbase.ProcessID // FIXME(sbinet)
    22  	refs  []uint32 // uids of referenced objects
    23  	lower int32    // lower bound of array
    24  	last  int32    // last element in array containing an object
    25  }
    26  
    27  func NewRefArray() *RefArray {
    28  	return &RefArray{
    29  		refs: make([]uint32, 0),
    30  		last: -1,
    31  	}
    32  }
    33  
    34  func (*RefArray) RVersion() int16 {
    35  	return rvers.RefArray
    36  }
    37  
    38  func (*RefArray) Class() string {
    39  	return "TRefArray"
    40  }
    41  
    42  func (arr *RefArray) UID() uint32 {
    43  	return arr.obj.UID()
    44  }
    45  
    46  func (arr *RefArray) Name() string {
    47  	if arr.name == "" {
    48  		return "TRefArray"
    49  	}
    50  	return arr.name
    51  }
    52  
    53  func (*RefArray) Title() string {
    54  	return "An array of references to TObjects"
    55  }
    56  
    57  func (arr *RefArray) At(i int) root.Object {
    58  	panic("not implemented")
    59  }
    60  
    61  func (arr *RefArray) Last() int {
    62  	return int(arr.last)
    63  }
    64  
    65  func (arr *RefArray) Len() int {
    66  	return len(arr.refs)
    67  }
    68  
    69  func (arr *RefArray) UIDs() []uint32 {
    70  	return arr.refs
    71  }
    72  
    73  func (arr *RefArray) MarshalROOT(w *rbytes.WBuffer) (int, error) {
    74  	if w.Err() != nil {
    75  		return 0, w.Err()
    76  	}
    77  
    78  	hdr := w.WriteHeader(arr.Class(), arr.RVersion())
    79  	w.WriteObject(&arr.obj)
    80  	w.WriteString(arr.name)
    81  	w.WriteI32(int32(len(arr.refs)))
    82  	w.WriteI32(arr.lower)
    83  	w.WriteI16(0) // FIXME(sbinet): handle fPID ProcessID
    84  
    85  	w.WriteArrayU32(arr.refs)
    86  
    87  	return w.SetHeader(hdr)
    88  }
    89  
    90  func (arr *RefArray) UnmarshalROOT(r *rbytes.RBuffer) error {
    91  	if r.Err() != nil {
    92  		return r.Err()
    93  	}
    94  
    95  	hdr := r.ReadHeader(arr.Class(), arr.RVersion())
    96  	if hdr.Vers < 1 {
    97  		return fmt.Errorf("rcont: TRefArray version too old (%d < 1)", hdr.Vers)
    98  	}
    99  
   100  	r.ReadObject(&arr.obj)
   101  	arr.name = r.ReadString()
   102  	size := int(r.ReadI32())
   103  	arr.lower = r.ReadI32()
   104  	arr.last = -1
   105  	_ = r.ReadU16() // pid
   106  
   107  	arr.refs = make([]uint32, size)
   108  	for i := range arr.refs {
   109  		arr.refs[i] = r.ReadU32()
   110  		if arr.refs[i] != 0 {
   111  			arr.last = int32(i)
   112  		}
   113  	}
   114  
   115  	r.CheckHeader(hdr)
   116  	return r.Err()
   117  }
   118  
   119  func init() {
   120  	f := func() reflect.Value {
   121  		o := NewRefArray()
   122  		return reflect.ValueOf(o)
   123  	}
   124  	rtypes.Factory.Add("TRefArray", f)
   125  }
   126  
   127  var (
   128  	_ root.Object        = (*RefArray)(nil)
   129  	_ root.Named         = (*RefArray)(nil)
   130  	_ root.SeqCollection = (*RefArray)(nil)
   131  	_ rbytes.Marshaler   = (*RefArray)(nil)
   132  	_ rbytes.Unmarshaler = (*RefArray)(nil)
   133  )