Skip to content

Commit

Permalink
groot/{rdict,rtree,rvers}: add support for T{Branch,Leaf}Object
Browse files Browse the repository at this point in the history
  • Loading branch information
sbinet committed Dec 16, 2021
1 parent 975023e commit c117054
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 2 deletions.
4 changes: 2 additions & 2 deletions groot/gen.rboot.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ var (
// rtree
"ROOT::TIOFeatures",
"TBasket",
"TBranch", "TBranchElement", "TBranchRef",
"TBranch", "TBranchElement", "TBranchObject", "TBranchRef",
"TChain",
"TLeaf", "TLeafElement",
"TLeaf", "TLeafElement", "TLeafObject",
"TLeafO",
"TLeafB", "TLeafS", "TLeafI", "TLeafL",
"TLeafF", "TLeafD",
Expand Down
56 changes: 56 additions & 0 deletions groot/rdict/cxx_root_streamers_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -4374,6 +4374,34 @@ func init() {
Factor: 0.000000,
}.New()},
}))
StreamerInfos.Add(NewCxxStreamerInfo("TBranchObject", 1, 0xa4720f49, []rbytes.StreamerElement{
NewStreamerBase(Element{
Name: *rbase.NewNamed("TBranch", "Branch descriptor"),
Type: rmeta.Base,
Size: 0,
ArrLen: 0,
ArrDim: 0,
MaxIdx: [5]int32{0, 278366892, 0, 0, 0},
Offset: 0,
EName: "BASE",
XMin: 0.000000,
XMax: 0.000000,
Factor: 0.000000,
}.New(), 13),
&StreamerString{StreamerElement: Element{
Name: *rbase.NewNamed("fClassName", "Class name of referenced object"),
Type: rmeta.TString,
Size: 24,
ArrLen: 0,
ArrDim: 0,
MaxIdx: [5]int32{0, 0, 0, 0, 0},
Offset: 0,
EName: "TString",
XMin: 0.000000,
XMax: 0.000000,
Factor: 0.000000,
}.New()},
}))
StreamerInfos.Add(NewCxxStreamerInfo("TBranchElement", 10, 0xe74f5e63, []rbytes.StreamerElement{
NewStreamerBase(Element{
Name: *rbase.NewNamed("TBranch", "Branch descriptor"),
Expand Down Expand Up @@ -4733,6 +4761,34 @@ func init() {
Factor: 0.000000,
}.New()},
}))
StreamerInfos.Add(NewCxxStreamerInfo("TLeafObject", 4, 0x26ba7c4c, []rbytes.StreamerElement{
NewStreamerBase(Element{
Name: *rbase.NewNamed("TLeaf", "Leaf: description of a Branch data type"),
Type: rmeta.Base,
Size: 0,
ArrLen: 0,
ArrDim: 0,
MaxIdx: [5]int32{0, 1830715730, 0, 0, 0},
Offset: 0,
EName: "BASE",
XMin: 0.000000,
XMax: 0.000000,
Factor: 0.000000,
}.New(), 2),
&StreamerBasicType{StreamerElement: Element{
Name: *rbase.NewNamed("fVirtual", "Support for polymorphism, when set classname is written with object."),
Type: rmeta.Bool,
Size: 1,
ArrLen: 0,
ArrDim: 0,
MaxIdx: [5]int32{0, 0, 0, 0, 0},
Offset: 0,
EName: "bool",
XMin: 0.000000,
XMax: 0.000000,
Factor: 0.000000,
}.New()},
}))
StreamerInfos.Add(NewCxxStreamerInfo("TLeafElement", 1, 0xa04f8893, []rbytes.StreamerElement{
NewStreamerBase(Element{
Name: *rbase.NewNamed("TLeaf", "Leaf: description of a Branch data type"),
Expand Down
78 changes: 78 additions & 0 deletions groot/rtree/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,69 @@ func (b *tbranch) flush() error {
return nil
}

// tbranchObject is a Branch for objects.
type tbranchObject struct {
tbranch
class string // class name of referenced object
}

func (b *tbranchObject) RVersion() int16 {
return rvers.BranchObject
}

func (b *tbranchObject) Class() string {
return "TBranchObject"
}

func (b *tbranchObject) MarshalROOT(w *rbytes.WBuffer) (int, error) {
if w.Err() != nil {
return 0, w.Err()
}

pos := w.WriteVersion(b.RVersion())
if n, err := b.tbranch.MarshalROOT(w); err != nil {
return n, err
}
w.WriteString(b.class)

return w.SetByteCount(pos, b.Class())
}

// ROOTUnmarshaler is the interface implemented by an object that can
// unmarshal itself from a ROOT buffer
func (b *tbranchObject) UnmarshalROOT(r *rbytes.RBuffer) error {
if r.Err() != nil {
return r.Err()
}

beg := r.Pos()
vers, pos, bcnt := r.ReadVersion(b.Class())
if vers < 1 {
r.SetErr(fmt.Errorf("rtree: TBranchObject version too old (%d < 8)", vers))
return r.Err()
}

if err := b.tbranch.UnmarshalROOT(r); err != nil {
return err
}

for _, leaf := range b.leaves {
switch leaf := leaf.(type) {
case *tleaf:
leaf.branch = b
case *tleafObject:
leaf.branch = b
case *tleafElement:
leaf.branch = b
}
}

b.class = r.ReadString()

r.CheckByteCount(pos, bcnt, beg, b.Class())
return r.Err()
}

// tbranchElement is a Branch for objects.
type tbranchElement struct {
tbranch
Expand Down Expand Up @@ -915,6 +978,8 @@ func (b *tbranchElement) UnmarshalROOT(r *rbytes.RBuffer) error {
switch leaf := leaf.(type) {
case *tleaf:
leaf.branch = b
case *tleafObject:
leaf.branch = b
case *tleafElement:
leaf.branch = b
}
Expand Down Expand Up @@ -1110,6 +1175,13 @@ func init() {
}
rtypes.Factory.Add("TBranch", f)
}
{
f := func() reflect.Value {
o := &tbranchObject{}
return reflect.ValueOf(o)
}
rtypes.Factory.Add("TBranchObject", f)
}
{
f := func() reflect.Value {
o := &tbranchElement{}
Expand Down Expand Up @@ -1176,6 +1248,12 @@ var (
_ rbytes.Marshaler = (*tbranch)(nil)
_ rbytes.Unmarshaler = (*tbranch)(nil)

_ root.Object = (*tbranchObject)(nil)
_ root.Named = (*tbranchObject)(nil)
_ Branch = (*tbranchObject)(nil)
_ rbytes.Marshaler = (*tbranchObject)(nil)
_ rbytes.Unmarshaler = (*tbranchObject)(nil)

_ root.Object = (*tbranchElement)(nil)
_ root.Named = (*tbranchElement)(nil)
_ Branch = (*tbranchElement)(nil)
Expand Down
75 changes: 75 additions & 0 deletions groot/rtree/leaf.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,64 @@ func (leaf *tleaf) computeOffsetArray(base, nevts int) []int32 {
return o
}

// tleafObject is a Leaf for a general object derived from Object.
type tleafObject struct {
tleaf
virtual bool
typ reflect.Type
}

func (*tleafObject) RVersion() int16 {
return rvers.LeafObject
}

func (leaf *tleafObject) Class() string {
return "TLeafObject"
}

func (leaf *tleafObject) Type() reflect.Type {
return leaf.typ
}

func (leaf *tleafObject) MarshalROOT(w *rbytes.WBuffer) (int, error) {
if w.Err() != nil {
return 0, w.Err()
}

pos := w.WriteVersion(leaf.RVersion())
_, _ = leaf.tleaf.MarshalROOT(w)
w.WriteBool(leaf.virtual)

return w.SetByteCount(pos, leaf.Class())
}

func (leaf *tleafObject) UnmarshalROOT(r *rbytes.RBuffer) error {
if r.Err() != nil {
return r.Err()
}
beg := r.Pos()

vers, pos, bcnt := r.ReadVersion(leaf.Class())
_ = leaf.tleaf.UnmarshalROOT(r)

if vers < 4 {
panic(fmt.Errorf(
"rtree: TLeafObject %q with version [%v] is not supported (too old)",
leaf.Name(),
vers,
))
}
leaf.virtual = r.ReadBool()

if !rtypes.Factory.HasKey(leaf.Title()) {
return fmt.Errorf("rtree: could not find type %q for TLeafObject %q", leaf.Title(), leaf.Name())
}
leaf.typ = rtypes.Factory.Get(leaf.Title())().Type().Elem()

r.CheckByteCount(pos, bcnt, beg, leaf.Class())
return r.Err()
}

const (
tleafHdrSize = 0
tleafElementHdrSize = 1
Expand All @@ -245,6 +303,10 @@ type tleafElement struct {
streamers []rbytes.StreamerElement
}

func (*tleafElement) RVersion() int16 {
return rvers.LeafElement
}

func (leaf *tleafElement) Class() string {
return "TLeafElement"
}
Expand Down Expand Up @@ -437,6 +499,13 @@ func init() {
}
rtypes.Factory.Add("TLeaf", f)
}
{
f := func() reflect.Value {
o := &tleafObject{}
return reflect.ValueOf(o)
}
rtypes.Factory.Add("TLeafObject", f)
}
{
f := func() reflect.Value {
o := &tleafElement{}
Expand Down Expand Up @@ -799,6 +868,12 @@ var (
_ rbytes.Marshaler = (*tleaf)(nil)
_ rbytes.Unmarshaler = (*tleaf)(nil)

_ root.Object = (*tleafObject)(nil)
_ root.Named = (*tleafObject)(nil)
_ Leaf = (*tleafObject)(nil)
_ rbytes.Marshaler = (*tleafObject)(nil)
_ rbytes.Unmarshaler = (*tleafObject)(nil)

_ root.Object = (*tleafElement)(nil)
_ root.Named = (*tleafElement)(nil)
_ Leaf = (*tleafElement)(nil)
Expand Down
2 changes: 2 additions & 0 deletions groot/rtree/rbranch.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ func asBranch(b Branch) *tbranch {
switch b := b.(type) {
case *tbranch:
return b
case *tbranchObject:
return &b.tbranch
case *tbranchElement:
return &b.tbranch
}
Expand Down
51 changes: 51 additions & 0 deletions groot/rtree/rleaf.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,62 @@ func rleafFrom(leaf Leaf, rvar ReadVar, rctx rleafCtx) rleaf {
case *tleafElement:
return newRLeafElem(leaf, rvar, rctx)

case *tleafObject:
return newRLeafObject(leaf, rvar, rctx)

default:
panic(fmt.Errorf("not implemented %T", leaf))
}
}

type rleafObject struct {
base *tleafObject
v rbytes.Unmarshaler
}

var (
_ rleaf = (*rleafObject)(nil)
)

func newRLeafObject(leaf *tleafObject, rvar ReadVar, rctx rleafCtx) rleaf {
switch {
case leaf.count != nil:
panic("not implemented")
case leaf.len > 1:
panic("not implemented")
default:
return &rleafObject{
base: leaf,
v: reflect.ValueOf(rvar.Value).Interface().(rbytes.Unmarshaler),
}
}
}

func (leaf *rleafObject) Leaf() Leaf { return leaf.base }

func (leaf *rleafObject) Offset() int64 {
return int64(leaf.base.Offset())
}

func (leaf *rleafObject) readFromBuffer(r *rbytes.RBuffer) error {
if leaf.base.virtual {
var (
n = int(r.ReadU8())
class = r.ReadCString(n + 1)
)
if class != leaf.base.Title() {
// FIXME(sbinet): we should be able to handle (C++) polymorphism.
// but in Go, this should translate to interfaces.
panic(fmt.Errorf(
"rtree: rleaf object with incompatible class names: got=%q, want=%q",
class, leaf.base.Title(),
))
}
}

return leaf.v.UnmarshalROOT(r)
}

func newRLeafElem(leaf *tleafElement, rvar ReadVar, rctx rleafCtx) rleaf {
const kind = rbytes.ObjectWise // FIXME(sbinet): infer from stream?

Expand Down
2 changes: 2 additions & 0 deletions groot/rvers/versions_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,12 @@ const (
ROOT_IOFeatures = 1 // ROOT version for ROOT::TIOFeatures
Basket = 3 // ROOT version for TBasket
Branch = 13 // ROOT version for TBranch
BranchObject = 1 // ROOT version for TBranchObject
BranchElement = 10 // ROOT version for TBranchElement
BranchRef = 1 // ROOT version for TBranchRef
Chain = 5 // ROOT version for TChain
Leaf = 2 // ROOT version for TLeaf
LeafObject = 4 // ROOT version for TLeafObject
LeafElement = 1 // ROOT version for TLeafElement
LeafO = 1 // ROOT version for TLeafO
LeafB = 1 // ROOT version for TLeafB
Expand Down

0 comments on commit c117054

Please sign in to comment.