Skip to content
This repository was archived by the owner on Oct 30, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions groot/cmd/root-gen-type/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ func TestGenerate(t *testing.T) {
want: "testdata/small-evnt-tree-fullsplit.txt",
types: []string{"Event", "P3"},
},
{
fname: "../../testdata/tbase.root",
want: "testdata/tbase.txt",
types: []string{"Base", "D1", "D2"},
},
} {
t.Run(tc.fname, func(t *testing.T) {
oname := filepath.Base(tc.fname) + ".go"
Expand Down
284 changes: 284 additions & 0 deletions groot/cmd/root-gen-type/testdata/tbase.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
// DO NOT EDIT; automatically generated by root-gen-type

package main

import (
"fmt"
"reflect"

"go-hep.org/x/hep/groot/rbase"
"go-hep.org/x/hep/groot/rbytes"
"go-hep.org/x/hep/groot/rdict"
"go-hep.org/x/hep/groot/rmeta"
"go-hep.org/x/hep/groot/root"
"go-hep.org/x/hep/groot/rtypes"
)

type D1 struct {
base0 Base `groot:"BASE-Base"` // base class
D32 int32 `groot:"D32"`
}

func (*D1) Class() string {
return "D1"
}

func (*D1) RVersion() int16 {
return 1
}

// MarshalROOT implements rbytes.Marshaler
func (o *D1) MarshalROOT(w *rbytes.WBuffer) (int, error) {
if w.Err() != nil {
return 0, w.Err()
}

hdr := w.WriteHeader(o.Class(), o.RVersion())

w.WriteObject(&o.base0)
w.WriteI32(o.D32)

return w.SetHeader(hdr)
}

// UnmarshalROOT implements rbytes.Unmarshaler
func (o *D1) UnmarshalROOT(r *rbytes.RBuffer) error {
if r.Err() != nil {
return r.Err()
}

hdr := r.ReadHeader(o.Class())
if hdr.Vers > o.RVersion() {
panic(fmt.Errorf(
"rbytes: invalid %s version=%d > %d",
o.Class(), hdr.Vers, o.RVersion(),
))
}

r.ReadObject(&o.base0)
o.D32 = r.ReadI32()

r.CheckHeader(hdr)
return r.Err()
}

func init() {
f := func() reflect.Value {
var o D1
return reflect.ValueOf(&o)
}
rtypes.Factory.Add("D1", f)
}

func init() {
// Streamer for D1.
rdict.StreamerInfos.Add(rdict.NewCxxStreamerInfo("D1", 1, 0x665ff02a, []rbytes.StreamerElement{
rdict.NewStreamerBase(rdict.Element{
Name: *rbase.NewNamed("Base", ""),
Type: rmeta.Base,
Size: 0,
ArrLen: 0,
ArrDim: 0,
MaxIdx: [5]int32{0, 2285240, 0, 0, 0},
Offset: 0,
EName: "BASE",
XMin: 0.000000,
XMax: 0.000000,
Factor: 0.000000,
}.New(), -1),
&rdict.StreamerBasicType{StreamerElement: rdict.Element{
Name: *rbase.NewNamed("D32", ""),
Type: rmeta.Int,
Size: 4,
ArrLen: 0,
ArrDim: 0,
MaxIdx: [5]int32{0, 0, 0, 0, 0},
Offset: 0,
EName: "int",
XMin: 0.000000,
XMax: 0.000000,
Factor: 0.000000,
}.New()},
}))
}

var (
_ root.Object = (*D1)(nil)
_ rbytes.RVersioner = (*D1)(nil)
_ rbytes.Marshaler = (*D1)(nil)
_ rbytes.Unmarshaler = (*D1)(nil)
)

type Base struct {
I32 int32 `groot:"I32"`
}

func (*Base) Class() string {
return "Base"
}

func (*Base) RVersion() int16 {
return 1
}

// MarshalROOT implements rbytes.Marshaler
func (o *Base) MarshalROOT(w *rbytes.WBuffer) (int, error) {
if w.Err() != nil {
return 0, w.Err()
}

hdr := w.WriteHeader(o.Class(), o.RVersion())

w.WriteI32(o.I32)

return w.SetHeader(hdr)
}

// UnmarshalROOT implements rbytes.Unmarshaler
func (o *Base) UnmarshalROOT(r *rbytes.RBuffer) error {
if r.Err() != nil {
return r.Err()
}

hdr := r.ReadHeader(o.Class())
if hdr.Vers > o.RVersion() {
panic(fmt.Errorf(
"rbytes: invalid %s version=%d > %d",
o.Class(), hdr.Vers, o.RVersion(),
))
}

o.I32 = r.ReadI32()

r.CheckHeader(hdr)
return r.Err()
}

func init() {
f := func() reflect.Value {
var o Base
return reflect.ValueOf(&o)
}
rtypes.Factory.Add("Base", f)
}

func init() {
// Streamer for Base.
rdict.StreamerInfos.Add(rdict.NewCxxStreamerInfo("Base", 1, 0x22deb8, []rbytes.StreamerElement{
&rdict.StreamerBasicType{StreamerElement: rdict.Element{
Name: *rbase.NewNamed("I32", ""),
Type: rmeta.Int,
Size: 4,
ArrLen: 0,
ArrDim: 0,
MaxIdx: [5]int32{0, 0, 0, 0, 0},
Offset: 0,
EName: "int",
XMin: 0.000000,
XMax: 0.000000,
Factor: 0.000000,
}.New()},
}))
}

var (
_ root.Object = (*Base)(nil)
_ rbytes.RVersioner = (*Base)(nil)
_ rbytes.Marshaler = (*Base)(nil)
_ rbytes.Unmarshaler = (*Base)(nil)
)

type D2 struct {
base0 Base `groot:"BASE-Base"` // base class
I32 int32 `groot:"I32"`
}

func (*D2) Class() string {
return "D2"
}

func (*D2) RVersion() int16 {
return 1
}

// MarshalROOT implements rbytes.Marshaler
func (o *D2) MarshalROOT(w *rbytes.WBuffer) (int, error) {
if w.Err() != nil {
return 0, w.Err()
}

hdr := w.WriteHeader(o.Class(), o.RVersion())

w.WriteObject(&o.base0)
w.WriteI32(o.I32)

return w.SetHeader(hdr)
}

// UnmarshalROOT implements rbytes.Unmarshaler
func (o *D2) UnmarshalROOT(r *rbytes.RBuffer) error {
if r.Err() != nil {
return r.Err()
}

hdr := r.ReadHeader(o.Class())
if hdr.Vers > o.RVersion() {
panic(fmt.Errorf(
"rbytes: invalid %s version=%d > %d",
o.Class(), hdr.Vers, o.RVersion(),
))
}

r.ReadObject(&o.base0)
o.I32 = r.ReadI32()

r.CheckHeader(hdr)
return r.Err()
}

func init() {
f := func() reflect.Value {
var o D2
return reflect.ValueOf(&o)
}
rtypes.Factory.Add("D2", f)
}

func init() {
// Streamer for D2.
rdict.StreamerInfos.Add(rdict.NewCxxStreamerInfo("D2", 1, 0x6662a8e4, []rbytes.StreamerElement{
rdict.NewStreamerBase(rdict.Element{
Name: *rbase.NewNamed("Base", ""),
Type: rmeta.Base,
Size: 0,
ArrLen: 0,
ArrDim: 0,
MaxIdx: [5]int32{0, 2285240, 0, 0, 0},
Offset: 0,
EName: "BASE",
XMin: 0.000000,
XMax: 0.000000,
Factor: 0.000000,
}.New(), -1),
&rdict.StreamerBasicType{StreamerElement: rdict.Element{
Name: *rbase.NewNamed("I32", ""),
Type: rmeta.Int,
Size: 4,
ArrLen: 0,
ArrDim: 0,
MaxIdx: [5]int32{0, 0, 0, 0, 0},
Offset: 0,
EName: "int",
XMin: 0.000000,
XMax: 0.000000,
Factor: 0.000000,
}.New()},
}))
}

var (
_ root.Object = (*D2)(nil)
_ rbytes.RVersioner = (*D2)(nil)
_ rbytes.Marshaler = (*D2)(nil)
_ rbytes.Unmarshaler = (*D2)(nil)
)
2 changes: 1 addition & 1 deletion groot/rdict/gen_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ func (o *%[1]s) MarshalROOT(w *rbytes.WBuffer) (int, error) {
func (g *genGoType) genMarshalField(si rbytes.StreamerInfo, i int, se rbytes.StreamerElement) {
switch se := se.(type) {
case *StreamerBase:
g.printf("w.Write(&o.%s)\n", fmt.Sprintf("base%d", i))
g.printf("w.WriteObject(&o.%s)\n", fmt.Sprintf("base%d", i))

case *StreamerBasicPointer:
title := se.Title()
Expand Down
75 changes: 75 additions & 0 deletions groot/riofs/gendata/gen-base.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright ©2022 The go-hep Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build ignore

package main

import (
"flag"
"log"

"go-hep.org/x/hep/groot/internal/rtests"
)

var (
root = flag.String("f", "test-base.root", "output ROOT file")
split = flag.Int("split", 0, "default split-level for TTree")
)

func main() {
flag.Parse()

out, err := rtests.RunCxxROOT("gentree", []byte(script), *root, *split)
if err != nil {
log.Fatalf("could not run ROOT macro:\noutput:\n%v\nerror: %+v", string(out), err)
}
}

const script = `
#include <stdint.h>

class Base {
public:
int32_t I32;
};

class D1 : public Base {
public:
int32_t D32;
};

class D2 : public Base {
public:
int32_t I32;
};

void gentree(const char* fname, int splitlvl = 99) {
int bufsize = 32000;
int evtmax = 2;

auto f = TFile::Open(fname, "RECREATE");
auto t = new TTree("tree", "my tree title");

D1 d1;
D2 d2;

t->Branch("d1", &d1, bufsize, splitlvl);
t->Branch("d2", &d2, bufsize, splitlvl);

for (int i = 0; i != evtmax; i++) {
d1.I32 = i+1;
d1.D32 = i+2;
((Base*)&d2)->I32 = i+3;
d2.I32 = i+4;

t->Fill();
}

f->Write();
f->Close();

exit(0);
}
`
1 change: 1 addition & 0 deletions groot/riofs/riofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
//go:generate go run ./gendata/gen-tprofile.go -f ../testdata/tprofile.root
//go:generate go run ./gendata/gen-tgme.go -f ../testdata/tgme.root
//go:generate go run ./gendata/gen-tdatime.go -f ../testdata/tdatime.root
//go:generate go run ./gendata/gen-base.go -f ../testdata/tbase.root

// Directory describes a ROOT directory structure in memory.
type Directory interface {
Expand Down
Binary file added groot/testdata/tbase.root
Binary file not shown.