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 }