go-hep.org/x/hep@v0.38.1/groot/rcont/list.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 List struct {
    19  	obj  rbase.Object
    20  	name string
    21  	objs []root.Object
    22  	opts []string
    23  }
    24  
    25  func NewList(name string, objs []root.Object) *List {
    26  	list := &List{
    27  		obj:  rbase.Object{ID: 0x0, Bits: 0x3000000},
    28  		name: name,
    29  		objs: objs,
    30  		opts: make([]string, len(objs)),
    31  	}
    32  	return list
    33  }
    34  
    35  func (*List) RVersion() int16 {
    36  	return rvers.List
    37  }
    38  
    39  func (*List) Class() string {
    40  	return "TList"
    41  }
    42  
    43  func (li *List) UID() uint32 {
    44  	return li.obj.UID()
    45  }
    46  
    47  func (li *List) Name() string {
    48  	if li.name == "" {
    49  		return "TList"
    50  	}
    51  	return li.name
    52  }
    53  
    54  func (*List) Title() string {
    55  	return "Doubly linked list"
    56  }
    57  
    58  func (li *List) At(i int) root.Object {
    59  	return li.objs[i]
    60  }
    61  
    62  func (li *List) Last() int {
    63  	panic("not implemented")
    64  }
    65  
    66  func (li *List) Len() int {
    67  	return len(li.objs)
    68  }
    69  
    70  func (li *List) Append(obj root.Object) {
    71  	li.objs = append(li.objs, obj)
    72  	li.opts = append(li.opts, "")
    73  }
    74  
    75  func (li *List) MarshalROOT(w *rbytes.WBuffer) (int, error) {
    76  	if w.Err() != nil {
    77  		return 0, w.Err()
    78  	}
    79  
    80  	hdr := w.WriteHeader(li.Class(), li.RVersion())
    81  	w.WriteObject(&li.obj)
    82  	w.WriteString(li.name)
    83  	w.WriteI32(int32(len(li.objs)))
    84  	for i, obj := range li.objs {
    85  		w.WriteObjectAny(obj)
    86  		w.WriteString(li.opts[i])
    87  	}
    88  
    89  	return w.SetHeader(hdr)
    90  }
    91  
    92  func (li *List) UnmarshalROOT(r *rbytes.RBuffer) error {
    93  	if r.Err() != nil {
    94  		return r.Err()
    95  	}
    96  
    97  	hdr := r.ReadHeader(li.Class(), li.RVersion())
    98  	if hdr.Vers <= 3 {
    99  		return fmt.Errorf("rcont: TList version too old (%d <= 3)", hdr.Vers)
   100  	}
   101  
   102  	r.ReadObject(&li.obj)
   103  	li.name = r.ReadString()
   104  	size := int(r.ReadI32())
   105  
   106  	li.objs = make([]root.Object, size)
   107  	li.opts = make([]string, size)
   108  
   109  	for i := range li.objs {
   110  		obj := r.ReadObjectAny()
   111  		// obj := r.ReadObjectRef()
   112  		if obj == nil {
   113  			panic(fmt.Errorf("nil obj ref: %w", r.Err())) // FIXME(sbinet)
   114  			// return r.Err()
   115  		}
   116  		li.objs[i] = obj
   117  		li.opts[i] = r.ReadString()
   118  	}
   119  
   120  	r.CheckHeader(hdr)
   121  	return r.Err()
   122  }
   123  
   124  func (l *List) RMembers() (mbrs []rbytes.Member) {
   125  	var (
   126  		arr  []root.Object
   127  		opts []string
   128  	)
   129  	if len(l.objs) > 0 {
   130  		arr = l.objs
   131  		opts = l.opts
   132  	}
   133  	mbrs = append(mbrs, []rbytes.Member{
   134  		{Name: "name", Value: &l.name},
   135  		{Name: "arr", Value: &arr},
   136  		{Name: "opt", Value: &opts},
   137  	}...)
   138  
   139  	return mbrs
   140  }
   141  
   142  type HashList struct {
   143  	List
   144  }
   145  
   146  func (*HashList) RVersion() int16 {
   147  	return rvers.HashList
   148  }
   149  
   150  func (*HashList) Class() string {
   151  	return "THashList"
   152  }
   153  
   154  func (li *HashList) MarshalROOT(w *rbytes.WBuffer) (int, error) {
   155  	return li.List.MarshalROOT(w)
   156  }
   157  
   158  func (li *HashList) UnmarshalROOT(r *rbytes.RBuffer) error {
   159  	return li.List.UnmarshalROOT(r)
   160  }
   161  
   162  func init() {
   163  	{
   164  		f := func() reflect.Value {
   165  			o := NewList("", nil)
   166  			return reflect.ValueOf(o)
   167  		}
   168  		rtypes.Factory.Add("TList", f)
   169  	}
   170  	{
   171  		f := func() reflect.Value {
   172  			o := &HashList{}
   173  			return reflect.ValueOf(o)
   174  		}
   175  		rtypes.Factory.Add("THashList", f)
   176  	}
   177  }
   178  
   179  var (
   180  	_ root.Object        = (*List)(nil)
   181  	_ root.UIDer         = (*List)(nil)
   182  	_ root.Collection    = (*List)(nil)
   183  	_ root.SeqCollection = (*List)(nil)
   184  	_ root.List          = (*List)(nil)
   185  	_ rbytes.Marshaler   = (*List)(nil)
   186  	_ rbytes.Unmarshaler = (*List)(nil)
   187  )
   188  
   189  var (
   190  	_ root.Object        = (*HashList)(nil)
   191  	_ root.UIDer         = (*HashList)(nil)
   192  	_ root.Collection    = (*HashList)(nil)
   193  	_ root.SeqCollection = (*HashList)(nil)
   194  	_ root.List          = (*HashList)(nil)
   195  	_ rbytes.Marshaler   = (*HashList)(nil)
   196  	_ rbytes.Unmarshaler = (*HashList)(nil)
   197  )