go-hep.org/x/hep@v0.38.1/groot/rdict/rstreamer.go (about)

     1  // Copyright 2020 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 rdict
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  	"strconv"
    11  	"strings"
    12  
    13  	"go-hep.org/x/hep/groot/rbase"
    14  	"go-hep.org/x/hep/groot/rbytes"
    15  	"go-hep.org/x/hep/groot/rmeta"
    16  	"go-hep.org/x/hep/groot/root"
    17  	"go-hep.org/x/hep/groot/rtypes"
    18  	"go-hep.org/x/hep/groot/rvers"
    19  )
    20  
    21  // RStreamerOf returns a read-streamer for the i-th element of the provided
    22  // streamer info and stream kind.
    23  func RStreamerOf(sinfo rbytes.StreamerInfo, i int, kind rbytes.StreamKind) (rbytes.RStreamer, error) {
    24  	si, ok := sinfo.(*StreamerInfo)
    25  	if !ok {
    26  		return nil, fmt.Errorf("rdict: not a rdict.StreamerInfo (got=%T)", sinfo)
    27  	}
    28  
    29  	err := si.BuildStreamers()
    30  	if err != nil {
    31  		return nil, fmt.Errorf("rdict: could not build streamers: %w", err)
    32  	}
    33  
    34  	rops := make([]rstreamer, len(si.descr))
    35  	switch kind {
    36  	case rbytes.ObjectWise:
    37  		copy(rops, si.roops)
    38  	case rbytes.MemberWise:
    39  		copy(rops, si.rmops)
    40  	default:
    41  		return nil, fmt.Errorf("rdict: invalid stream kind %v", kind)
    42  	}
    43  
    44  	return newRStreamerElem(i, si, kind, rops)
    45  }
    46  
    47  type rstreamerElem struct {
    48  	recv any
    49  	rop  *rstreamer
    50  	i    int // streamer-element index (or -1 for the whole StreamerInfo)
    51  	kind rbytes.StreamKind
    52  	si   *StreamerInfo
    53  	se   rbytes.StreamerElement
    54  }
    55  
    56  func newRStreamerElem(i int, si *StreamerInfo, kind rbytes.StreamKind, rops []rstreamer) (*rstreamerElem, error) {
    57  	return &rstreamerElem{
    58  		recv: nil,
    59  		rop:  &rops[i],
    60  		i:    i,
    61  		kind: kind,
    62  		si:   si,
    63  		se:   si.elems[i],
    64  	}, nil
    65  }
    66  
    67  func (rr *rstreamerElem) Bind(recv any) error {
    68  	rv := reflect.ValueOf(recv)
    69  	if rv.Kind() != reflect.Ptr {
    70  		return fmt.Errorf("rdict: invalid kind (got=%T, want=pointer)", recv)
    71  	}
    72  	rr.recv = recv
    73  	rr.rop.cfg.offset = -1 // binding directly to 'recv'. assume no offset is to be applied
    74  	return nil
    75  }
    76  
    77  func (rr *rstreamerElem) RStreamROOT(r *rbytes.RBuffer) error {
    78  	err := rr.rop.rstream(r, rr.recv)
    79  	if err != nil {
    80  		var (
    81  			name  = rr.si.Name()
    82  			ename = rr.se.TypeName()
    83  		)
    84  		return fmt.Errorf(
    85  			"rdict: could not read element %d (type=%q) from %q: %w",
    86  			rr.i, ename, name, err,
    87  		)
    88  	}
    89  	return nil
    90  }
    91  
    92  func (rr *rstreamerElem) Count(f func() int) error {
    93  	rr.rop.cfg.count = f
    94  	return nil
    95  }
    96  
    97  var (
    98  	_ rbytes.RStreamer = (*rstreamerElem)(nil)
    99  	_ rbytes.Binder    = (*rstreamerElem)(nil)
   100  	_ rbytes.Counter   = (*rstreamerElem)(nil)
   101  )
   102  
   103  type rstreamOp interface {
   104  	rstream(r *rbytes.RBuffer, recv any) error
   105  }
   106  
   107  // type rstreamBufOp interface {
   108  // 	rstreamBuf(r *rbytes.RBuffer, recv reflect.Value, descr *elemDescr, beg, end int, n int, offset int, arrmode arrayMode) error
   109  // }
   110  
   111  type ropFunc func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error
   112  
   113  type rstreamer struct {
   114  	op  ropFunc
   115  	cfg *streamerConfig
   116  }
   117  
   118  func (rr rstreamer) rstream(r *rbytes.RBuffer, recv any) error {
   119  	return rr.op(r, recv, rr.cfg)
   120  }
   121  
   122  var (
   123  	_ rstreamOp = (*rstreamer)(nil)
   124  )
   125  
   126  func (si *StreamerInfo) makeROp(sictx rbytes.StreamerInfoContext, i int, descr elemDescr) rstreamer {
   127  	cfg := &streamerConfig{si, i, &descr, descr.offset, 0, nil}
   128  	switch descr.otype {
   129  	case rmeta.Base:
   130  		var (
   131  			se       = descr.elem.(*StreamerBase)
   132  			typename = se.Name()
   133  			typevers = se.vbase
   134  			rop      = ropFrom(sictx, typename, int16(typevers), rmeta.Base, nil)
   135  		)
   136  		return rstreamer{rop, cfg}
   137  
   138  	case rmeta.Bool:
   139  		return rstreamer{rstreamBool, cfg}
   140  	case rmeta.Char:
   141  		return rstreamer{rstreamI8, cfg}
   142  	case rmeta.Short:
   143  		return rstreamer{rstreamI16, cfg}
   144  	case rmeta.Int:
   145  		return rstreamer{rstreamI32, cfg}
   146  	case rmeta.Long, rmeta.Long64:
   147  		return rstreamer{rstreamI64, cfg}
   148  	case rmeta.UChar:
   149  		return rstreamer{rstreamU8, cfg}
   150  	case rmeta.UShort:
   151  		return rstreamer{rstreamU16, cfg}
   152  	case rmeta.UInt:
   153  		return rstreamer{rstreamU32, cfg}
   154  	case rmeta.ULong, rmeta.ULong64:
   155  		return rstreamer{rstreamU64, cfg}
   156  	case rmeta.Float32:
   157  		return rstreamer{rstreamF32, cfg}
   158  	case rmeta.Float64:
   159  		return rstreamer{rstreamF64, cfg}
   160  	case rmeta.Bits:
   161  		return rstreamer{rstreamBits, cfg}
   162  	case rmeta.Float16:
   163  		return rstreamer{rstreamF16(descr.elem), cfg}
   164  	case rmeta.Double32:
   165  		return rstreamer{rstreamD32(descr.elem), cfg}
   166  
   167  	case rmeta.Counter:
   168  		se := descr.elem.(*StreamerBasicType)
   169  		switch se.esize {
   170  		case 4:
   171  			return rstreamer{rstreamI32, cfg}
   172  		case 8:
   173  			return rstreamer{rstreamI64, cfg}
   174  		default:
   175  			panic(fmt.Errorf("rdict: invalid counter size (%d) in %#v", se.esize, se))
   176  		}
   177  
   178  	case rmeta.CharStar:
   179  		return rstreamer{rstreamTString, cfg}
   180  
   181  	case rmeta.TNamed:
   182  		return rstreamer{rstreamTNamed, cfg}
   183  	case rmeta.TObject:
   184  		return rstreamer{rstreamTObject, cfg}
   185  	case rmeta.TString, rmeta.STLstring:
   186  		return rstreamer{rstreamTString, cfg}
   187  
   188  	case rmeta.STL:
   189  		var (
   190  			se       = descr.elem
   191  			newClass = descr.nclass
   192  			oldClass = descr.oclass
   193  			// _, isSTLbase = se.(*StreamerBase) // FIXME(sbinet)
   194  		)
   195  
   196  		switch {
   197  		case se.ArrayLen() <= 1:
   198  			switch {
   199  			case newClass != oldClass:
   200  				panic("rdict: rmeta.STL (w/ old-class != new-class) not implemented")
   201  			default:
   202  				switch se := se.(type) {
   203  				default:
   204  					panic(fmt.Errorf("rdict: invalid streamer element: %#v", se))
   205  
   206  				case *StreamerSTLstring:
   207  					return rstreamer{
   208  						rstreamType("string", rstreamStdString),
   209  						cfg,
   210  					}
   211  
   212  				case *StreamerSTL:
   213  					switch se.STLType() {
   214  					case rmeta.STLvector, rmeta.STLlist, rmeta.STLdeque, rmeta.STLend:
   215  						var (
   216  							ct       = se.ContainedType()
   217  							typename = se.TypeName()
   218  							enames   = rmeta.CxxTemplateFrom(typename).Args
   219  							rop      = ropFrom(sictx, enames[0], -1, ct, &descr)
   220  						)
   221  						return rstreamer{
   222  							rstreamType(typename, rstreamStdSlice(typename, rop)),
   223  							cfg,
   224  						}
   225  
   226  					case rmeta.STLset, rmeta.STLmultiset, rmeta.STLunorderedset, rmeta.STLunorderedmultiset:
   227  						var (
   228  							ct       = se.ContainedType()
   229  							typename = se.TypeName()
   230  							enames   = rmeta.CxxTemplateFrom(typename).Args
   231  							rop      = ropFrom(sictx, enames[0], -1, ct, &descr)
   232  						)
   233  						return rstreamer{
   234  							rstreamType(typename, rstreamStdSet(typename, rop)),
   235  							cfg,
   236  						}
   237  
   238  					case rmeta.STLmap, rmeta.STLunorderedmap, rmeta.STLmultimap, rmeta.STLunorderedmultimap:
   239  						var (
   240  							ct     = se.ContainedType()
   241  							enames = rmeta.CxxTemplateFrom(se.TypeName()).Args
   242  							kname  = enames[0]
   243  							vname  = enames[1]
   244  						)
   245  
   246  						krop := ropFrom(sictx, kname, -1, ct, &descr)
   247  						vrop := ropFrom(sictx, vname, -1, ct, &descr)
   248  						return rstreamer{
   249  							rstreamStdMap(kname, vname, krop, vrop),
   250  							cfg,
   251  						}
   252  
   253  					case rmeta.STLbitset:
   254  						var (
   255  							typename = se.TypeName()
   256  							enames   = rmeta.CxxTemplateFrom(typename).Args
   257  							n, err   = strconv.Atoi(enames[0])
   258  						)
   259  
   260  						if err != nil {
   261  							panic(fmt.Errorf("rdict: invalid STL bitset argument (type=%q): %+v", typename, err))
   262  						}
   263  						return rstreamer{
   264  							rstreamType(typename, rstreamStdBitset(typename, n)),
   265  							cfg,
   266  						}
   267  
   268  					default:
   269  						panic(fmt.Errorf("rdict: STL container type=%v not handled", se.STLType()))
   270  					}
   271  				}
   272  			}
   273  		default:
   274  			panic("rdict: rmeta.STL (w/ array-len > 1) not implemented")
   275  			//			switch {
   276  			//			case newClass != oldClass:
   277  			//				panic("not implemented")
   278  			//			default:
   279  			//				return rstreamer{
   280  			//					rstreamSTL(rstreamSTLArrayMbrWise, rstreamSTLObjWise, descr.oclass),
   281  			//					&streamerConfig{si, i, &descr, descr.offset, se.ArrayLen()},
   282  			//				}
   283  			//			}
   284  		}
   285  
   286  	case rmeta.Conv + rmeta.Bool:
   287  		return rstreamer{rstreamCnv(descr.ntype, rstreamBool), cfg}
   288  
   289  	case rmeta.Conv + rmeta.Char:
   290  		return rstreamer{rstreamCnv(descr.ntype, rstreamI8), cfg}
   291  
   292  	case rmeta.Conv + rmeta.Short:
   293  		return rstreamer{rstreamCnv(descr.ntype, rstreamI16), cfg}
   294  
   295  	case rmeta.Conv + rmeta.Int:
   296  		return rstreamer{rstreamCnv(descr.ntype, rstreamI32), cfg}
   297  
   298  	case rmeta.Conv + rmeta.Long, rmeta.Conv + rmeta.Long64:
   299  		return rstreamer{rstreamCnv(descr.ntype, rstreamI64), cfg}
   300  
   301  	case rmeta.Conv + rmeta.UChar:
   302  		return rstreamer{rstreamCnv(descr.ntype, rstreamU8), cfg}
   303  
   304  	case rmeta.Conv + rmeta.UShort:
   305  		return rstreamer{rstreamCnv(descr.ntype, rstreamU16), cfg}
   306  
   307  	case rmeta.Conv + rmeta.UInt:
   308  		return rstreamer{rstreamCnv(descr.ntype, rstreamU32), cfg}
   309  
   310  	case rmeta.Conv + rmeta.ULong, rmeta.Conv + rmeta.ULong64:
   311  		return rstreamer{rstreamCnv(descr.ntype, rstreamU64), cfg}
   312  
   313  	case rmeta.Conv + rmeta.Float32:
   314  		return rstreamer{rstreamCnv(descr.ntype, rstreamF32), cfg}
   315  
   316  	case rmeta.Conv + rmeta.Float64:
   317  		return rstreamer{rstreamCnv(descr.ntype, rstreamF64), cfg}
   318  
   319  	case rmeta.Conv + rmeta.Bits:
   320  		return rstreamer{rstreamCnv(descr.ntype, rstreamBits), cfg}
   321  
   322  	case rmeta.Conv + rmeta.Float16:
   323  		return rstreamer{rstreamCnv(descr.ntype, rstreamF16(descr.elem)), cfg}
   324  
   325  	case rmeta.Conv + rmeta.Double32:
   326  		return rstreamer{rstreamCnv(descr.ntype, rstreamD32(descr.elem)), cfg}
   327  
   328  		// fixed-size arrays of basic types: [32]int
   329  
   330  	case rmeta.OffsetL + rmeta.Bool:
   331  		cfg.length = descr.elem.ArrayLen()
   332  		return rstreamer{rstreamBasicArray(cfg.length, rstreamBool), cfg}
   333  
   334  	case rmeta.OffsetL + rmeta.Char:
   335  		cfg.length = descr.elem.ArrayLen()
   336  		return rstreamer{rstreamBasicArray(cfg.length, rstreamI8), cfg}
   337  
   338  	case rmeta.OffsetL + rmeta.Short:
   339  		cfg.length = descr.elem.ArrayLen()
   340  		return rstreamer{rstreamBasicArray(cfg.length, rstreamI16), cfg}
   341  
   342  	case rmeta.OffsetL + rmeta.Int:
   343  		cfg.length = descr.elem.ArrayLen()
   344  		return rstreamer{rstreamBasicArray(cfg.length, rstreamI32), cfg}
   345  
   346  	case rmeta.OffsetL + rmeta.Long, rmeta.OffsetL + rmeta.Long64:
   347  		cfg.length = descr.elem.ArrayLen()
   348  		return rstreamer{rstreamBasicArray(cfg.length, rstreamI64), cfg}
   349  
   350  	case rmeta.OffsetL + rmeta.UChar:
   351  		cfg.length = descr.elem.ArrayLen()
   352  		return rstreamer{rstreamBasicArray(cfg.length, rstreamU8), cfg}
   353  
   354  	case rmeta.OffsetL + rmeta.UShort:
   355  		cfg.length = descr.elem.ArrayLen()
   356  		return rstreamer{rstreamBasicArray(cfg.length, rstreamU16), cfg}
   357  
   358  	case rmeta.OffsetL + rmeta.UInt:
   359  		cfg.length = descr.elem.ArrayLen()
   360  		return rstreamer{rstreamBasicArray(cfg.length, rstreamU32), cfg}
   361  
   362  	case rmeta.OffsetL + rmeta.ULong, rmeta.OffsetL + rmeta.ULong64:
   363  		cfg.length = descr.elem.ArrayLen()
   364  		return rstreamer{rstreamBasicArray(cfg.length, rstreamU64), cfg}
   365  
   366  	case rmeta.OffsetL + rmeta.Float32:
   367  		cfg.length = descr.elem.ArrayLen()
   368  		return rstreamer{rstreamBasicArray(cfg.length, rstreamF32), cfg}
   369  
   370  	case rmeta.OffsetL + rmeta.Float64:
   371  		cfg.length = descr.elem.ArrayLen()
   372  		return rstreamer{rstreamBasicArray(cfg.length, rstreamF64), cfg}
   373  
   374  	case rmeta.OffsetL + rmeta.Float16:
   375  		cfg.length = descr.elem.ArrayLen()
   376  		return rstreamer{
   377  			rstreamBasicArray(cfg.length, rstreamF16(descr.elem)), // FIXME(sbinet): ROOT uses rstreamCnv here.
   378  			cfg,
   379  		}
   380  
   381  	case rmeta.OffsetL + rmeta.Double32:
   382  		cfg.length = descr.elem.ArrayLen()
   383  		return rstreamer{
   384  			rstreamBasicArray(cfg.length, rstreamD32(descr.elem)), // FIXME(sbinet): ROOT uses rstreamCnv here.
   385  			cfg,
   386  		}
   387  
   388  	case rmeta.OffsetL + rmeta.CharStar:
   389  		cfg.length = descr.elem.ArrayLen()
   390  		return rstreamer{rstreamBasicArray(cfg.length, rstreamTString), cfg}
   391  
   392  	case rmeta.OffsetL + rmeta.TString:
   393  		cfg.length = descr.elem.ArrayLen()
   394  		return rstreamer{rstreamBasicArray(cfg.length, rstreamTString), cfg}
   395  
   396  	case rmeta.OffsetL + rmeta.TObject:
   397  		cfg.length = descr.elem.ArrayLen()
   398  		return rstreamer{rstreamBasicArray(cfg.length, rstreamTObject), cfg}
   399  
   400  	case rmeta.OffsetL + rmeta.TNamed:
   401  		cfg.length = descr.elem.ArrayLen()
   402  		return rstreamer{rstreamBasicArray(cfg.length, rstreamTNamed), cfg}
   403  
   404  	case rmeta.OffsetL + rmeta.Any,
   405  		rmeta.OffsetL + rmeta.Object:
   406  		var (
   407  			se       = descr.elem
   408  			typename = se.TypeName()
   409  			rop      = ropFrom(sictx, typename, -1, 0, nil)
   410  		)
   411  		cfg.length = se.ArrayLen()
   412  		return rstreamer{rstreamBasicArray(cfg.length, rop), cfg}
   413  
   414  		// var-size arrays of basic types: [n]int
   415  
   416  	case rmeta.OffsetP + rmeta.Bool:
   417  		return rstreamer{rstreamBools, cfg}
   418  
   419  	case rmeta.OffsetP + rmeta.Char:
   420  		return rstreamer{rstreamI8s, cfg}
   421  
   422  	case rmeta.OffsetP + rmeta.Short:
   423  		return rstreamer{rstreamI16s, cfg}
   424  
   425  	case rmeta.OffsetP + rmeta.Int:
   426  		return rstreamer{rstreamI32s, cfg}
   427  
   428  	case rmeta.OffsetP + rmeta.Long, rmeta.OffsetP + rmeta.Long64:
   429  		return rstreamer{rstreamI64s, cfg}
   430  
   431  	case rmeta.OffsetP + rmeta.UChar:
   432  		return rstreamer{rstreamU8s, cfg}
   433  
   434  	case rmeta.OffsetP + rmeta.UShort:
   435  		return rstreamer{rstreamU16s, cfg}
   436  
   437  	case rmeta.OffsetP + rmeta.UInt:
   438  		return rstreamer{rstreamU32s, cfg}
   439  
   440  	case rmeta.OffsetP + rmeta.ULong, rmeta.OffsetP + rmeta.ULong64:
   441  		return rstreamer{rstreamU64s, cfg}
   442  
   443  	case rmeta.OffsetP + rmeta.Float32:
   444  		return rstreamer{rstreamF32s, cfg}
   445  
   446  	case rmeta.OffsetP + rmeta.Float64:
   447  		return rstreamer{rstreamF64s, cfg}
   448  
   449  	case rmeta.OffsetP + rmeta.Float16:
   450  		return rstreamer{rstreamF16s, cfg}
   451  
   452  	case rmeta.OffsetP + rmeta.Double32:
   453  		return rstreamer{rstreamD32s, cfg}
   454  
   455  	case rmeta.OffsetP + rmeta.CharStar:
   456  		return rstreamer{rstreamStrs, cfg}
   457  
   458  	case rmeta.Streamer:
   459  		switch se := descr.elem.(type) {
   460  		default:
   461  			panic(fmt.Errorf("rdict: invalid streamer element: %#v", se))
   462  
   463  		case *StreamerSTLstring:
   464  			return rstreamer{
   465  				rstreamType("string", rstreamStdString),
   466  				cfg,
   467  			}
   468  
   469  		case *StreamerSTL:
   470  			switch se.STLType() {
   471  			case rmeta.STLvector, rmeta.STLlist, rmeta.STLdeque, rmeta.STLend:
   472  				var (
   473  					ct       = se.ContainedType()
   474  					typename = se.TypeName()
   475  					enames   = rmeta.CxxTemplateFrom(typename).Args
   476  					rop      = ropFrom(sictx, enames[0], -1, ct, &descr)
   477  				)
   478  				return rstreamer{
   479  					rstreamType(typename, rstreamStdSlice(typename, rop)),
   480  					cfg,
   481  				}
   482  
   483  			case rmeta.STLset, rmeta.STLmultiset, rmeta.STLunorderedset, rmeta.STLunorderedmultiset:
   484  				var (
   485  					ct       = se.ContainedType()
   486  					typename = se.TypeName()
   487  					enames   = rmeta.CxxTemplateFrom(typename).Args
   488  					rop      = ropFrom(sictx, enames[0], -1, ct, &descr)
   489  				)
   490  				return rstreamer{
   491  					rstreamType(typename, rstreamStdSet(typename, rop)),
   492  					cfg,
   493  				}
   494  
   495  			case rmeta.STLmap, rmeta.STLmultimap, rmeta.STLunorderedmap, rmeta.STLunorderedmultimap:
   496  				var (
   497  					ct     = se.ContainedType()
   498  					enames = rmeta.CxxTemplateFrom(se.TypeName()).Args
   499  					kname  = enames[0]
   500  					vname  = enames[1]
   501  				)
   502  
   503  				krop := ropFrom(sictx, kname, -1, ct, &descr)
   504  				vrop := ropFrom(sictx, vname, -1, ct, &descr)
   505  				return rstreamer{
   506  					rstreamStdMap(kname, vname, krop, vrop),
   507  					cfg,
   508  				}
   509  
   510  			case rmeta.STLbitset:
   511  				var (
   512  					typename = se.TypeName()
   513  					enames   = rmeta.CxxTemplateFrom(typename).Args
   514  					n, err   = strconv.Atoi(enames[0])
   515  				)
   516  
   517  				if err != nil {
   518  					panic(fmt.Errorf("rdict: invalid STL bitset argument (type=%q): %+v", typename, err))
   519  				}
   520  				return rstreamer{
   521  					rstreamType(typename, rstreamStdBitset(typename, n)),
   522  					cfg,
   523  				}
   524  
   525  			default:
   526  				panic(fmt.Errorf("rdict: STL container type=%v not handled", se.STLType()))
   527  			}
   528  		}
   529  
   530  	case rmeta.Any, rmeta.Object:
   531  		var (
   532  			se       = descr.elem
   533  			typename = se.TypeName()
   534  			rop      = ropFrom(sictx, typename, -1, 0, nil)
   535  		)
   536  		return rstreamer{rop, cfg}
   537  
   538  	case rmeta.AnyP, rmeta.Anyp:
   539  		var (
   540  			se       = descr.elem
   541  			typename = strings.TrimRight(se.TypeName(), "*") // FIXME(sbinet): handle T** ?
   542  			rop      = ropFrom(sictx, typename, -1, 0, nil)
   543  		)
   544  		return rstreamer{
   545  			rstreamAnyPtr(rop),
   546  			cfg,
   547  		}
   548  
   549  	case rmeta.ObjectP, rmeta.Objectp:
   550  		var (
   551  			se       = descr.elem
   552  			typename = strings.TrimRight(se.TypeName(), "*") // FIXME(sbinet): handle T** ?
   553  			rop      = ropFrom(sictx, typename, -1, 0, nil)
   554  		)
   555  		return rstreamer{
   556  			rstreamObjPtr(rop),
   557  			cfg,
   558  		}
   559  
   560  	case rmeta.StreamLoop:
   561  		var (
   562  			se       = descr.elem.(*StreamerLoop)
   563  			typename = strings.TrimRight(se.TypeName(), "*") // FIXME(sbinet): handle T** ?
   564  			rop      = ropFrom(sictx, typename, -1, 0, nil)
   565  		)
   566  		return rstreamer{
   567  			rstreamBasicSlice(rop),
   568  			cfg,
   569  		}
   570  
   571  	default:
   572  		panic(fmt.Errorf("not implemented k=%d (%v)", descr.otype, descr.otype))
   573  		// return rstreamer{rstreamGeneric, &streamerConfig{si, i, &descr, descr.offset, 0}}
   574  	}
   575  }
   576  
   577  func rstreamSI(si *StreamerInfo) ropFunc {
   578  	typename := si.Name()
   579  	switch {
   580  	case typename == "TObject":
   581  		return rstreamTObject
   582  	case typename == "TNamed":
   583  		return rstreamTNamed
   584  	case typename == "TString":
   585  		return rstreamTString
   586  	case rtypes.Factory.HasKey(typename):
   587  		obj := rtypes.Factory.Get(typename)().Interface()
   588  		_, ok := obj.(rbytes.Unmarshaler)
   589  		if ok {
   590  			return func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   591  				obj := cfg.adjust(recv).(rbytes.Unmarshaler)
   592  				return obj.UnmarshalROOT(r)
   593  			}
   594  		}
   595  	}
   596  	return rstreamCat(typename, int16(si.ClassVersion()), si.roops)
   597  }
   598  
   599  func rstreamObjPtr(rop ropFunc) ropFunc {
   600  	return func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   601  		obj := r.ReadObjectAny()
   602  		if r.Err() != nil {
   603  			return r.Err()
   604  		}
   605  		rv := reflect.ValueOf(cfg.adjust(recv))
   606  		if obj == nil {
   607  			if !rv.Elem().IsNil() {
   608  				rv.Elem().Set(reflect.Value{})
   609  			}
   610  			return nil
   611  		}
   612  		rv.Elem().Set(reflect.ValueOf(obj))
   613  		return nil
   614  	}
   615  }
   616  
   617  func rstreamAnyPtr(rop ropFunc) ropFunc {
   618  	return func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   619  		obj := r.ReadObjectAny()
   620  		if r.Err() != nil {
   621  			return r.Err()
   622  		}
   623  		rv := reflect.ValueOf(cfg.adjust(recv))
   624  		if obj == nil {
   625  			if !rv.Elem().IsNil() {
   626  				rv.Elem().Set(reflect.Value{})
   627  			}
   628  			return nil
   629  		}
   630  		rv.Elem().Set(reflect.ValueOf(obj))
   631  		return nil
   632  	}
   633  }
   634  
   635  func rstreamBool(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   636  	*(cfg.adjust(recv).(*bool)) = r.ReadBool()
   637  	return r.Err()
   638  }
   639  
   640  func rstreamI8(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   641  	*(cfg.adjust(recv).(*int8)) = r.ReadI8()
   642  	return r.Err()
   643  }
   644  
   645  func rstreamI16(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   646  	*(cfg.adjust(recv).(*int16)) = r.ReadI16()
   647  	return r.Err()
   648  }
   649  
   650  func rstreamI32(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   651  	*(cfg.adjust(recv).(*int32)) = r.ReadI32()
   652  	return r.Err()
   653  }
   654  
   655  func rstreamI64(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   656  	*(cfg.adjust(recv).(*int64)) = r.ReadI64()
   657  	return r.Err()
   658  }
   659  
   660  func rstreamU8(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   661  	*(cfg.adjust(recv).(*uint8)) = r.ReadU8()
   662  	return r.Err()
   663  }
   664  
   665  func rstreamU16(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   666  	*(cfg.adjust(recv).(*uint16)) = r.ReadU16()
   667  	return r.Err()
   668  }
   669  
   670  func rstreamU32(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   671  	*(cfg.adjust(recv).(*uint32)) = r.ReadU32()
   672  	return r.Err()
   673  }
   674  
   675  func rstreamU64(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   676  	*(cfg.adjust(recv).(*uint64)) = r.ReadU64()
   677  	return r.Err()
   678  }
   679  
   680  func rstreamF32(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   681  	*(cfg.adjust(recv).(*float32)) = r.ReadF32()
   682  	return r.Err()
   683  }
   684  
   685  func rstreamF64(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   686  	*(cfg.adjust(recv).(*float64)) = r.ReadF64()
   687  	return r.Err()
   688  }
   689  
   690  func rstreamBits(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   691  	*(cfg.adjust(recv).(*uint32)) = r.ReadU32()
   692  	// FIXME(sbinet) handle TObject reference
   693  	// if (bits&kIsReferenced) != 0 { ... }
   694  	return r.Err()
   695  }
   696  
   697  func rstreamF16(se rbytes.StreamerElement) ropFunc {
   698  	return func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   699  		recv = cfg.adjust(recv)
   700  		*(recv.(*root.Float16)) = r.ReadF16(se)
   701  		return r.Err()
   702  	}
   703  }
   704  
   705  func rstreamD32(se rbytes.StreamerElement) ropFunc {
   706  	return func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   707  		recv = cfg.adjust(recv)
   708  		*(recv.(*root.Double32)) = r.ReadD32(se)
   709  		return r.Err()
   710  	}
   711  }
   712  
   713  func rstreamTString(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   714  	*(cfg.adjust(recv).(*string)) = r.ReadString()
   715  	return r.Err()
   716  }
   717  
   718  func rstreamTObject(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   719  	obj := cfg.adjust(recv).(*rbase.Object)
   720  	return obj.UnmarshalROOT(r)
   721  }
   722  
   723  func rstreamTNamed(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   724  	named := cfg.adjust(recv).(*rbase.Named)
   725  	return named.UnmarshalROOT(r)
   726  }
   727  
   728  func rstreamCnv(to rmeta.Enum, from ropFunc) ropFunc {
   729  	switch to {
   730  	case rmeta.Bool:
   731  	case rmeta.Char:
   732  	case rmeta.Short:
   733  	case rmeta.Int:
   734  	case rmeta.Long, rmeta.Long64:
   735  	case rmeta.UChar:
   736  	case rmeta.UShort:
   737  	case rmeta.UInt:
   738  	case rmeta.ULong, rmeta.ULong64:
   739  	case rmeta.Float32:
   740  	case rmeta.Float64:
   741  	case rmeta.Float16:
   742  	case rmeta.Double32:
   743  	case rmeta.Bits:
   744  	}
   745  
   746  	panic("not implemented")
   747  }
   748  
   749  func rstreamBasicArray(n int, arr ropFunc) ropFunc {
   750  	return func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   751  		rv := reflect.ValueOf(cfg.adjust(recv)).Elem()
   752  		for i := range n {
   753  			err := arr(r, rv.Index(i).Addr().Interface(), nil)
   754  			if err != nil {
   755  				return fmt.Errorf(
   756  					"rdict: could not rstream array element %s[%d] of %s: %w",
   757  					cfg.descr.elem.Name(), i, cfg.si.Name(), err,
   758  				)
   759  			}
   760  		}
   761  		return nil
   762  	}
   763  }
   764  
   765  func rstreamBasicSlice(sli ropFunc) ropFunc {
   766  	return func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   767  		_ = r.ReadI8() // is-array
   768  		n := int(reflect.ValueOf(recv).Elem().FieldByIndex(cfg.descr.method).Int())
   769  		rv := reflect.ValueOf(cfg.adjust(recv)).Elem()
   770  		if nn := rv.Len(); nn < n {
   771  			rv.Set(reflect.AppendSlice(rv, reflect.MakeSlice(rv.Type(), n-nn, n-nn)))
   772  		}
   773  		for i := range n {
   774  			err := sli(r, rv.Index(i).Addr().Interface(), nil)
   775  			if err != nil {
   776  				return fmt.Errorf(
   777  					"rdict: could not rstream slice element %s[%d] of %s: %w",
   778  					cfg.descr.elem.Name(), i, cfg.si.Name(), err,
   779  				)
   780  			}
   781  		}
   782  		return nil
   783  	}
   784  }
   785  
   786  func rstreamHeader(r *rbytes.RBuffer, typename string, typevers int16) rbytes.Header {
   787  	if _, ok := rmeta.CxxBuiltins[typename]; ok && typename != "string" {
   788  		return rbytes.Header{Pos: -1}
   789  	}
   790  	if typename == "TString" {
   791  		return rbytes.Header{Pos: -1}
   792  	}
   793  	return r.ReadHeader(typename, typevers)
   794  }
   795  
   796  func rcheckHeader(r *rbytes.RBuffer, hdr rbytes.Header) error {
   797  	if hdr.Pos < 0 {
   798  		return nil
   799  	}
   800  	r.CheckHeader(hdr)
   801  	return r.Err()
   802  }
   803  
   804  func rstreamType(typename string, rop ropFunc) ropFunc {
   805  	return func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   806  		hdr := r.ReadHeader(typename, rvers.StreamerBaseSTL)
   807  		err := rop(r, recv, cfg)
   808  		if err != nil {
   809  			return fmt.Errorf(
   810  				"rdict: could not read (type=%q, vers=%d): %w",
   811  				hdr.Name, hdr.Vers, err,
   812  			)
   813  		}
   814  		r.CheckHeader(hdr)
   815  		return r.Err()
   816  	}
   817  }
   818  
   819  func rstreamStdSlice(typename string, rop ropFunc) ropFunc {
   820  	//	const typevers = 1
   821  	return func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   822  		// FIXME(sbinet): use typevers to infer obj-/mbr-wise reading.
   823  		n := int(r.ReadI32())
   824  		rv := reflect.ValueOf(cfg.adjust(recv)).Elem()
   825  		if nn := rv.Len(); nn < n {
   826  			rv.Set(reflect.AppendSlice(rv, reflect.MakeSlice(rv.Type(), n-nn, n-nn)))
   827  		}
   828  		rv.SetLen(n)
   829  		for i := range n {
   830  			err := rop(r, rv.Index(i).Addr().Interface(), nil)
   831  			if err != nil {
   832  				return fmt.Errorf(
   833  					"rdict: could not rstream element %s[%d] of %s: %w",
   834  					cfg.descr.elem.Name(), i, cfg.si.Name(), err,
   835  				)
   836  			}
   837  		}
   838  		return r.Err()
   839  	}
   840  }
   841  
   842  func rstreamStdSet(typename string, rop ropFunc) ropFunc {
   843  	//	const typevers = 1
   844  
   845  	// FIXME(sbinet): add special handling for std::set-like types
   846  	// the correct equivalent Go-type of std::set<T> is map[T]struct{}
   847  	// (or, when availaible, std.Set[T])
   848  	return rstreamStdSlice(typename, rop)
   849  }
   850  
   851  func rstreamStdMap(kname, vname string, krop, vrop ropFunc) ropFunc {
   852  	typename := fmt.Sprintf("map<%s,%s>", kname, vname)
   853  	if strings.HasSuffix(vname, ">") {
   854  		typename = fmt.Sprintf("map<%s,%s >", kname, vname)
   855  	}
   856  	return func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   857  		// typevers = int16(cfg.si.ClassVersion())
   858  		hdr := r.ReadHeader(typename, rvers.StreamerBaseSTL)
   859  		if hdr.MemberWise {
   860  			clvers := r.ReadI16()
   861  			switch {
   862  			case clvers == 1:
   863  				// TODO
   864  			case clvers <= 0:
   865  				/*chksum*/ _ = r.ReadU32()
   866  			}
   867  		}
   868  
   869  		n := int(r.ReadI32())
   870  		rv := reflect.ValueOf(cfg.adjust(recv)).Elem()
   871  		keyT := reflect.SliceOf(rv.Type().Key())
   872  		valT := reflect.SliceOf(rv.Type().Elem())
   873  		keys := reflect.New(keyT).Elem()
   874  		keys.Set(reflect.AppendSlice(keys, reflect.MakeSlice(keyT, n, n)))
   875  		if n > 0 {
   876  			hdr := rstreamHeader(r, kname, -1) // FIXME(sbinet): use -1 passthrough or key-si-classversion ?
   877  			for i := range n {
   878  				err := krop(r, keys.Index(i).Addr().Interface(), nil)
   879  				if err != nil {
   880  					return fmt.Errorf(
   881  						"rdict: could not rstream key-element %s[%d] of %s: %w",
   882  						kname, i, cfg.si.Name(), err,
   883  					)
   884  				}
   885  			}
   886  			err := rcheckHeader(r, hdr)
   887  			if err != nil {
   888  				return err
   889  			}
   890  		}
   891  
   892  		vals := reflect.New(valT).Elem()
   893  		vals.Set(reflect.AppendSlice(vals, reflect.MakeSlice(valT, n, n)))
   894  		if n > 0 {
   895  			hdr := rstreamHeader(r, vname, -1) // FIXME(sbinet): use -1 passthrough or val-si-classversion
   896  			for i := range n {
   897  				err := vrop(r, vals.Index(i).Addr().Interface(), nil)
   898  				if err != nil {
   899  					return fmt.Errorf(
   900  						"rdict: could not rstream val-element %s[%d] of %s: %w",
   901  						vname, i, cfg.si.Name(), err,
   902  					)
   903  				}
   904  			}
   905  			err := rcheckHeader(r, hdr)
   906  			if err != nil {
   907  				return err
   908  			}
   909  		}
   910  
   911  		if rv.IsNil() {
   912  			rv.Set(reflect.MakeMapWithSize(rv.Type(), n))
   913  		}
   914  		for i := range n {
   915  			rv.SetMapIndex(keys.Index(i), vals.Index(i))
   916  		}
   917  
   918  		r.CheckHeader(hdr)
   919  		return r.Err()
   920  	}
   921  }
   922  
   923  func rstreamStdBitset(typename string, n int) ropFunc {
   924  	return func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   925  		var (
   926  			bits = int(r.ReadI32())
   927  			sli  = cfg.adjust(recv).(*[]uint8)
   928  		)
   929  		*sli = rbytes.ResizeU8(*sli, bits)
   930  		r.ReadStdBitset(*sli)
   931  		return r.Err()
   932  	}
   933  }
   934  
   935  func rstreamBools(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   936  	var (
   937  		_   = r.ReadI8() // is-array
   938  		n   = cfg.counter(recv)
   939  		sli = cfg.adjust(recv).(*[]bool)
   940  	)
   941  	*sli = rbytes.ResizeBool(*sli, n)
   942  	r.ReadArrayBool(*sli)
   943  	return r.Err()
   944  }
   945  
   946  func rstreamU8s(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   947  	var (
   948  		_   = r.ReadI8() // is-array
   949  		n   = cfg.counter(recv)
   950  		sli = cfg.adjust(recv).(*[]uint8)
   951  	)
   952  	*sli = rbytes.ResizeU8(*sli, n)
   953  	r.ReadArrayU8(*sli)
   954  	return r.Err()
   955  }
   956  
   957  func rstreamU16s(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   958  	var (
   959  		_   = r.ReadI8() // is-array
   960  		n   = cfg.counter(recv)
   961  		sli = cfg.adjust(recv).(*[]uint16)
   962  	)
   963  	*sli = rbytes.ResizeU16(*sli, n)
   964  	r.ReadArrayU16(*sli)
   965  	return r.Err()
   966  }
   967  
   968  func rstreamU32s(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   969  	var (
   970  		_   = r.ReadI8() // is-array
   971  		n   = cfg.counter(recv)
   972  		sli = cfg.adjust(recv).(*[]uint32)
   973  	)
   974  	*sli = rbytes.ResizeU32(*sli, n)
   975  	r.ReadArrayU32(*sli)
   976  	return r.Err()
   977  }
   978  
   979  func rstreamU64s(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   980  	var (
   981  		_   = r.ReadI8() // is-array
   982  		n   = cfg.counter(recv)
   983  		sli = cfg.adjust(recv).(*[]uint64)
   984  	)
   985  	*sli = rbytes.ResizeU64(*sli, n)
   986  	r.ReadArrayU64(*sli)
   987  	return r.Err()
   988  }
   989  
   990  func rstreamI8s(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
   991  	var (
   992  		_   = r.ReadI8() // is-array
   993  		n   = cfg.counter(recv)
   994  		sli = cfg.adjust(recv).(*[]int8)
   995  	)
   996  	*sli = rbytes.ResizeI8(*sli, n)
   997  	r.ReadArrayI8(*sli)
   998  	return r.Err()
   999  }
  1000  
  1001  func rstreamI16s(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
  1002  	var (
  1003  		_   = r.ReadI8() // is-array
  1004  		n   = cfg.counter(recv)
  1005  		sli = cfg.adjust(recv).(*[]int16)
  1006  	)
  1007  	*sli = rbytes.ResizeI16(*sli, n)
  1008  	r.ReadArrayI16(*sli)
  1009  	return r.Err()
  1010  }
  1011  
  1012  func rstreamI32s(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
  1013  	var (
  1014  		_   = r.ReadI8() // is-array
  1015  		n   = cfg.counter(recv)
  1016  		sli = cfg.adjust(recv).(*[]int32)
  1017  	)
  1018  	*sli = rbytes.ResizeI32(*sli, n)
  1019  	r.ReadArrayI32(*sli)
  1020  	return r.Err()
  1021  }
  1022  
  1023  func rstreamI64s(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
  1024  	var (
  1025  		_   = r.ReadI8() // is-array
  1026  		n   = cfg.counter(recv)
  1027  		sli = cfg.adjust(recv).(*[]int64)
  1028  	)
  1029  	*sli = rbytes.ResizeI64(*sli, n)
  1030  	r.ReadArrayI64(*sli)
  1031  	return r.Err()
  1032  }
  1033  
  1034  func rstreamF32s(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
  1035  	var (
  1036  		_   = r.ReadI8() // is-array
  1037  		n   = cfg.counter(recv)
  1038  		sli = cfg.adjust(recv).(*[]float32)
  1039  	)
  1040  	*sli = rbytes.ResizeF32(*sli, n)
  1041  	r.ReadArrayF32(*sli)
  1042  	return r.Err()
  1043  }
  1044  
  1045  func rstreamF64s(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
  1046  	var (
  1047  		_   = r.ReadI8() // is-array
  1048  		n   = cfg.counter(recv)
  1049  		sli = cfg.adjust(recv).(*[]float64)
  1050  	)
  1051  	*sli = rbytes.ResizeF64(*sli, n)
  1052  	r.ReadArrayF64(*sli)
  1053  	return r.Err()
  1054  }
  1055  
  1056  func rstreamF16s(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
  1057  	var (
  1058  		_   = r.ReadI8() // is-array
  1059  		n   = cfg.counter(recv)
  1060  		sli = cfg.adjust(recv).(*[]root.Float16)
  1061  	)
  1062  	*sli = rbytes.ResizeF16(*sli, n)
  1063  	r.ReadArrayF16(*sli, cfg.descr.elem)
  1064  	return r.Err()
  1065  }
  1066  
  1067  func rstreamD32s(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
  1068  	var (
  1069  		_   = r.ReadI8() // is-array
  1070  		n   = cfg.counter(recv)
  1071  		sli = cfg.adjust(recv).(*[]root.Double32)
  1072  	)
  1073  	*sli = rbytes.ResizeD32(*sli, n)
  1074  	r.ReadArrayD32(*sli, cfg.descr.elem)
  1075  	return r.Err()
  1076  }
  1077  
  1078  func rstreamStrs(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
  1079  	var (
  1080  		_   = r.ReadI8() // is-array
  1081  		n   = cfg.counter(recv)
  1082  		sli = cfg.adjust(recv).(*[]string)
  1083  	)
  1084  	*sli = rbytes.ResizeStr(*sli, n)
  1085  	r.ReadArrayString(*sli)
  1086  	return r.Err()
  1087  }
  1088  
  1089  func rstreamCat(typename string, typevers int16, rops []rstreamer) ropFunc {
  1090  	return func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
  1091  		hdr := r.ReadHeader(typename, typevers)
  1092  		if hdr.Vers != typevers {
  1093  			r.SetErr(fmt.Errorf(
  1094  				"rdict: inconsistent ROOT version type=%q (got=%d, want=%d)",
  1095  				hdr.Name, hdr.Vers, typevers,
  1096  			))
  1097  			return r.Err()
  1098  		}
  1099  
  1100  		recv = cfg.adjust(recv)
  1101  		for i, rop := range rops {
  1102  			err := rop.rstream(r, recv)
  1103  			if err != nil {
  1104  				return fmt.Errorf(
  1105  					"rdict: could not rstream element %d (%s) of %s: %w",
  1106  					i, rop.cfg.descr.elem.Name(), cfg.si.Name(), err,
  1107  				)
  1108  			}
  1109  		}
  1110  		r.CheckHeader(hdr)
  1111  		return r.Err()
  1112  	}
  1113  }
  1114  
  1115  func rstreamStdString(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
  1116  	*(cfg.adjust(recv).(*string)) = r.ReadString()
  1117  	return r.Err()
  1118  
  1119  }
  1120  
  1121  // func rstreamGeneric(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
  1122  // 	const (
  1123  // 		beg     = 0
  1124  // 		end     = 1
  1125  // 		n       = 1
  1126  // 		arrmode = 2
  1127  // 	)
  1128  // 	return cfg.si.rstream(r, recv, cfg.descr, beg, end, n, cfg.offset, arrmode)
  1129  // }
  1130  
  1131  // type rmbrwiseSTLFunc func(r *rbytes.RBuffer, recv any, cfg *streamerConfig, vers int16) error
  1132  // type robjwiseSTLFunc func(r *rbytes.RBuffer, recv any, cfg *streamerConfig, vers int16, start int32) error
  1133  //
  1134  // func rstreamSTL(mbrwise rmbrwiseSTLFunc, objwise robjwiseSTLFunc, oclass string) ropFunc {
  1135  // 	return func(r *rbytes.RBuffer, recv any, cfg *streamerConfig) error {
  1136  // 		err := r.Err()
  1137  // 		if err != nil {
  1138  // 			return err
  1139  // 		}
  1140  //
  1141  // 		hdr := r.ReadHeader(oclass, -1)
  1142  // 		switch {
  1143  // 		case hdr.MemberWise:
  1144  // 			err = mbrwise(r, cfg.adjust(recv), cfg, hdr.Vers)
  1145  // 		default:
  1146  // 			err = objwise(r, cfg.adjust(recv), cfg, hdr.Vers, int32(beg))
  1147  // 		}
  1148  //
  1149  // 		r.CheckHeader(hdr)
  1150  // 		return err
  1151  // 	}
  1152  // }
  1153  //
  1154  // func rstreamSTLArrayMbrWise(r *rbytes.RBuffer, recv any, cfg *streamerConfig, vers int16) error {
  1155  // 	panic("not implemented")
  1156  // }
  1157  //
  1158  // func rstreamSTLObjWise(r *rbytes.RBuffer, recv any, cfg *streamerConfig, vers int16, start int32) error {
  1159  // 	panic("not implemented")
  1160  // }
  1161  
  1162  // func (si *StreamerInfo) rstream(r *rbytes.RBuffer, recv any, descr *elemDescr, beg, end, n, offset int, mode arrayMode) error {
  1163  // 	needIncr := mode&2 == 0
  1164  // 	mode &= ^2
  1165  //
  1166  // 	if needIncr {
  1167  // 		panic("not implemented")
  1168  // 	}
  1169  // 	const kHaveLoop = 1024
  1170  // 	var typeOffset rmeta.Enum
  1171  // 	if mode == 0 {
  1172  // 		typeOffset = kHaveLoop
  1173  // 	}
  1174  //
  1175  // 	var (
  1176  // 		ioffset = []int{-1, offset}
  1177  // 		err     error
  1178  // 	)
  1179  // 	for i := beg; i < end; i++ {
  1180  // 		ioffset[0] = descr.offset
  1181  //
  1182  // 		var (
  1183  // 			recv  = ptrAdjust(recv, ioffset)
  1184  // 			etype = descr.otype
  1185  // 		)
  1186  //
  1187  // 		switch etype + typeOffset {
  1188  // 		case rmeta.Bool:
  1189  // 			*(recv.(*bool)) = r.ReadBool()
  1190  // 		case rmeta.Char:
  1191  // 			*(recv.(*int8)) = r.ReadI8()
  1192  // 		case rmeta.Short:
  1193  // 			*(recv.(*int16)) = r.ReadI16()
  1194  // 		case rmeta.Int:
  1195  // 			*(recv.(*int32)) = r.ReadI32()
  1196  // 		case rmeta.Long, rmeta.Long64:
  1197  // 			*(recv.(*int64)) = r.ReadI64()
  1198  // 		case rmeta.UChar:
  1199  // 			*(recv.(*uint8)) = r.ReadU8()
  1200  // 		case rmeta.UShort:
  1201  // 			*(recv.(*uint16)) = r.ReadU16()
  1202  // 		case rmeta.UInt:
  1203  // 			*(recv.(*uint32)) = r.ReadU32()
  1204  // 		case rmeta.ULong, rmeta.ULong64:
  1205  // 			*(recv.(*uint64)) = r.ReadU64()
  1206  // 		case rmeta.Float32:
  1207  // 			*(recv.(*float32)) = r.ReadF32()
  1208  // 		case rmeta.Float64:
  1209  // 			*(recv.(*float64)) = r.ReadF64()
  1210  // 		case rmeta.Float16:
  1211  // 			*(recv.(*root.Float16)) = r.ReadF16(descr.elem)
  1212  // 		case rmeta.Double32:
  1213  // 			*(recv.(*root.Double32)) = r.ReadD32(descr.elem)
  1214  // 		}
  1215  // 		err = r.Err()
  1216  //
  1217  // 		if err != nil {
  1218  // 			return fmt.Errorf("rdict: could not rstream data: %w", err)
  1219  // 		}
  1220  // 	}
  1221  // 	panic("not implemented")
  1222  // }
  1223  
  1224  // func ptrAdjust(ptr any, offsets []int) any {
  1225  // 	recv := ptr
  1226  // 	for _, offset := range offsets {
  1227  // 		rv := reflect.ValueOf(recv).Elem()
  1228  // 		switch rv.Kind() {
  1229  // 		case reflect.Struct:
  1230  // 			recv = rv.Field(offset).Addr().Interface()
  1231  // 		case reflect.Array, reflect.Slice:
  1232  // 			recv = rv.Index(offset).Addr().Interface()
  1233  // 		default:
  1234  // 			continue
  1235  // 		}
  1236  // 	}
  1237  // 	return recv
  1238  // }
  1239  
  1240  func ropFuncFor(e rmeta.Enum, descr *elemDescr) ropFunc {
  1241  	switch e {
  1242  	case rmeta.Bool:
  1243  		return rstreamBool
  1244  	case rmeta.Bits:
  1245  		return rstreamBits
  1246  	case rmeta.Int8:
  1247  		return rstreamI8
  1248  	case rmeta.Int16:
  1249  		return rstreamI16
  1250  	case rmeta.Int32:
  1251  		return rstreamI32
  1252  	case rmeta.Int64, rmeta.Long64:
  1253  		return rstreamI64
  1254  	case rmeta.Uint8:
  1255  		return rstreamU8
  1256  	case rmeta.Uint16:
  1257  		return rstreamU16
  1258  	case rmeta.Uint32:
  1259  		return rstreamU32
  1260  	case rmeta.Uint64, rmeta.ULong64:
  1261  		return rstreamU64
  1262  	case rmeta.Float32:
  1263  		return rstreamF32
  1264  	case rmeta.Float64:
  1265  		return rstreamF64
  1266  	case rmeta.Float16:
  1267  		return rstreamF16(descr.elem)
  1268  	case rmeta.Double32:
  1269  		return rstreamD32(descr.elem)
  1270  	case rmeta.TString, rmeta.CharStar:
  1271  		return rstreamTString
  1272  	case rmeta.STLstring:
  1273  		return rstreamStdString
  1274  	case rmeta.TObject:
  1275  		return rstreamTObject
  1276  	case rmeta.TNamed:
  1277  		return rstreamTNamed
  1278  	default:
  1279  		return nil
  1280  	}
  1281  }
  1282  
  1283  func ropFrom(sictx rbytes.StreamerInfoContext, typename string, typevers int16, enum rmeta.Enum, descr *elemDescr) ropFunc {
  1284  	e, ok := rmeta.TypeName2Enum(typename)
  1285  	if ok {
  1286  		rop := ropFuncFor(e, descr)
  1287  		if rop != nil {
  1288  			return rop
  1289  		}
  1290  	}
  1291  
  1292  	rop := ropFuncFor(enum, descr)
  1293  	if rop != nil {
  1294  		return rop
  1295  	}
  1296  
  1297  	switch {
  1298  	case hasStdPrefix(typename, "vector", "list", "deque"):
  1299  		enames := rmeta.CxxTemplateFrom(typename).Args
  1300  		rop := ropFrom(sictx, enames[0], -1, 0, nil)
  1301  		return rstreamStdSlice(typename, rop)
  1302  
  1303  	case hasStdPrefix(typename, "set", "multiset", "unordered_set", "unordered_multiset"):
  1304  		enames := rmeta.CxxTemplateFrom(typename).Args
  1305  		rop := ropFrom(sictx, enames[0], -1, 0, nil)
  1306  		return rstreamStdSet(typename, rop)
  1307  
  1308  	case hasStdPrefix(typename, "map", "multimap", "unordered_map", "unordered_multimap"):
  1309  		enames := rmeta.CxxTemplateFrom(typename).Args
  1310  		kname := enames[0]
  1311  		vname := enames[1]
  1312  
  1313  		krop := ropFrom(sictx, kname, -1, 0, nil)
  1314  		vrop := ropFrom(sictx, vname, -1, 0, nil)
  1315  		return rstreamStdMap(kname, vname, krop, vrop)
  1316  
  1317  	case hasStdPrefix(typename, "bitset"):
  1318  		enames := rmeta.CxxTemplateFrom(typename).Args
  1319  		n, err := strconv.Atoi(enames[0])
  1320  		if err != nil {
  1321  			panic(fmt.Errorf("rdict: invalid STL bitset argument (type=%q): %+v", typename, err))
  1322  		}
  1323  		return rstreamStdBitset(typename, n)
  1324  	}
  1325  
  1326  	osi, err := sictx.StreamerInfo(typename, int(typevers))
  1327  	if err != nil {
  1328  		panic(fmt.Errorf("rdict: could not find streamer info for %q (version=%d): %w", typename, typevers, err))
  1329  	}
  1330  	esi := osi.(*StreamerInfo)
  1331  
  1332  	err = esi.BuildStreamers()
  1333  	if err != nil {
  1334  		panic(fmt.Errorf("rdict: could not build streamers for %q (version=%d): %w", typename, typevers, err))
  1335  	}
  1336  
  1337  	rop = rstreamSI(esi)
  1338  	return rop
  1339  }