go-hep.org/x/hep@v0.38.1/groot/rtree/leaf.go (about) 1 // Copyright ©2017 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package rtree 6 7 import ( 8 "fmt" 9 "reflect" 10 "regexp" 11 "strconv" 12 "strings" 13 14 "go-hep.org/x/hep/groot/rbase" 15 "go-hep.org/x/hep/groot/rbytes" 16 "go-hep.org/x/hep/groot/rdict" 17 "go-hep.org/x/hep/groot/rmeta" 18 "go-hep.org/x/hep/groot/root" 19 "go-hep.org/x/hep/groot/rtypes" 20 "go-hep.org/x/hep/groot/rvers" 21 ) 22 23 type tleaf struct { 24 named rbase.Named 25 len int // number of fixed length elements in the leaf's data. 26 etype int // number of bytes for this data type 27 offset int // offset in ClonesArray object 28 hasrange bool // whether the leaf has a range 29 unsigned bool // whether the leaf holds unsigned data (uint8, uint16, uint32 or uint64) 30 shape []int 31 count leafCount // leaf count if variable length 32 branch Branch // supporting branch of this leaf 33 } 34 35 func newLeaf(name string, shape []int, etype, offset int, hasrange, unsigned bool, count leafCount, b Branch) tleaf { 36 var ( 37 nelems = 1 38 title = new(strings.Builder) 39 ) 40 41 title.WriteString(name) 42 switch { 43 case count != nil: 44 fmt.Fprintf(title, "[%s]", count.Name()) 45 default: 46 for _, dim := range shape { 47 nelems *= dim 48 fmt.Fprintf(title, "[%d]", dim) 49 } 50 } 51 return tleaf{ 52 named: *rbase.NewNamed(name, title.String()), 53 len: nelems, 54 etype: etype, 55 offset: offset, 56 hasrange: hasrange, 57 unsigned: unsigned, 58 shape: shape, 59 count: count, 60 branch: b, 61 } 62 } 63 64 func (*tleaf) RVersion() int16 { 65 return rvers.Leaf 66 } 67 68 // Name returns the name of the instance 69 func (leaf *tleaf) Name() string { 70 return leaf.named.Name() 71 } 72 73 // Title returns the title of the instance 74 func (leaf *tleaf) Title() string { 75 return leaf.named.Title() 76 } 77 78 func (leaf *tleaf) Class() string { 79 return "TLeaf" 80 } 81 82 func (leaf *tleaf) Shape() []int { 83 return leaf.shape 84 } 85 86 func (leaf *tleaf) setBranch(b Branch) { 87 leaf.branch = b 88 } 89 90 func (leaf *tleaf) Branch() Branch { 91 return leaf.branch 92 } 93 94 func (leaf *tleaf) HasRange() bool { 95 return leaf.hasrange 96 } 97 98 func (leaf *tleaf) IsUnsigned() bool { 99 return leaf.unsigned 100 } 101 102 func (leaf *tleaf) LeafCount() Leaf { 103 return leaf.count 104 } 105 106 func (leaf *tleaf) Len() int { 107 if leaf.count != nil { 108 // variable length array 109 n := leaf.count.ivalue() 110 max := leaf.count.imax() 111 if n > max { 112 n = max 113 } 114 return leaf.len * n 115 } 116 return leaf.len 117 } 118 119 func (leaf *tleaf) LenType() int { 120 return leaf.etype 121 } 122 123 func (leaf *tleaf) Offset() int { 124 return leaf.offset 125 } 126 127 func (leaf *tleaf) Kind() reflect.Kind { 128 panic("not implemented: " + leaf.Name()) 129 } 130 131 func (leaf *tleaf) Type() reflect.Type { 132 panic("not implemented: " + leaf.Name()) 133 } 134 135 func (leaf *tleaf) readFromBuffer(r *rbytes.RBuffer) error { 136 panic("not implemented: " + leaf.Name()) 137 } 138 139 func (leaf *tleaf) setAddress(ptr any) error { 140 panic("not implemented: " + leaf.Name()) 141 } 142 143 func (leaf *tleaf) writeToBuffer(w *rbytes.WBuffer) (int, error) { 144 panic("not implemented: " + leaf.Name()) 145 } 146 147 func (leaf *tleaf) TypeName() string { 148 panic("not implemented: " + leaf.Name()) 149 } 150 151 func (leaf *tleaf) MarshalROOT(w *rbytes.WBuffer) (int, error) { 152 if w.Err() != nil { 153 return 0, w.Err() 154 } 155 156 hdr := w.WriteHeader(leaf.Class(), leaf.RVersion()) 157 w.WriteObject(&leaf.named) 158 159 w.WriteI32(int32(leaf.len)) 160 w.WriteI32(int32(leaf.etype)) 161 w.WriteI32(int32(leaf.offset)) 162 w.WriteBool(leaf.hasrange) 163 w.WriteBool(leaf.unsigned) 164 w.WriteObjectAny(leaf.count) 165 return w.SetHeader(hdr) 166 } 167 168 func (leaf *tleaf) UnmarshalROOT(r *rbytes.RBuffer) error { 169 if r.Err() != nil { 170 return r.Err() 171 } 172 173 hdr := r.ReadHeader(leaf.Class(), leaf.RVersion()) 174 175 r.ReadObject(&leaf.named) 176 leaf.shape = leafDims(leaf.Title()) 177 leaf.len = int(r.ReadI32()) 178 leaf.etype = int(r.ReadI32()) 179 leaf.offset = int(r.ReadI32()) 180 leaf.hasrange = r.ReadBool() 181 leaf.unsigned = r.ReadBool() 182 183 leaf.count = nil 184 ptr := r.ReadObjectAny() 185 if ptr != nil { 186 leaf.count = ptr.(leafCount) 187 } 188 189 if leaf.len == 0 { 190 leaf.len = 1 191 } 192 193 r.CheckHeader(hdr) 194 return r.Err() 195 } 196 197 func (leaf *tleaf) canGenerateOffsetArray() bool { 198 return leaf.count != nil 199 } 200 201 func (leaf *tleaf) computeOffsetArray(base, nevts int) []int32 { 202 o := make([]int32, nevts) 203 if leaf.count == nil { 204 return o 205 } 206 207 var ( 208 hdr = tleafHdrSize 209 origEntry = maxI64(leaf.branch.getReadEntry(), 0) // -1 indicates to start at the beginning 210 origLeafEntry = leaf.count.Branch().getReadEntry() 211 sz int 212 offset = int32(base) 213 ) 214 for i := range nevts { 215 o[i] = offset 216 leaf.count.Branch().getEntry(origEntry + int64(i)) 217 sz = leaf.count.ivalue() 218 offset += int32(leaf.etype*sz + hdr) 219 } 220 leaf.count.Branch().getEntry(origLeafEntry) 221 222 return o 223 } 224 225 // tleafObject is a Leaf for a general object derived from Object. 226 type tleafObject struct { 227 tleaf 228 virtual bool 229 typ reflect.Type 230 } 231 232 func (*tleafObject) RVersion() int16 { 233 return rvers.LeafObject 234 } 235 236 func (leaf *tleafObject) Class() string { 237 return "TLeafObject" 238 } 239 240 func (leaf *tleafObject) Type() reflect.Type { 241 return leaf.typ 242 } 243 244 func (leaf *tleafObject) MarshalROOT(w *rbytes.WBuffer) (int, error) { 245 if w.Err() != nil { 246 return 0, w.Err() 247 } 248 249 hdr := w.WriteHeader(leaf.Class(), leaf.RVersion()) 250 w.WriteObject(&leaf.tleaf) 251 w.WriteBool(leaf.virtual) 252 253 return w.SetHeader(hdr) 254 } 255 256 func (leaf *tleafObject) UnmarshalROOT(r *rbytes.RBuffer) error { 257 if r.Err() != nil { 258 return r.Err() 259 } 260 261 hdr := r.ReadHeader(leaf.Class(), leaf.RVersion()) 262 263 if hdr.Vers < 4 { 264 panic(fmt.Errorf( 265 "rtree: TLeafObject %q with version [%v] is not supported (too old)", 266 leaf.Name(), 267 hdr.Vers, 268 )) 269 } 270 271 r.ReadObject(&leaf.tleaf) 272 leaf.virtual = r.ReadBool() 273 274 if !rtypes.Factory.HasKey(leaf.Title()) { 275 return fmt.Errorf("rtree: could not find type %q for TLeafObject %q", leaf.Title(), leaf.Name()) 276 } 277 leaf.typ = rtypes.Factory.Get(leaf.Title())().Type().Elem() 278 279 r.CheckHeader(hdr) 280 return r.Err() 281 } 282 283 const ( 284 tleafHdrSize = 0 285 tleafElementHdrSize = 1 286 ) 287 288 // tleafElement is a Leaf for a general object derived from Object. 289 type tleafElement struct { 290 rvers int16 291 tleaf 292 id int32 // element serial number in fInfo 293 ltype int32 // leaf type 294 295 ptr any 296 src reflect.Value 297 rstreamer rbytes.RStreamer 298 wstreamer rbytes.WStreamer 299 streamers []rbytes.StreamerElement 300 } 301 302 func (*tleafElement) RVersion() int16 { 303 return rvers.LeafElement 304 } 305 306 func (leaf *tleafElement) Class() string { 307 return "TLeafElement" 308 } 309 310 func (leaf *tleafElement) ivalue() int { 311 return int(leaf.src.Int()) 312 } 313 314 func (leaf *tleafElement) imax() int { 315 panic("not implemented") 316 } 317 318 func (leaf *tleafElement) Kind() reflect.Kind { 319 return leaf.src.Kind() 320 } 321 322 func (leaf *tleafElement) Type() reflect.Type { 323 return leaf.src.Type() 324 } 325 326 func (leaf *tleafElement) TypeName() string { 327 name := leaf.src.Type().Name() 328 if name == "" { 329 panic(fmt.Errorf("rtree: invalid typename for leaf %q", leaf.Name())) 330 } 331 return name 332 } 333 334 func (leaf *tleafElement) MarshalROOT(w *rbytes.WBuffer) (int, error) { 335 if w.Err() != nil { 336 return 0, w.Err() 337 } 338 339 hdr := w.WriteHeader(leaf.Class(), leaf.rvers) 340 w.WriteObject(&leaf.tleaf) 341 w.WriteI32(leaf.id) 342 w.WriteI32(leaf.ltype) 343 344 return w.SetHeader(hdr) 345 } 346 347 func (leaf *tleafElement) UnmarshalROOT(r *rbytes.RBuffer) error { 348 if r.Err() != nil { 349 return r.Err() 350 } 351 352 hdr := r.ReadHeader(leaf.Class(), leaf.RVersion()) 353 leaf.rvers = hdr.Vers 354 355 r.ReadObject(&leaf.tleaf) 356 leaf.id = r.ReadI32() 357 leaf.ltype = r.ReadI32() 358 359 r.CheckHeader(hdr) 360 return r.Err() 361 } 362 363 func (leaf *tleafElement) readFromBuffer(r *rbytes.RBuffer) error { 364 if r.Err() != nil { 365 return r.Err() 366 } 367 368 if leaf.rstreamer == nil { 369 panic(fmt.Errorf("rtree: nil streamer (leaf: %s)", leaf.Name())) 370 } 371 372 err := leaf.rstreamer.RStreamROOT(r) 373 if err != nil { 374 return err 375 } 376 377 return nil 378 } 379 380 func (leaf *tleafElement) setAddress(ptr any) error { 381 leaf.ptr = ptr 382 leaf.src = reflect.ValueOf(leaf.ptr).Elem() 383 384 if leaf.rstreamer != nil { 385 return leaf.setReadAddress(ptr) 386 } 387 388 if leaf.wstreamer != nil { 389 return leaf.setWriteAddress(ptr) 390 } 391 392 return fmt.Errorf("rtree: leaf %q is neither read nor write", leaf.Name()) 393 } 394 395 func (leaf *tleafElement) setReadAddress(ptr any) error { 396 err := leaf.rstreamer.(rbytes.Binder).Bind(ptr) 397 if err != nil { 398 return fmt.Errorf("rtree: could not bind read-streamer for leaf=%q (type=%s) to ptr=%T: %w", 399 leaf.Name(), leaf.TypeName(), leaf.ptr, err, 400 ) 401 } 402 if leaf.count != nil { 403 r, ok := leaf.rstreamer.(rbytes.Counter) 404 if !ok { 405 return fmt.Errorf( 406 "rtree: could not set read-streamer counter for leaf=%q (type=%s)", 407 leaf.Name(), leaf.TypeName(), 408 ) 409 } 410 err = r.Count(leaf.count.ivalue) 411 if err != nil { 412 return fmt.Errorf( 413 "rtree: could not set read-streamer counter for leaf=%q (type=%s): %w", 414 leaf.Name(), leaf.TypeName(), err, 415 ) 416 } 417 } 418 return nil 419 } 420 421 func (leaf *tleafElement) setWriteAddress(ptr any) error { 422 err := leaf.wstreamer.(rbytes.Binder).Bind(ptr) 423 if err != nil { 424 return fmt.Errorf("rtree: could not bind write-streamer for leaf=%q (type=%s) to ptr=%T: %w", 425 leaf.Name(), leaf.TypeName(), leaf.ptr, err, 426 ) 427 } 428 if leaf.count != nil { 429 w, ok := leaf.wstreamer.(rbytes.Counter) 430 if !ok { 431 return fmt.Errorf( 432 "rtree: could not set write-streamer counter for leaf=%q (type=%s)", 433 leaf.Name(), leaf.TypeName(), 434 ) 435 } 436 err = w.Count(leaf.count.ivalue) 437 if err != nil { 438 return fmt.Errorf( 439 "rtree: could not set write-streamer counter for leaf=%q (type=%s): %w", 440 leaf.Name(), leaf.TypeName(), err, 441 ) 442 } 443 } 444 return nil 445 } 446 447 func (leaf *tleafElement) writeToBuffer(w *rbytes.WBuffer) (int, error) { 448 if w.Err() != nil { 449 return 0, w.Err() 450 } 451 452 if leaf.wstreamer == nil { 453 panic(fmt.Errorf("rtree: nil write-streamer (leaf: %s)", leaf.Name())) 454 } 455 456 pos := w.Pos() 457 err := leaf.wstreamer.WStreamROOT(w) 458 return int(w.Pos() - pos), err 459 } 460 461 func (leaf *tleafElement) canGenerateOffsetArray() bool { 462 return leaf.count != nil && leaf.tleaf.etype != 0 463 } 464 465 func (leaf *tleafElement) computeOffsetArray(base, nevts int) []int32 { 466 o := make([]int32, nevts) 467 if leaf.count == nil { 468 return o 469 } 470 471 var ( 472 hdr = tleafElementHdrSize 473 origEntry = maxI64(leaf.branch.getReadEntry(), 0) // -1 indicates to start at the beginning 474 origLeafEntry = leaf.count.Branch().getReadEntry() 475 sz int 476 offset = int32(base) 477 ) 478 for i := range nevts { 479 o[i] = offset 480 leaf.count.Branch().getEntry(origEntry + int64(i)) 481 sz = leaf.count.ivalue() 482 offset += int32(leaf.etype*sz + hdr) 483 } 484 leaf.count.Branch().getEntry(origLeafEntry) 485 486 return o 487 } 488 489 func init() { 490 { 491 f := func() reflect.Value { 492 o := &tleaf{} 493 return reflect.ValueOf(o) 494 } 495 rtypes.Factory.Add("TLeaf", f) 496 } 497 { 498 f := func() reflect.Value { 499 o := &tleafObject{} 500 return reflect.ValueOf(o) 501 } 502 rtypes.Factory.Add("TLeafObject", f) 503 } 504 { 505 f := func() reflect.Value { 506 o := &tleafElement{} 507 return reflect.ValueOf(o) 508 } 509 rtypes.Factory.Add("TLeafElement", f) 510 } 511 } 512 513 var ( 514 reLeafDims = regexp.MustCompile(`\w*?\[(\d*)\]+?`) 515 ) 516 517 func leafDims(s string) []int { 518 out := reLeafDims.FindAllStringSubmatch(s, -1) 519 if len(out) == 0 { 520 return nil 521 } 522 523 dims := make([]int, len(out)) 524 for i := range out { 525 v := out[i][1] 526 switch v { 527 case "": 528 dims[i] = -1 // variable size 529 default: 530 dim, err := strconv.Atoi(v) 531 if err != nil { 532 panic(fmt.Errorf("could not infer leaf array dimension: %w", err)) 533 } 534 dims[i] = dim 535 } 536 } 537 538 return dims 539 } 540 541 func gotypeToROOTTypeCode(rt reflect.Type) string { 542 switch rt.Kind() { 543 case reflect.Bool: 544 return "O" 545 case reflect.String: 546 return "C" 547 case reflect.Int8: 548 return "B" 549 case reflect.Int16: 550 return "S" 551 case reflect.Int32: 552 return "I" 553 case reflect.Int64: 554 return "L" 555 case reflect.Uint8: 556 return "b" 557 case reflect.Uint16: 558 return "s" 559 case reflect.Uint32: 560 return "i" 561 case reflect.Uint64: 562 return "l" 563 case reflect.Float32: 564 if rt == reflect.TypeOf(root.Float16(0)) { 565 return "f" 566 } 567 return "F" 568 case reflect.Float64: 569 if rt == reflect.TypeOf(root.Double32(0)) { 570 return "d" 571 } 572 return "D" 573 case reflect.Array: 574 return gotypeToROOTTypeCode(rt.Elem()) 575 case reflect.Slice: 576 return gotypeToROOTTypeCode(rt.Elem()) 577 } 578 panic("impossible") 579 } 580 581 func newLeafFromWVar(w *wtree, b Branch, v WriteVar, lvl int, cfg wopt) (Leaf, error) { 582 const ( 583 signed = false 584 unsigned = true 585 ) 586 587 var ( 588 rv = reflect.Indirect(reflect.ValueOf(v.Value)) 589 rt, shape = flattenArrayType(rv.Type()) 590 kind = rt.Kind() 591 leaf Leaf 592 count leafCount 593 addLeaf func(leaf Leaf) 594 ) 595 596 switch b := b.(type) { 597 case *tbranch: 598 addLeaf = func(leaf Leaf) { 599 b.leaves = append(b.leaves, leaf) 600 w.ttree.leaves = append(w.ttree.leaves, leaf) 601 } 602 case *tbranchElement: 603 addLeaf = func(leaf Leaf) { 604 if _, ok := leaf.(*tleafElement); !ok { 605 lb, ltyp := asLeafBase(leaf) 606 607 if b.bup != nil { 608 lb.named.SetName(b.bup.Name() + "." + lb.Name()) 609 lb.named.SetTitle(b.bup.Name() + "." + lb.Title()) 610 } 611 leaf = &tleafElement{ 612 rvers: rvers.LeafElement, 613 tleaf: *lb, 614 id: -1, // FIXME(sbinet): infer correct index 615 ltype: int32(ltyp), 616 } 617 } 618 619 b.leaves = append(b.leaves, leaf) 620 w.ttree.leaves = append(w.ttree.leaves, leaf) 621 } 622 } 623 624 switch kind { 625 case reflect.Slice: 626 lc := b.Leaf(v.Count) 627 switch lc { 628 case nil: 629 // write as vector<T>. 630 const ( 631 offset = 0 632 hasrange = false 633 unsigned = false 634 ) 635 base := newLeaf(v.Name, nil, int(rt.Size()), offset, hasrange, unsigned, count, b) 636 leaf := &tleafElement{ 637 rvers: rvers.LeafElement, 638 tleaf: base, 639 id: -1, // FIXME(sbinet): create proper serial number 640 ltype: 2, // FIXME(sbinet) 641 ptr: v.Value, 642 src: reflect.ValueOf(v.Value), 643 } 644 si := rdict.StreamerOf(w.ttree.f, reflect.TypeOf(v.Value).Elem()) 645 646 var err error 647 leaf.wstreamer, err = si.NewWStreamer(rbytes.ObjectWise) 648 if err != nil { 649 return nil, fmt.Errorf("could not create w-streamer for leaf %q: %w", v.Name, err) 650 } 651 652 err = leaf.setAddress(v.Value) 653 if err != nil { 654 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 655 } 656 657 addLeaf(leaf) 658 return leaf, nil 659 660 default: 661 lcc, ok := lc.(leafCount) 662 if !ok { 663 return nil, fmt.Errorf( 664 "leaf count %q from branch %q for slice (name=%q, type=%T) is not a LeafCount", 665 v.Count, b.Name(), v.Name, v.Value, 666 ) 667 } 668 count = lcc 669 kind = rt.Elem().Kind() 670 } 671 672 case reflect.Struct: 673 const ( 674 offset = 0 675 hasrange = false 676 unsigned = false 677 ) 678 base := newLeaf(v.Name, nil, int(rt.Size()), offset, hasrange, unsigned, count, b) 679 leaf := &tleafElement{ 680 rvers: rvers.LeafElement, 681 tleaf: base, 682 id: -1, // FIXME(sbinet): create proper serial number 683 ltype: -1, // FIXME(sbinet) 684 ptr: v.Value, 685 src: reflect.ValueOf(v.Value), 686 } 687 si := rdict.StreamerOf(w.ttree.f, reflect.TypeOf(v.Value).Elem()) 688 wstreamer, err := si.NewWStreamer(rbytes.ObjectWise) 689 if err != nil { 690 return nil, fmt.Errorf("could not create w-streamer for leaf %q: %w", v.Name, err) 691 } 692 leaf.wstreamer = wstreamer 693 694 err = leaf.setAddress(v.Value) 695 if err != nil { 696 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 697 } 698 addLeaf(leaf) 699 return leaf, nil 700 } 701 702 switch kind { 703 case reflect.Bool: 704 leaf = newLeafO(b, v.Name, shape, false, count) 705 err := leaf.setAddress(v.Value) 706 if err != nil { 707 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 708 } 709 addLeaf(leaf) 710 711 case reflect.Uint8: 712 leaf = newLeafB(b, v.Name, shape, unsigned, count) 713 err := leaf.setAddress(v.Value) 714 if err != nil { 715 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 716 } 717 addLeaf(leaf) 718 719 case reflect.Uint16: 720 leaf = newLeafS(b, v.Name, shape, unsigned, count) 721 err := leaf.setAddress(v.Value) 722 if err != nil { 723 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 724 } 725 addLeaf(leaf) 726 727 case reflect.Uint32: 728 leaf = newLeafI(b, v.Name, shape, unsigned, count) 729 err := leaf.setAddress(v.Value) 730 if err != nil { 731 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 732 } 733 addLeaf(leaf) 734 735 case reflect.Uint64: 736 leaf = newLeafL(b, v.Name, shape, unsigned, count) 737 err := leaf.setAddress(v.Value) 738 if err != nil { 739 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 740 } 741 addLeaf(leaf) 742 743 case reflect.Int8: 744 leaf = newLeafB(b, v.Name, shape, signed, count) 745 err := leaf.setAddress(v.Value) 746 if err != nil { 747 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 748 } 749 addLeaf(leaf) 750 751 case reflect.Int16: 752 leaf = newLeafS(b, v.Name, shape, signed, count) 753 err := leaf.setAddress(v.Value) 754 if err != nil { 755 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 756 } 757 addLeaf(leaf) 758 759 case reflect.Int32: 760 leaf = newLeafI(b, v.Name, shape, signed, count) 761 err := leaf.setAddress(v.Value) 762 if err != nil { 763 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 764 } 765 addLeaf(leaf) 766 767 case reflect.Int64: 768 leaf = newLeafL(b, v.Name, shape, signed, count) 769 err := leaf.setAddress(v.Value) 770 if err != nil { 771 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 772 } 773 addLeaf(leaf) 774 775 case reflect.Float32: 776 switch rt { 777 case reflect.TypeOf(float32(0)), reflect.TypeOf([]float32(nil)): 778 leaf = newLeafF(b, v.Name, shape, signed, count) 779 err := leaf.setAddress(v.Value) 780 if err != nil { 781 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 782 } 783 addLeaf(leaf) 784 785 case reflect.TypeOf(root.Float16(0)), reflect.TypeOf([]root.Float16(nil)): 786 leaf = newLeafF16(b, v.Name, shape, signed, count, nil) 787 err := leaf.setAddress(v.Value) 788 if err != nil { 789 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 790 } 791 addLeaf(leaf) 792 793 default: 794 panic(fmt.Errorf("invalid type %T", v.Value)) 795 } 796 case reflect.Float64: 797 switch rt { 798 case reflect.TypeOf(float64(0)), reflect.TypeOf([]float64(nil)): 799 leaf = newLeafD(b, v.Name, shape, signed, count) 800 err := leaf.setAddress(v.Value) 801 if err != nil { 802 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 803 } 804 addLeaf(leaf) 805 806 case reflect.TypeOf(root.Double32(0)), reflect.TypeOf([]root.Double32(nil)): 807 leaf = newLeafD32(b, v.Name, shape, signed, count, nil) 808 err := leaf.setAddress(v.Value) 809 if err != nil { 810 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 811 } 812 addLeaf(leaf) 813 814 default: 815 panic(fmt.Errorf("invalid type %T", v.Value)) 816 } 817 case reflect.String: 818 leaf = newLeafC(b, v.Name, shape, signed, count) 819 err := leaf.setAddress(v.Value) 820 if err != nil { 821 return nil, fmt.Errorf("could not set leaf address for %q: %w", v.Name, err) 822 } 823 addLeaf(leaf) 824 825 default: 826 return nil, fmt.Errorf("rtree: invalid write-var (name=%q) type %T", v.Name, v.Value) 827 } 828 829 return leaf, nil 830 } 831 832 func asLeafBase(leaf Leaf) (*tleaf, rmeta.Enum) { 833 switch leaf := leaf.(type) { 834 case *LeafO: 835 return &leaf.tleaf, rmeta.Bool 836 case *LeafB: 837 return &leaf.tleaf, rmeta.Int8 838 case *LeafS: 839 return &leaf.tleaf, rmeta.Int16 840 case *LeafI: 841 return &leaf.tleaf, rmeta.Int32 842 case *LeafL: 843 return &leaf.tleaf, rmeta.Int64 844 case *LeafF: 845 return &leaf.tleaf, rmeta.Float32 846 case *LeafD: 847 return &leaf.tleaf, rmeta.Float64 848 case *LeafF16: 849 return &leaf.tleaf, rmeta.Float16 850 case *LeafD32: 851 return &leaf.tleaf, rmeta.Double32 852 case *LeafC: 853 return &leaf.tleaf, rmeta.CharStar // FIXME(sbinet): rmeta.Char? 854 default: 855 panic(fmt.Errorf("rtree: invalid leaf type %T", leaf)) 856 } 857 } 858 859 var ( 860 _ root.Object = (*tleaf)(nil) 861 _ root.Named = (*tleaf)(nil) 862 _ Leaf = (*tleaf)(nil) 863 _ rbytes.Marshaler = (*tleaf)(nil) 864 _ rbytes.Unmarshaler = (*tleaf)(nil) 865 866 _ root.Object = (*tleafObject)(nil) 867 _ root.Named = (*tleafObject)(nil) 868 _ Leaf = (*tleafObject)(nil) 869 _ rbytes.Marshaler = (*tleafObject)(nil) 870 _ rbytes.Unmarshaler = (*tleafObject)(nil) 871 872 _ root.Object = (*tleafElement)(nil) 873 _ root.Named = (*tleafElement)(nil) 874 _ Leaf = (*tleafElement)(nil) 875 _ rbytes.Marshaler = (*tleafElement)(nil) 876 _ rbytes.Unmarshaler = (*tleafElement)(nil) 877 )