go-hep.org/x/hep@v0.38.1/groot/rdict/rdict.go (about) 1 // Copyright ©2018 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package rdict contains the definition of ROOT streamers and facilities 6 // to generate new streamers meta data from user types. 7 package rdict // import "go-hep.org/x/hep/groot/rdict" 8 9 import ( 10 "fmt" 11 "math" 12 "reflect" 13 "strconv" 14 "strings" 15 "sync" 16 "text/tabwriter" 17 18 "go-hep.org/x/hep/groot/rbase" 19 "go-hep.org/x/hep/groot/rbytes" 20 "go-hep.org/x/hep/groot/rcont" 21 "go-hep.org/x/hep/groot/rmeta" 22 "go-hep.org/x/hep/groot/root" 23 "go-hep.org/x/hep/groot/rtypes" 24 "go-hep.org/x/hep/groot/rvers" 25 ) 26 27 var ( 28 ptrSize = 4 << (^uintptr(0) >> 63) 29 intSize = int(reflect.TypeOf(int(0)).Size()) 30 ) 31 32 type StreamerInfo struct { 33 named rbase.Named 34 chksum uint32 35 clsver int32 36 objarr *rcont.ObjArray 37 elems []rbytes.StreamerElement 38 39 init sync.Once 40 descr []elemDescr 41 roops []rstreamer // read-stream object-wise operations 42 woops []wstreamer // write-stream object-wise operations 43 rmops []rstreamer // read-stream member-wise operations 44 wmops []wstreamer // write-stream member-wise operations 45 } 46 47 // NewStreamerInfo creates a new StreamerInfo from Go provided informations. 48 func NewStreamerInfo(name string, version int, elems []rbytes.StreamerElement) *StreamerInfo { 49 sinfos := &StreamerInfo{ 50 named: *rbase.NewNamed(GoName2Cxx(name), "Go;"+name), 51 chksum: genChecksum(name, elems), 52 clsver: int32(version), 53 objarr: rcont.NewObjArray(), 54 elems: elems, 55 } 56 return sinfos 57 } 58 59 // NewCxxStreamerInfo creates a new StreamerInfo from C++ provided informations. 60 func NewCxxStreamerInfo(name string, version int32, chksum uint32, elems []rbytes.StreamerElement) *StreamerInfo { 61 sinfos := &StreamerInfo{ 62 named: *rbase.NewNamed(name, ""), 63 chksum: chksum, 64 clsver: version, 65 objarr: rcont.NewObjArray(), 66 elems: elems, 67 } 68 return sinfos 69 } 70 71 func (*StreamerInfo) RVersion() int16 { return rvers.StreamerInfo } 72 73 func (tsi *StreamerInfo) Class() string { 74 return "TStreamerInfo" 75 } 76 77 func (tsi *StreamerInfo) Name() string { 78 return tsi.named.Name() 79 } 80 81 func (tsi *StreamerInfo) Title() string { 82 return tsi.named.Title() 83 } 84 85 func (tsi *StreamerInfo) CheckSum() int { 86 return int(tsi.chksum) 87 } 88 89 func (tsi *StreamerInfo) ClassVersion() int { 90 return int(tsi.clsver) 91 } 92 93 func (tsi *StreamerInfo) Elements() []rbytes.StreamerElement { 94 return tsi.elems 95 } 96 97 func (tsi *StreamerInfo) MarshalROOT(w *rbytes.WBuffer) (int, error) { 98 if w.Err() != nil { 99 return 0, w.Err() 100 } 101 102 hdr := w.WriteHeader(tsi.Class(), tsi.RVersion()) 103 w.WriteObject(&tsi.named) 104 w.WriteU32(tsi.chksum) 105 w.WriteI32(tsi.clsver) 106 107 if len(tsi.elems) > 0 { 108 elems := make([]root.Object, len(tsi.elems)) 109 for i, v := range tsi.elems { 110 elems[i] = v 111 } 112 tsi.objarr.SetElems(elems) 113 } 114 w.WriteObjectAny(tsi.objarr) 115 tsi.objarr.SetElems(nil) 116 117 return w.SetHeader(hdr) 118 } 119 120 func (tsi *StreamerInfo) UnmarshalROOT(r *rbytes.RBuffer) error { 121 if r.Err() != nil { 122 return r.Err() 123 } 124 125 hdr := r.ReadHeader(tsi.Class(), tsi.RVersion()) 126 127 r.ReadObject(&tsi.named) 128 129 tsi.chksum = r.ReadU32() 130 tsi.clsver = r.ReadI32() 131 objs := r.ReadObjectAny() 132 if r.Err() != nil { 133 return r.Err() 134 } 135 136 tsi.objarr = objs.(*rcont.ObjArray) 137 tsi.elems = nil 138 if tsi.objarr.Len() > 0 { 139 tsi.elems = make([]rbytes.StreamerElement, tsi.objarr.Len()) 140 for i := range tsi.elems { 141 elem := tsi.objarr.At(i) 142 tsi.elems[i] = elem.(rbytes.StreamerElement) 143 } 144 } 145 tsi.objarr.SetElems(nil) 146 147 r.CheckHeader(hdr) 148 return r.Err() 149 } 150 151 func (si *StreamerInfo) String() string { 152 o := new(strings.Builder) 153 fmt.Fprintf(o, " StreamerInfo for %q version=%d title=%q\n", si.Name(), si.ClassVersion(), si.Title()) 154 w := tabwriter.NewWriter(o, 8, 4, 1, ' ', 0) 155 for _, elm := range si.Elements() { 156 fmt.Fprintf(w, " %s\t%s\toffset=%3d\ttype=%3d\tsize=%3d\t %s\n", elm.TypeName(), elm.Name(), elm.Offset(), elm.Type(), elm.Size(), elm.Title()) 157 } 158 w.Flush() 159 return o.String() 160 161 } 162 163 // BuildStreamers builds the r/w streamers. 164 func (si *StreamerInfo) BuildStreamers() error { 165 var err error 166 si.init.Do(func() { 167 err = si.build(StreamerInfos) 168 }) 169 return err 170 } 171 172 func (si *StreamerInfo) build(sictx rbytes.StreamerInfoContext) error { 173 si.descr = make([]elemDescr, 0, len(si.elems)) 174 si.roops = make([]rstreamer, 0, len(si.elems)) 175 si.woops = make([]wstreamer, 0, len(si.elems)) 176 si.rmops = make([]rstreamer, 0, len(si.elems)) 177 si.wmops = make([]wstreamer, 0, len(si.elems)) 178 179 for i, se := range si.elems { 180 class := strings.TrimRight(se.TypeName(), "*") 181 method := func() []int { 182 var cname string 183 switch se := se.(type) { 184 case *StreamerBasicPointer: 185 cname = se.CountName() 186 case *StreamerLoop: 187 cname = se.CountName() 188 if se.cclass != si.Name() { 189 // reaching into another class internals isn't supported (yet?) in groot 190 panic(fmt.Errorf("rdict: unsupported StreamerLoop case: si=%q, se=%q, count=%q, class=%q", 191 si.Name(), se.Name(), cname, se.cclass, 192 )) 193 } 194 default: 195 return []int{0} 196 } 197 198 return si.findField(sictx, cname, se, nil) 199 }() 200 201 if method == nil { 202 return fmt.Errorf("rdict: could not find count-offset for element %q in streamer %q (se=%T)", se.Name(), si.Name(), se) 203 } 204 205 descr := elemDescr{ 206 otype: se.Type(), 207 ntype: se.Type(), // FIXME(sbinet): handle schema evolution 208 offset: i, // FIXME(sbinet): make sure this works (instead of se.Offset()) 209 length: se.ArrayLen(), 210 elem: se, 211 method: method, // FIXME(sbinet): schema evolution (old/new class may not have the same "offsets") 212 oclass: class, // FIXME(sbinet): impl. 213 nclass: class, // FIXME(sbinet): impl. + schema evolution 214 mbr: nil, // FIXME(sbinet): impl 215 } 216 217 si.descr = append(si.descr, descr) 218 } 219 220 for i, descr := range si.descr { 221 si.roops = append(si.roops, si.makeROp(sictx, i, descr)) 222 si.woops = append(si.woops, si.makeWOp(sictx, i, descr)) 223 // FIXME(sbinet): handle member-wise r/w ops 224 // si.rmops 225 // si.wmops 226 } 227 228 return nil 229 } 230 231 func (si *StreamerInfo) NewDecoder(kind rbytes.StreamKind, r *rbytes.RBuffer) (rbytes.Decoder, error) { 232 err := si.BuildStreamers() 233 if err != nil { 234 return nil, fmt.Errorf("rdict: could not build read streamers: %w", err) 235 } 236 237 switch kind { 238 case rbytes.ObjectWise: 239 return newDecoder(r, si, kind, si.roops) 240 case rbytes.MemberWise: 241 return newDecoder(r, si, kind, si.rmops) 242 default: 243 return nil, fmt.Errorf("rdict: invalid stream kind %v", kind) 244 } 245 } 246 247 func (si *StreamerInfo) NewEncoder(kind rbytes.StreamKind, w *rbytes.WBuffer) (rbytes.Encoder, error) { 248 err := si.BuildStreamers() 249 if err != nil { 250 return nil, fmt.Errorf("rdict: could not build write streamers: %w", err) 251 } 252 253 switch kind { 254 case rbytes.ObjectWise: 255 return newEncoder(w, si, kind, si.woops) 256 case rbytes.MemberWise: 257 return newEncoder(w, si, kind, si.wmops) 258 default: 259 return nil, fmt.Errorf("rdict: invalid stream kind %v", kind) 260 } 261 } 262 263 func (si *StreamerInfo) NewRStreamer(kind rbytes.StreamKind) (rbytes.RStreamer, error) { 264 err := si.BuildStreamers() 265 if err != nil { 266 return nil, fmt.Errorf("rdict: could not build read streamers: %w", err) 267 } 268 269 roops := make([]rstreamer, len(si.descr)) 270 switch kind { 271 case rbytes.ObjectWise: 272 copy(roops, si.roops) 273 case rbytes.MemberWise: 274 copy(roops, si.rmops) 275 default: 276 return nil, fmt.Errorf("rdict: invalid stream kind %v", kind) 277 } 278 return newRStreamerInfo(si, kind, roops) 279 } 280 281 func (si *StreamerInfo) NewWStreamer(kind rbytes.StreamKind) (rbytes.WStreamer, error) { 282 err := si.BuildStreamers() 283 if err != nil { 284 return nil, fmt.Errorf("rdict: could not build write streamers: %w", err) 285 } 286 287 wops := make([]wstreamer, len(si.descr)) 288 switch kind { 289 case rbytes.ObjectWise: 290 copy(wops, si.woops) 291 case rbytes.MemberWise: 292 copy(wops, si.wmops) 293 default: 294 return nil, fmt.Errorf("rdict: invalid stream kind %v", kind) 295 } 296 return newWStreamerInfo(si, kind, wops) 297 } 298 299 func (si *StreamerInfo) findField(ctx rbytes.StreamerInfoContext, name string, se rbytes.StreamerElement, offset []int) []int { 300 for j := range si.elems { 301 if si.elems[j].Name() == name { 302 offset = append(offset, j) 303 return offset 304 } 305 } 306 307 // look into base classes, if any. 308 for j, bse := range si.elems { 309 switch bse := bse.(type) { 310 case *StreamerBase: 311 base, err := ctx.StreamerInfo(bse.Name(), -1) 312 if err != nil { 313 panic(fmt.Errorf("rdict: could not find base class %q of %q: %w", se.Name(), si.Name(), err)) 314 } 315 boffset := base.(*StreamerInfo).findField(ctx, name, se, nil) 316 if boffset != nil { 317 return append(append(offset, j), boffset...) 318 } 319 } 320 } 321 322 return nil 323 } 324 325 type Element struct { 326 Name rbase.Named 327 Type rmeta.Enum // element type 328 Size int32 // size of element 329 ArrLen int32 // cumulative size of all array dims 330 ArrDim int32 // number of array dimensions 331 MaxIdx [5]int32 // maximum array index for array dimension "dim" 332 Offset int32 // element offset in class 333 EName string // data type name of data member 334 XMin float64 // minimum of data member if a range is specified [xmin.xmax.nbits] 335 XMax float64 // maximum of data member if a range is specified [xmin.xmax.nbits] 336 Factor float64 // conversion factor if a range is specified. factor = (1<<nbits/(xmax-xmin)) 337 } 338 339 func (e Element) New() StreamerElement { 340 e.parse() 341 return StreamerElement{ 342 named: e.Name, 343 etype: e.Type, 344 esize: e.Size, 345 arrlen: e.ArrLen, 346 arrdim: e.ArrDim, 347 maxidx: e.MaxIdx, 348 offset: e.Offset, 349 ename: e.EName, 350 xmin: e.XMin, 351 xmax: e.XMax, 352 factor: e.Factor, 353 } 354 } 355 356 // parse parses the element's title for ROOT meta-data information (range, factor, ...) 357 func (e *Element) parse() { 358 switch e.Type { 359 case rmeta.Float16, rmeta.OffsetL + rmeta.Float16, rmeta.OffsetP + rmeta.Float16: 360 e.XMin, e.XMax, e.Factor = e.getRange(e.Name.Title()) 361 case rmeta.Double32, rmeta.OffsetL + rmeta.Double32, rmeta.OffsetP + rmeta.Double32: 362 e.XMin, e.XMax, e.Factor = e.getRange(e.Name.Title()) 363 } 364 } 365 366 func (Element) getRange(str string) (xmin, xmax, factor float64) { 367 if str == "" { 368 return xmin, xmax, factor 369 } 370 beg := strings.LastIndex(str, "[") 371 if beg < 0 { 372 return xmin, xmax, factor 373 } 374 if beg > 0 { 375 // make sure there is a '/' in-between 376 // make sure the slash is just one position before. 377 slash := strings.LastIndex(str[:beg], "/") 378 if slash < 0 || slash+2 != beg { 379 return xmin, xmax, factor 380 } 381 } 382 end := strings.LastIndex(str, "]") 383 if end < 0 { 384 return xmin, xmax, factor 385 } 386 str = str[beg+1 : end] 387 if !strings.Contains(str, ",") { 388 return xmin, xmax, factor 389 } 390 391 toks := strings.Split(str, ",") 392 for i, tok := range toks { 393 toks[i] = strings.ToLower(strings.TrimSpace(tok)) 394 } 395 396 switch len(toks) { 397 case 2, 3: 398 default: 399 panic(fmt.Errorf("rdict: invalid ROOT range specification (too many commas): %q", str)) 400 } 401 402 var nbits uint32 = 32 403 if len(toks) == 3 { 404 n, err := strconv.ParseUint(toks[2], 10, 32) 405 if err != nil { 406 panic(fmt.Errorf("rdict: could not parse nbits specification %q: %w", str, err)) 407 } 408 nbits = uint32(n) 409 if nbits < 2 || nbits > 32 { 410 panic(fmt.Errorf("rdict: illegal nbits specification (nbits=%d outside of range [2,32])", nbits)) 411 } 412 } 413 414 fct := func(s string) float64 { 415 switch { 416 case strings.Contains(s, "pi"): 417 var f float64 418 switch { 419 case strings.Contains(s, "2pi"), strings.Contains(s, "2*pi"), strings.Contains(s, "twopi"): 420 f = 2 * math.Pi 421 case strings.Contains(s, "pi/2"): 422 f = math.Pi / 2 423 case strings.Contains(s, "pi/4"): 424 f = math.Pi / 4 425 case strings.Contains(s, "pi"): 426 f = math.Pi 427 } 428 if strings.Contains(s, "-") { 429 f = -f 430 } 431 return f 432 default: 433 f, err := strconv.ParseFloat(s, 64) 434 if err != nil { 435 panic(fmt.Errorf("rdict: could not parse range value %q: %w", s, err)) 436 } 437 return f 438 } 439 } 440 441 xmin = fct(toks[0]) 442 xmax = fct(toks[1]) 443 444 var bigint uint32 445 switch { 446 case nbits < 32: 447 bigint = 1 << nbits 448 default: 449 bigint = 0xffffffff 450 } 451 if xmin < xmax { 452 factor = float64(bigint) / (xmax - xmin) 453 } 454 if xmin >= xmax && nbits < 15 { 455 xmin = float64(nbits) + 0.1 456 } 457 return xmin, xmax, factor 458 } 459 460 type StreamerElement struct { 461 named rbase.Named 462 etype rmeta.Enum // element type 463 esize int32 // size of element 464 arrlen int32 // cumulative size of all array dims 465 arrdim int32 // number of array dimensions 466 maxidx [5]int32 // maximum array index for array dimension "dim" 467 offset int32 // element offset in class 468 ename string // data type name of data member 469 xmin float64 // minimum of data member if a range is specified [xmin.xmax.nbits] 470 xmax float64 // maximum of data member if a range is specified [xmin.xmax.nbits] 471 factor float64 // conversion factor if a range is specified. factor = (1<<nbits/(xmax-xmin)) 472 } 473 474 func (*StreamerElement) RVersion() int16 { return rvers.StreamerElement } 475 476 func (tse *StreamerElement) Class() string { 477 return "TStreamerElement" 478 } 479 480 func (tse *StreamerElement) Name() string { 481 return tse.named.Name() 482 } 483 484 func (tse *StreamerElement) Title() string { 485 return tse.named.Title() 486 } 487 488 func (tse *StreamerElement) ArrayDim() int { 489 return int(tse.arrdim) 490 } 491 492 func (tse *StreamerElement) ArrayDims() []int32 { 493 return tse.maxidx[:tse.arrdim] 494 } 495 496 func (tse *StreamerElement) ArrayLen() int { 497 return int(tse.arrlen) 498 } 499 500 func (tse *StreamerElement) Type() rmeta.Enum { 501 return tse.etype 502 } 503 504 func (tse *StreamerElement) Offset() uintptr { 505 return uintptr(tse.offset) 506 } 507 508 func (tse *StreamerElement) Size() uintptr { 509 return uintptr(tse.esize) 510 } 511 512 func (tse *StreamerElement) TypeName() string { 513 return tse.ename 514 } 515 516 func (tse *StreamerElement) XMin() float64 { 517 return tse.xmin 518 } 519 520 func (tse *StreamerElement) XMax() float64 { 521 return tse.xmax 522 } 523 524 func (tse *StreamerElement) Factor() float64 { 525 return tse.factor 526 } 527 528 func (tse *StreamerElement) MarshalROOT(w *rbytes.WBuffer) (int, error) { 529 if w.Err() != nil { 530 return 0, w.Err() 531 } 532 533 hdr := w.WriteHeader(tse.Class(), tse.RVersion()) 534 w.WriteObject(&tse.named) 535 w.WriteI32(int32(tse.etype)) 536 w.WriteI32(tse.esize) 537 w.WriteI32(tse.arrlen) 538 w.WriteI32(tse.arrdim) 539 w.WriteArrayI32(tse.maxidx[:]) 540 w.WriteString(tse.ename) 541 542 switch { 543 case tse.RVersion() == 3: 544 w.WriteF64(tse.xmin) 545 w.WriteF64(tse.xmax) 546 w.WriteF64(tse.factor) 547 case tse.RVersion() > 3: 548 // FIXME(sbinet) 549 // if (TestBit(kHasRange)) GetRange(GetTitle(),fXmin,fXmax,fFactor) 550 } 551 552 return w.SetHeader(hdr) 553 } 554 555 func (tse *StreamerElement) UnmarshalROOT(r *rbytes.RBuffer) error { 556 if r.Err() != nil { 557 return r.Err() 558 } 559 560 hdr := r.ReadHeader(tse.Class(), tse.RVersion()) 561 562 r.ReadObject(&tse.named) 563 564 tse.etype = rmeta.Enum(r.ReadI32()) 565 tse.esize = r.ReadI32() 566 tse.arrlen = r.ReadI32() 567 tse.arrdim = r.ReadI32() 568 if hdr.Vers == 1 { 569 copy(tse.maxidx[:], r.ReadStaticArrayI32()) 570 } else { 571 r.ReadArrayI32(tse.maxidx[:]) 572 } 573 tse.ename = r.ReadString() 574 575 if tse.etype == 11 && (tse.ename == "Bool_t" || tse.ename == "bool") { 576 tse.etype = 18 577 } 578 579 // if vers <= 2 { 580 // // FIXME(sbinet) 581 // // tse.esize = tse.arrlen * gROOT->GetType(GetTypeName())->Size() 582 // } 583 switch { 584 default: 585 tse.xmin = 0 586 tse.xmax = 0 587 tse.factor = 0 588 case hdr.Vers == 3: 589 tse.xmin = r.ReadF64() 590 tse.xmax = r.ReadF64() 591 tse.factor = r.ReadF64() 592 case hdr.Vers > 3: 593 tse.xmin, tse.xmax, tse.factor = Element{}.getRange(tse.Title()) 594 } 595 596 r.CheckHeader(hdr) 597 return r.Err() 598 } 599 600 type StreamerBase struct { 601 StreamerElement 602 vbase int32 // version number of the base class 603 } 604 605 func NewStreamerBase(se StreamerElement, vbase int32) *StreamerBase { 606 return &StreamerBase{StreamerElement: se, vbase: vbase} 607 } 608 609 func (*StreamerBase) RVersion() int16 { return rvers.StreamerBase } 610 611 func (tsb *StreamerBase) Class() string { 612 return "TStreamerBase" 613 } 614 615 // Base returns the base class' version. 616 func (tsb *StreamerBase) Base() int { 617 return int(tsb.vbase) 618 } 619 620 func (tsb *StreamerBase) MarshalROOT(w *rbytes.WBuffer) (int, error) { 621 if w.Err() != nil { 622 return 0, w.Err() 623 } 624 625 hdr := w.WriteHeader(tsb.Class(), tsb.RVersion()) 626 w.WriteObject(&tsb.StreamerElement) 627 w.WriteI32(tsb.vbase) 628 629 return w.SetHeader(hdr) 630 } 631 632 func (tsb *StreamerBase) UnmarshalROOT(r *rbytes.RBuffer) error { 633 if r.Err() != nil { 634 return r.Err() 635 } 636 637 hdr := r.ReadHeader(tsb.Class(), tsb.RVersion()) 638 639 r.ReadObject(&tsb.StreamerElement) 640 641 if hdr.Vers > 2 { 642 tsb.vbase = r.ReadI32() 643 } 644 645 r.CheckHeader(hdr) 646 return r.Err() 647 } 648 649 type StreamerBasicType struct { 650 StreamerElement 651 } 652 653 func (*StreamerBasicType) RVersion() int16 { return rvers.StreamerBasicType } 654 655 func (tsb *StreamerBasicType) Class() string { 656 return "TStreamerBasicType" 657 } 658 659 func (tsb *StreamerBasicType) MarshalROOT(w *rbytes.WBuffer) (int, error) { 660 if w.Err() != nil { 661 return 0, w.Err() 662 } 663 664 hdr := w.WriteHeader(tsb.Class(), tsb.RVersion()) 665 w.WriteObject(&tsb.StreamerElement) 666 667 return w.SetHeader(hdr) 668 } 669 670 func (tsb *StreamerBasicType) UnmarshalROOT(r *rbytes.RBuffer) error { 671 if r.Err() != nil { 672 return r.Err() 673 } 674 675 hdr := r.ReadHeader(tsb.Class(), tsb.RVersion()) 676 677 r.ReadObject(&tsb.StreamerElement) 678 679 etype := tsb.StreamerElement.etype 680 if rmeta.OffsetL < etype && etype < rmeta.OffsetP { 681 etype -= rmeta.OffsetL 682 } 683 684 basic := true 685 switch etype { 686 case rmeta.Bool, rmeta.UChar, rmeta.Char: 687 tsb.StreamerElement.esize = 1 688 case rmeta.UShort, rmeta.Short: 689 tsb.StreamerElement.esize = 2 690 case rmeta.Bits, rmeta.UInt, rmeta.Int, rmeta.Counter: 691 tsb.StreamerElement.esize = 4 692 case rmeta.ULong, rmeta.ULong64, rmeta.Long, rmeta.Long64: 693 tsb.StreamerElement.esize = 8 694 case rmeta.Float, rmeta.Float16: 695 tsb.StreamerElement.esize = 4 696 case rmeta.Double, rmeta.Double32: 697 tsb.StreamerElement.esize = 8 698 case rmeta.CharStar: 699 tsb.StreamerElement.esize = int32(ptrSize) 700 default: 701 basic = false 702 } 703 if basic && tsb.StreamerElement.arrlen > 0 { 704 tsb.StreamerElement.esize *= tsb.StreamerElement.arrlen 705 } 706 707 r.CheckHeader(hdr) 708 return r.Err() 709 } 710 711 type StreamerBasicPointer struct { 712 StreamerElement 713 cvers int32 // version number of the class with the counter 714 cname string // name of data member holding the array count 715 ccls string // name of the class with the counter 716 } 717 718 func NewStreamerBasicPointer(se StreamerElement, cvers int32, cname, ccls string) *StreamerBasicPointer { 719 return &StreamerBasicPointer{ 720 StreamerElement: se, 721 cvers: cvers, 722 cname: cname, 723 ccls: ccls, 724 } 725 } 726 727 func (*StreamerBasicPointer) RVersion() int16 { return rvers.StreamerBasicPointer } 728 729 func (tsb *StreamerBasicPointer) Class() string { 730 return "TStreamerBasicPointer" 731 } 732 733 func (tsb *StreamerBasicPointer) CountName() string { 734 return tsb.cname 735 } 736 737 func (tsb *StreamerBasicPointer) MarshalROOT(w *rbytes.WBuffer) (int, error) { 738 if w.Err() != nil { 739 return 0, w.Err() 740 } 741 742 hdr := w.WriteHeader(tsb.Class(), tsb.RVersion()) 743 w.WriteObject(&tsb.StreamerElement) 744 w.WriteI32(tsb.cvers) 745 w.WriteString(tsb.cname) 746 w.WriteString(tsb.ccls) 747 748 return w.SetHeader(hdr) 749 } 750 751 func (tsb *StreamerBasicPointer) UnmarshalROOT(r *rbytes.RBuffer) error { 752 if r.Err() != nil { 753 return r.Err() 754 } 755 756 hdr := r.ReadHeader(tsb.Class(), tsb.RVersion()) 757 758 r.ReadObject(&tsb.StreamerElement) 759 760 tsb.cvers = r.ReadI32() 761 tsb.cname = r.ReadString() 762 tsb.ccls = r.ReadString() 763 764 r.CheckHeader(hdr) 765 return r.Err() 766 } 767 768 // StreamerLoop represents a streamer for a var-length array of a non-basic type. 769 type StreamerLoop struct { 770 StreamerElement 771 cvers int32 // version number of the class with the counter 772 cname string // name of data member holding the array count 773 cclass string // name of the class with the counter 774 } 775 776 func NewStreamerLoop(se StreamerElement, cvers int32, cname, cclass string) *StreamerLoop { 777 se.etype = rmeta.StreamLoop 778 return &StreamerLoop{ 779 StreamerElement: se, 780 cvers: cvers, 781 cname: cname, 782 cclass: cclass, 783 } 784 } 785 786 func (*StreamerLoop) RVersion() int16 { return rvers.StreamerLoop } 787 788 func (*StreamerLoop) Class() string { 789 return "TStreamerLoop" 790 } 791 792 func (tsl *StreamerLoop) CountName() string { 793 return tsl.cname 794 } 795 796 func (tsl *StreamerLoop) MarshalROOT(w *rbytes.WBuffer) (int, error) { 797 if w.Err() != nil { 798 return 0, w.Err() 799 } 800 801 hdr := w.WriteHeader(tsl.Class(), tsl.RVersion()) 802 w.WriteObject(&tsl.StreamerElement) 803 w.WriteI32(tsl.cvers) 804 w.WriteString(tsl.cname) 805 w.WriteString(tsl.cclass) 806 807 return w.SetHeader(hdr) 808 } 809 810 func (tsl *StreamerLoop) UnmarshalROOT(r *rbytes.RBuffer) error { 811 if r.Err() != nil { 812 return r.Err() 813 } 814 815 hdr := r.ReadHeader(tsl.Class(), tsl.RVersion()) 816 817 r.ReadObject(&tsl.StreamerElement) 818 tsl.cvers = r.ReadI32() 819 tsl.cname = r.ReadString() 820 tsl.cclass = r.ReadString() 821 822 r.CheckHeader(hdr) 823 return r.Err() 824 } 825 826 type StreamerObject struct { 827 StreamerElement 828 } 829 830 func (*StreamerObject) RVersion() int16 { return rvers.StreamerObject } 831 832 func (tso *StreamerObject) Class() string { 833 return "TStreamerObject" 834 } 835 836 func (tso *StreamerObject) MarshalROOT(w *rbytes.WBuffer) (int, error) { 837 if w.Err() != nil { 838 return 0, w.Err() 839 } 840 841 hdr := w.WriteHeader(tso.Class(), tso.RVersion()) 842 w.WriteObject(&tso.StreamerElement) 843 return w.SetHeader(hdr) 844 } 845 846 func (tso *StreamerObject) UnmarshalROOT(r *rbytes.RBuffer) error { 847 if r.Err() != nil { 848 return r.Err() 849 } 850 851 hdr := r.ReadHeader(tso.Class(), tso.RVersion()) 852 853 r.ReadObject(&tso.StreamerElement) 854 855 r.CheckHeader(hdr) 856 return r.Err() 857 } 858 859 type StreamerObjectPointer struct { 860 StreamerElement 861 } 862 863 func (*StreamerObjectPointer) RVersion() int16 { return rvers.StreamerObjectPointer } 864 865 func (tso *StreamerObjectPointer) Class() string { 866 return "TStreamerObjectPointer" 867 } 868 869 func (tso *StreamerObjectPointer) MarshalROOT(w *rbytes.WBuffer) (int, error) { 870 if w.Err() != nil { 871 return 0, w.Err() 872 } 873 874 hdr := w.WriteHeader(tso.Class(), tso.RVersion()) 875 w.WriteObject(&tso.StreamerElement) 876 return w.SetHeader(hdr) 877 } 878 879 func (tso *StreamerObjectPointer) UnmarshalROOT(r *rbytes.RBuffer) error { 880 if r.Err() != nil { 881 return r.Err() 882 } 883 884 hdr := r.ReadHeader(tso.Class(), tso.RVersion()) 885 886 r.ReadObject(&tso.StreamerElement) 887 888 r.CheckHeader(hdr) 889 return r.Err() 890 } 891 892 type StreamerObjectAny struct { 893 StreamerElement 894 } 895 896 func (*StreamerObjectAny) RVersion() int16 { return rvers.StreamerObjectAny } 897 898 func (tso *StreamerObjectAny) Class() string { 899 return "TStreamerObjectAny" 900 } 901 902 func (tso *StreamerObjectAny) MarshalROOT(w *rbytes.WBuffer) (int, error) { 903 if w.Err() != nil { 904 return 0, w.Err() 905 } 906 907 hdr := w.WriteHeader(tso.Class(), tso.RVersion()) 908 w.WriteObject(&tso.StreamerElement) 909 910 return w.SetHeader(hdr) 911 } 912 913 func (tso *StreamerObjectAny) UnmarshalROOT(r *rbytes.RBuffer) error { 914 if r.Err() != nil { 915 return r.Err() 916 } 917 918 hdr := r.ReadHeader(tso.Class(), tso.RVersion()) 919 920 r.ReadObject(&tso.StreamerElement) 921 922 r.CheckHeader(hdr) 923 return r.Err() 924 } 925 926 type StreamerObjectAnyPointer struct { 927 StreamerElement 928 } 929 930 func (*StreamerObjectAnyPointer) RVersion() int16 { return rvers.StreamerObjectAnyPointer } 931 932 func (tso *StreamerObjectAnyPointer) Class() string { 933 return "TStreamerObjectAnyPointer" 934 } 935 936 func (tso *StreamerObjectAnyPointer) MarshalROOT(w *rbytes.WBuffer) (int, error) { 937 if w.Err() != nil { 938 return 0, w.Err() 939 } 940 941 hdr := w.WriteHeader(tso.Class(), tso.RVersion()) 942 w.WriteObject(&tso.StreamerElement) 943 944 return w.SetHeader(hdr) 945 } 946 947 func (tso *StreamerObjectAnyPointer) UnmarshalROOT(r *rbytes.RBuffer) error { 948 if r.Err() != nil { 949 return r.Err() 950 } 951 952 hdr := r.ReadHeader(tso.Class(), tso.RVersion()) 953 954 r.ReadObject(&tso.StreamerElement) 955 956 r.CheckHeader(hdr) 957 return r.Err() 958 } 959 960 type StreamerString struct { 961 StreamerElement 962 } 963 964 func (*StreamerString) RVersion() int16 { return rvers.StreamerString } 965 966 func (tss *StreamerString) Class() string { 967 return "TStreamerString" 968 } 969 970 func (tss *StreamerString) MarshalROOT(w *rbytes.WBuffer) (int, error) { 971 if w.Err() != nil { 972 return 0, w.Err() 973 } 974 975 hdr := w.WriteHeader(tss.Class(), tss.RVersion()) 976 w.WriteObject(&tss.StreamerElement) 977 978 return w.SetHeader(hdr) 979 } 980 981 func (tss *StreamerString) UnmarshalROOT(r *rbytes.RBuffer) error { 982 if r.Err() != nil { 983 return r.Err() 984 } 985 986 hdr := r.ReadHeader(tss.Class(), tss.RVersion()) 987 988 r.ReadObject(&tss.StreamerElement) 989 990 r.CheckHeader(hdr) 991 return r.Err() 992 } 993 994 type StreamerSTL struct { 995 StreamerElement 996 vtype rmeta.ESTLType // type of STL vector 997 ctype rmeta.Enum // STL contained type 998 } 999 1000 func NewStreamerSTL(name string, vtype rmeta.ESTLType, ctype rmeta.Enum) *StreamerSTL { 1001 return &StreamerSTL{ 1002 StreamerElement: StreamerElement{ 1003 named: *rbase.NewNamed(name, ""), 1004 esize: int32(ptrSize + 2*intSize), 1005 ename: rmeta.STLNameFrom(name, vtype, ctype), 1006 etype: rmeta.Streamer, 1007 }, 1008 vtype: vtype, 1009 ctype: ctype, 1010 } 1011 } 1012 1013 // NewCxxStreamerSTL creates a new StreamerSTL from C++ informations. 1014 func NewCxxStreamerSTL(se StreamerElement, vtype rmeta.ESTLType, ctype rmeta.Enum) *StreamerSTL { 1015 return &StreamerSTL{ 1016 StreamerElement: se, 1017 vtype: vtype, 1018 ctype: ctype, 1019 } 1020 } 1021 1022 func (*StreamerSTL) RVersion() int16 { return rvers.StreamerSTL } 1023 1024 func (tss *StreamerSTL) Class() string { 1025 return "TStreamerSTL" 1026 } 1027 1028 func (tss *StreamerSTL) ElemTypeName() []string { 1029 return rmeta.CxxTemplateFrom(tss.ename).Args 1030 } 1031 1032 func (tss *StreamerSTL) ContainedType() rmeta.Enum { 1033 return tss.ctype 1034 } 1035 1036 func (tss *StreamerSTL) STLType() rmeta.ESTLType { 1037 return tss.vtype 1038 } 1039 1040 func (tss *StreamerSTL) MarshalROOT(w *rbytes.WBuffer) (int, error) { 1041 if w.Err() != nil { 1042 return 0, w.Err() 1043 } 1044 1045 hdr := w.WriteHeader(tss.Class(), tss.RVersion()) 1046 w.WriteObject(&tss.StreamerElement) 1047 w.WriteI32(int32(tss.vtype)) 1048 w.WriteI32(int32(tss.ctype)) 1049 1050 return w.SetHeader(hdr) 1051 } 1052 1053 func (tss *StreamerSTL) UnmarshalROOT(r *rbytes.RBuffer) error { 1054 if r.Err() != nil { 1055 return r.Err() 1056 } 1057 1058 hdr := r.ReadHeader(tss.Class(), tss.RVersion()) 1059 1060 r.ReadObject(&tss.StreamerElement) 1061 1062 tss.vtype = rmeta.ESTLType(r.ReadI32()) 1063 tss.ctype = rmeta.Enum(r.ReadI32()) 1064 1065 if tss.vtype == rmeta.STLmultimap || tss.vtype == rmeta.STLset { 1066 switch { 1067 case strings.HasPrefix(tss.StreamerElement.ename, "std::set") || strings.HasPrefix(tss.StreamerElement.ename, "set"): 1068 tss.vtype = rmeta.STLset 1069 case strings.HasPrefix(tss.StreamerElement.ename, "std::multimap") || strings.HasPrefix(tss.StreamerElement.ename, "multimap"): 1070 tss.vtype = rmeta.STLmultimap 1071 } 1072 } 1073 1074 r.CheckHeader(hdr) 1075 return r.Err() 1076 } 1077 1078 // func (tss *StreamerSTL) isaPointer() bool { 1079 // tname := tss.StreamerElement.ename 1080 // return strings.HasSuffix(tname, "*") 1081 // } 1082 1083 type StreamerSTLstring struct { 1084 StreamerSTL 1085 } 1086 1087 func (*StreamerSTLstring) RVersion() int16 { return rvers.StreamerSTLstring } 1088 1089 func (tss *StreamerSTLstring) Class() string { 1090 return "TStreamerSTLstring" 1091 } 1092 1093 func (tss *StreamerSTLstring) MarshalROOT(w *rbytes.WBuffer) (int, error) { 1094 if w.Err() != nil { 1095 return 0, w.Err() 1096 } 1097 1098 hdr := w.WriteHeader(tss.Class(), tss.RVersion()) 1099 w.WriteObject(&tss.StreamerSTL) 1100 1101 return w.SetHeader(hdr) 1102 } 1103 1104 func (tss *StreamerSTLstring) UnmarshalROOT(r *rbytes.RBuffer) error { 1105 if r.Err() != nil { 1106 return r.Err() 1107 } 1108 1109 hdr := r.ReadHeader(tss.Class(), tss.RVersion()) 1110 1111 r.ReadObject(&tss.StreamerSTL) 1112 1113 r.CheckHeader(hdr) 1114 return r.Err() 1115 } 1116 1117 type StreamerArtificial struct { 1118 StreamerElement 1119 } 1120 1121 func (*StreamerArtificial) RVersion() int16 { return rvers.StreamerArtificial } 1122 1123 func (tss *StreamerArtificial) Class() string { 1124 return "TStreamerArtificial" 1125 } 1126 1127 func (tsa *StreamerArtificial) MarshalROOT(w *rbytes.WBuffer) (int, error) { 1128 if w.Err() != nil { 1129 return 0, w.Err() 1130 } 1131 1132 hdr := w.WriteHeader(tsa.Class(), tsa.RVersion()) 1133 w.WriteObject(&tsa.StreamerElement) 1134 1135 return w.SetHeader(hdr) 1136 } 1137 1138 func (tsa *StreamerArtificial) UnmarshalROOT(r *rbytes.RBuffer) error { 1139 if r.Err() != nil { 1140 return r.Err() 1141 } 1142 1143 hdr := r.ReadHeader(tsa.Class(), tsa.RVersion()) 1144 1145 r.ReadObject(&tsa.StreamerElement) 1146 1147 r.CheckHeader(hdr) 1148 return r.Err() 1149 } 1150 1151 func genChecksum(name string, elems []rbytes.StreamerElement) uint32 { 1152 var ( 1153 id uint32 1154 hash = func(s string) { 1155 for _, v := range []byte(s) { 1156 id = id*3 + uint32(v) 1157 } 1158 } 1159 ) 1160 1161 hash(name) 1162 1163 // FIXME(sbinet): handle base-classes for std::pair<K,V> 1164 for _, se := range elems { 1165 //if se, ok := se.(*StreamerBase); ok { 1166 // // FIXME(sbinet): get base checksum. 1167 //} 1168 1169 // FIXME(sbinet): add enum handling. 1170 hash(se.Name()) 1171 hash(se.TypeName()) 1172 1173 for _, v := range se.ArrayDims() { 1174 id = id*3 + uint32(v) 1175 } 1176 title := se.Title() 1177 beg := strings.Index(title, "[") 1178 if beg != 0 { 1179 continue 1180 } 1181 end := strings.Index(title, "]") 1182 hash(title[1:end]) 1183 } 1184 1185 return id 1186 } 1187 1188 func init() { 1189 { 1190 f := func() reflect.Value { 1191 o := &StreamerInfo{} 1192 return reflect.ValueOf(o) 1193 } 1194 rtypes.Factory.Add("TStreamerInfo", f) 1195 } 1196 1197 { 1198 f := func() reflect.Value { 1199 o := &StreamerElement{} 1200 return reflect.ValueOf(o) 1201 } 1202 rtypes.Factory.Add("TStreamerElement", f) 1203 } 1204 { 1205 f := func() reflect.Value { 1206 o := &StreamerBase{} 1207 return reflect.ValueOf(o) 1208 } 1209 rtypes.Factory.Add("TStreamerBase", f) 1210 } 1211 { 1212 f := func() reflect.Value { 1213 o := &StreamerBasicType{} 1214 return reflect.ValueOf(o) 1215 } 1216 rtypes.Factory.Add("TStreamerBasicType", f) 1217 } 1218 { 1219 f := func() reflect.Value { 1220 o := &StreamerBasicPointer{} 1221 return reflect.ValueOf(o) 1222 } 1223 rtypes.Factory.Add("TStreamerBasicPointer", f) 1224 } 1225 { 1226 f := func() reflect.Value { 1227 o := &StreamerLoop{} 1228 return reflect.ValueOf(o) 1229 } 1230 rtypes.Factory.Add("TStreamerLoop", f) 1231 } 1232 { 1233 f := func() reflect.Value { 1234 o := &StreamerObject{} 1235 return reflect.ValueOf(o) 1236 } 1237 rtypes.Factory.Add("TStreamerObject", f) 1238 } 1239 { 1240 f := func() reflect.Value { 1241 o := &StreamerObjectPointer{} 1242 return reflect.ValueOf(o) 1243 } 1244 rtypes.Factory.Add("TStreamerObjectPointer", f) 1245 } 1246 { 1247 f := func() reflect.Value { 1248 o := &StreamerObjectAny{} 1249 return reflect.ValueOf(o) 1250 } 1251 rtypes.Factory.Add("TStreamerObjectAny", f) 1252 } 1253 { 1254 f := func() reflect.Value { 1255 o := &StreamerObjectAnyPointer{} 1256 return reflect.ValueOf(o) 1257 } 1258 rtypes.Factory.Add("TStreamerObjectAnyPointer", f) 1259 } 1260 { 1261 f := func() reflect.Value { 1262 o := &StreamerString{} 1263 return reflect.ValueOf(o) 1264 } 1265 rtypes.Factory.Add("TStreamerString", f) 1266 } 1267 { 1268 f := func() reflect.Value { 1269 o := &StreamerSTL{} 1270 return reflect.ValueOf(o) 1271 } 1272 rtypes.Factory.Add("TStreamerSTL", f) 1273 } 1274 { 1275 f := func() reflect.Value { 1276 o := &StreamerSTLstring{ 1277 StreamerSTL: StreamerSTL{ 1278 vtype: rmeta.STLany, 1279 ctype: rmeta.STLstring, 1280 }, 1281 } 1282 return reflect.ValueOf(o) 1283 } 1284 rtypes.Factory.Add("TStreamerSTLstring", f) 1285 } 1286 { 1287 f := func() reflect.Value { 1288 o := &StreamerArtificial{} 1289 return reflect.ValueOf(o) 1290 } 1291 rtypes.Factory.Add("TStreamerArtificial", f) 1292 } 1293 } 1294 1295 var ( 1296 _ root.Object = (*StreamerInfo)(nil) 1297 _ root.Named = (*StreamerInfo)(nil) 1298 _ rbytes.StreamerInfo = (*StreamerInfo)(nil) 1299 _ rbytes.Marshaler = (*StreamerInfo)(nil) 1300 _ rbytes.Unmarshaler = (*StreamerInfo)(nil) 1301 1302 _ root.Object = (*StreamerElement)(nil) 1303 _ root.Named = (*StreamerElement)(nil) 1304 _ rbytes.StreamerElement = (*StreamerElement)(nil) 1305 _ rbytes.Marshaler = (*StreamerElement)(nil) 1306 _ rbytes.Unmarshaler = (*StreamerElement)(nil) 1307 1308 _ root.Object = (*StreamerBase)(nil) 1309 _ root.Named = (*StreamerBase)(nil) 1310 _ rbytes.StreamerElement = (*StreamerBase)(nil) 1311 _ rbytes.Marshaler = (*StreamerBase)(nil) 1312 _ rbytes.Unmarshaler = (*StreamerBase)(nil) 1313 1314 _ root.Object = (*StreamerBasicType)(nil) 1315 _ root.Named = (*StreamerBasicType)(nil) 1316 _ rbytes.StreamerElement = (*StreamerBasicType)(nil) 1317 _ rbytes.Marshaler = (*StreamerBasicType)(nil) 1318 _ rbytes.Unmarshaler = (*StreamerBasicType)(nil) 1319 1320 _ root.Object = (*StreamerBasicPointer)(nil) 1321 _ root.Named = (*StreamerBasicPointer)(nil) 1322 _ rbytes.StreamerElement = (*StreamerBasicPointer)(nil) 1323 _ rbytes.Marshaler = (*StreamerBasicPointer)(nil) 1324 _ rbytes.Unmarshaler = (*StreamerBasicPointer)(nil) 1325 1326 _ root.Object = (*StreamerLoop)(nil) 1327 _ root.Named = (*StreamerLoop)(nil) 1328 _ rbytes.StreamerElement = (*StreamerLoop)(nil) 1329 _ rbytes.Marshaler = (*StreamerLoop)(nil) 1330 _ rbytes.Unmarshaler = (*StreamerLoop)(nil) 1331 1332 _ root.Object = (*StreamerObject)(nil) 1333 _ root.Named = (*StreamerObject)(nil) 1334 _ rbytes.StreamerElement = (*StreamerObject)(nil) 1335 _ rbytes.Marshaler = (*StreamerObject)(nil) 1336 _ rbytes.Unmarshaler = (*StreamerObject)(nil) 1337 1338 _ root.Object = (*StreamerObjectPointer)(nil) 1339 _ root.Named = (*StreamerObjectPointer)(nil) 1340 _ rbytes.StreamerElement = (*StreamerObjectPointer)(nil) 1341 _ rbytes.Marshaler = (*StreamerObjectPointer)(nil) 1342 _ rbytes.Unmarshaler = (*StreamerObjectPointer)(nil) 1343 1344 _ root.Object = (*StreamerObjectAny)(nil) 1345 _ root.Named = (*StreamerObjectAny)(nil) 1346 _ rbytes.StreamerElement = (*StreamerObjectAny)(nil) 1347 _ rbytes.Marshaler = (*StreamerObjectAny)(nil) 1348 _ rbytes.Unmarshaler = (*StreamerObjectAny)(nil) 1349 1350 _ root.Object = (*StreamerString)(nil) 1351 _ root.Named = (*StreamerString)(nil) 1352 _ rbytes.StreamerElement = (*StreamerString)(nil) 1353 _ rbytes.Marshaler = (*StreamerString)(nil) 1354 _ rbytes.Unmarshaler = (*StreamerString)(nil) 1355 1356 _ root.Object = (*StreamerSTL)(nil) 1357 _ root.Named = (*StreamerSTL)(nil) 1358 _ rbytes.StreamerElement = (*StreamerSTL)(nil) 1359 _ rbytes.Marshaler = (*StreamerSTL)(nil) 1360 _ rbytes.Unmarshaler = (*StreamerSTL)(nil) 1361 1362 _ root.Object = (*StreamerSTLstring)(nil) 1363 _ root.Named = (*StreamerSTLstring)(nil) 1364 _ rbytes.StreamerElement = (*StreamerSTLstring)(nil) 1365 _ rbytes.Marshaler = (*StreamerSTLstring)(nil) 1366 _ rbytes.Unmarshaler = (*StreamerSTLstring)(nil) 1367 1368 _ root.Object = (*StreamerArtificial)(nil) 1369 _ root.Named = (*StreamerArtificial)(nil) 1370 _ rbytes.StreamerElement = (*StreamerArtificial)(nil) 1371 _ rbytes.Marshaler = (*StreamerArtificial)(nil) 1372 _ rbytes.Unmarshaler = (*StreamerArtificial)(nil) 1373 )