go-hep.org/x/hep@v0.38.1/groot/gen.rcont.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 //go:build ignore 6 7 package main 8 9 import ( 10 "fmt" 11 "log" 12 "os" 13 "text/template" 14 15 "go-hep.org/x/hep/groot/internal/genroot" 16 "go-hep.org/x/hep/groot/internal/rtests" 17 ) 18 19 func main() { 20 genArrays() 21 genTClonesArrayData() 22 } 23 24 func genArrays() { 25 fname := "./rcont/array_gen.go" 26 year := genroot.ExtractYear(fname) 27 f, err := os.Create(fname) 28 if err != nil { 29 log.Fatal(err) 30 } 31 defer f.Close() 32 33 genroot.GenImports(year, "rcont", f, 34 "reflect", 35 "", 36 "go-hep.org/x/hep/groot/root", 37 "go-hep.org/x/hep/groot/rbytes", 38 "go-hep.org/x/hep/groot/rtypes", 39 "go-hep.org/x/hep/groot/rvers", 40 ) 41 42 for i, typ := range []struct { 43 Name string 44 Type string 45 RFunc string 46 DType string 47 WFunc string 48 }{ 49 { 50 Name: "ArrayC", 51 Type: "int8", 52 RFunc: "r.ReadArrayI8", 53 DType: "I8", 54 WFunc: "w.WriteArrayI8", 55 }, 56 { 57 Name: "ArrayS", 58 Type: "int16", 59 RFunc: "r.ReadArrayI16", 60 DType: "I16", 61 WFunc: "w.WriteArrayI16", 62 }, 63 { 64 Name: "ArrayI", 65 Type: "int32", 66 RFunc: "r.ReadArrayI32", 67 DType: "I32", 68 WFunc: "w.WriteArrayI32", 69 }, 70 { 71 Name: "ArrayL", 72 Type: "int64", 73 RFunc: "r.ReadArrayI64", 74 DType: "I64", 75 WFunc: "w.WriteArrayI64", 76 }, 77 { 78 Name: "ArrayL64", 79 Type: "int64", 80 RFunc: "r.ReadArrayI64", 81 DType: "I64", 82 WFunc: "w.WriteArrayI64", 83 }, 84 { 85 Name: "ArrayF", 86 Type: "float32", 87 RFunc: "r.ReadArrayF32", 88 DType: "F32", 89 WFunc: "w.WriteArrayF32", 90 }, 91 { 92 Name: "ArrayD", 93 Type: "float64", 94 RFunc: "r.ReadArrayF64", 95 DType: "F64", 96 WFunc: "w.WriteArrayF64", 97 }, 98 } { 99 if i > 0 { 100 fmt.Fprintf(f, "\n") 101 } 102 tmpl := template.Must(template.New(typ.Name).Parse(arrayTmpl)) 103 err = tmpl.Execute(f, typ) 104 if err != nil { 105 log.Fatalf("error executing template for %q: %v\n", typ.Name, err) 106 } 107 } 108 109 err = f.Close() 110 if err != nil { 111 log.Fatal(err) 112 } 113 genroot.GoFmt(f) 114 } 115 116 const arrayTmpl = `// {{.Name}} implements ROOT T{{.Name}} 117 type {{.Name}} struct { 118 Data []{{.Type}} 119 } 120 121 func (*{{.Name}}) RVersion() int16 { 122 return rvers.{{.Name}} 123 } 124 125 // Class returns the ROOT class name. 126 func (*{{.Name}}) Class() string { 127 return "T{{.Name}}" 128 } 129 130 func (arr *{{.Name}}) Len() int { 131 return len(arr.Data) 132 } 133 134 func (arr *{{.Name}}) At(i int) {{.Type}} { 135 return arr.Data[i] 136 } 137 138 func (arr *{{.Name}}) Get(i int) any { 139 return arr.Data[i] 140 } 141 142 func (arr *{{.Name}}) Set(i int, v any) { 143 arr.Data[i] = v.({{.Type}}) 144 } 145 146 func (arr *{{.Name}}) MarshalROOT(w *rbytes.WBuffer) (int, error) { 147 if w.Err() != nil { 148 return 0, w.Err() 149 } 150 151 pos := w.Pos() 152 w.WriteI32(int32(len(arr.Data))) 153 {{.WFunc}}(arr.Data) 154 155 return int(w.Pos()-pos), w.Err() 156 } 157 158 func (arr *{{.Name}}) UnmarshalROOT(r *rbytes.RBuffer) error { 159 if r.Err() != nil { 160 return r.Err() 161 } 162 163 n := int(r.ReadI32()) 164 arr.Data = rbytes.Resize{{.DType}}(arr.Data, n) 165 {{.RFunc}}(arr.Data) 166 167 return r.Err() 168 } 169 170 func init() { 171 f := func() reflect.Value { 172 o := &{{.Name}}{} 173 return reflect.ValueOf(o) 174 } 175 rtypes.Factory.Add("T{{.Name}}", f) 176 } 177 178 var ( 179 _ root.Array = (*{{.Name}})(nil) 180 _ rbytes.Marshaler = (*{{.Name}})(nil) 181 _ rbytes.Unmarshaler = (*{{.Name}})(nil) 182 ) 183 ` 184 185 func genTClonesArrayData() { 186 macro := ` 187 void gen_tclonesarray(const char *fname, bool bypass) { 188 auto f = TFile::Open(fname, "RECREATE"); 189 auto c = new TClonesArray("TObjString", 3); 190 (*c)[0] = new TObjString("Elem-0"); 191 (*c)[1] = new TObjString("elem-1"); 192 (*c)[2] = new TObjString("Elem-20"); 193 194 c->BypassStreamer(bypass); 195 f->WriteObjectAny(c, "TClonesArray", "clones"); 196 f->Write(); 197 f->Close(); 198 } 199 ` 200 201 for _, v := range []struct { 202 name string 203 bypass bool 204 }{ 205 { 206 name: "testdata/tclonesarray-with-streamerbypass.root", 207 bypass: true, 208 }, 209 { 210 name: "testdata/tclonesarray-no-streamerbypass.root", 211 bypass: false, 212 }, 213 } { 214 out, err := rtests.RunCxxROOT("gen_tclonesarray", []byte(macro), v.name, v.bypass) 215 if err != nil { 216 log.Fatalf("could not run gen-tclonesarray:\n%s\nerror: %+v", out, err) 217 } 218 } 219 }