@@ -7,127 +7,8 @@ package rtree
7
7
import (
8
8
"fmt"
9
9
"io"
10
- "reflect"
11
- "regexp"
12
- "strings"
13
10
)
14
11
15
- // ReadVar describes a variable to be read out of a tree.
16
- type ReadVar struct {
17
- Name string // name of the branch to read
18
- Leaf string // name of the leaf to read
19
- Value interface {} // pointer to the value to fill
20
- count string // name of the leaf-count, if any
21
- }
22
-
23
- // NewReadVars returns the complete set of ReadVars to read all the data
24
- // contained in the provided Tree.
25
- func NewReadVars (t Tree ) []ReadVar {
26
- var vars []ReadVar
27
- for _ , b := range t .Branches () {
28
- for _ , leaf := range b .Leaves () {
29
- ptr := newValue (leaf )
30
- cnt := ""
31
- if leaf .LeafCount () != nil {
32
- cnt = leaf .LeafCount ().Name ()
33
- }
34
- vars = append (vars , ReadVar {Name : b .Name (), Leaf : leaf .Name (), Value : ptr , count : cnt })
35
- }
36
- }
37
-
38
- return vars
39
- }
40
-
41
- // ReadVarsFromStruct returns a list of ReadVars bound to the exported fields
42
- // of the provided pointer to a struct value.
43
- //
44
- // ReadVarsFromStruct panicks if the provided value is not a pointer to
45
- // a struct value.
46
- func ReadVarsFromStruct (ptr interface {}) []ReadVar {
47
- rv := reflect .ValueOf (ptr )
48
- if rv .Kind () != reflect .Ptr {
49
- panic (fmt .Errorf ("rtree: expect a pointer value, got %T" , ptr ))
50
- }
51
-
52
- rv = rv .Elem ()
53
- if rv .Kind () != reflect .Struct {
54
- panic (fmt .Errorf ("rtree: expect a pointer to struct value, got %T" , ptr ))
55
- }
56
-
57
- var (
58
- rt = rv .Type ()
59
- rvars = make ([]ReadVar , 0 , rt .NumField ())
60
- reDims = regexp .MustCompile (`\w*?\[(\w*)\]+?` )
61
- )
62
-
63
- split := func (s string ) (string , []string ) {
64
- n := s
65
- if i := strings .Index (s , "[" ); i > 0 {
66
- n = s [:i ]
67
- }
68
-
69
- out := reDims .FindAllStringSubmatch (s , - 1 )
70
- if len (out ) == 0 {
71
- return n , nil
72
- }
73
-
74
- dims := make ([]string , len (out ))
75
- for i := range out {
76
- dims [i ] = out [i ][1 ]
77
- }
78
- return n , dims
79
- }
80
-
81
- for i := 0 ; i < rt .NumField (); i ++ {
82
- var (
83
- ft = rt .Field (i )
84
- fv = rv .Field (i )
85
- )
86
- if ft .Name != strings .Title (ft .Name ) {
87
- // not exported. ignore.
88
- continue
89
- }
90
- rvar := ReadVar {
91
- Name : ft .Tag .Get ("groot" ),
92
- Value : fv .Addr ().Interface (),
93
- }
94
- if rvar .Name == "" {
95
- rvar .Name = ft .Name
96
- }
97
-
98
- if strings .Contains (rvar .Name , "[" ) {
99
- switch ft .Type .Kind () {
100
- case reflect .Slice :
101
- sli , dims := split (rvar .Name )
102
- if len (dims ) > 1 {
103
- panic (fmt .Errorf ("rtree: invalid number of slice-dimensions for field %q: %q" , ft .Name , rvar .Name ))
104
- }
105
- rvar .Name = sli
106
- rvar .count = dims [0 ]
107
-
108
- case reflect .Array :
109
- arr , dims := split (rvar .Name )
110
- if len (dims ) > 3 {
111
- panic (fmt .Errorf ("rtree: invalid number of array-dimension for field %q: %q" , ft .Name , rvar .Name ))
112
- }
113
- rvar .Name = arr
114
- default :
115
- panic (fmt .Errorf ("rtree: invalid field type for %q, or invalid struct-tag %q: %T" , ft .Name , rvar .Name , fv .Interface ()))
116
- }
117
- }
118
- switch ft .Type .Kind () {
119
- case reflect .Int , reflect .Uint , reflect .UnsafePointer , reflect .Uintptr , reflect .Chan , reflect .Interface :
120
- panic (fmt .Errorf ("rtree: invalid field type for %q: %T" , ft .Name , fv .Interface ()))
121
- case reflect .Map :
122
- panic (fmt .Errorf ("rtree: invalid field type for %q: %T (not yet supported)" , ft .Name , fv .Interface ()))
123
- }
124
-
125
- rvar .Leaf = rvar .Name
126
- rvars = append (rvars , rvar )
127
- }
128
- return rvars
129
- }
130
-
131
12
// Reader reads data from a Tree.
132
13
type Reader struct {
133
14
r reader
@@ -329,6 +210,7 @@ func newReader(t Tree, rvars []ReadVar, n int, beg, end int64) reader {
329
210
if err != nil {
330
211
panic (err )
331
212
}
213
+
332
214
switch t := t .(type ) {
333
215
case * ttree :
334
216
return newRTree (t , rvars , n , beg , end )
@@ -374,19 +256,17 @@ func newRTree(t *ttree, rvars []ReadVar, n int, beg, end int64) *rtree {
374
256
Name : leaf .Branch ().Name (),
375
257
Leaf : leaf .Name (),
376
258
Value : ptr ,
259
+ leaf : leaf ,
377
260
})
378
261
}
379
262
}
380
263
r .rvs = append (rcounts , r .rvs ... )
264
+ r .rvs = bindRVarsTo (t , r .rvs )
381
265
382
- r .lvs = make ([]rleaf , len (r .rvs ))
383
- for i , rvar := range r .rvs {
384
- br := t .Branch (rvar .Name )
385
- if br == nil {
386
- continue
387
- }
388
- leaf := br .Leaf (rvar .Leaf )
389
- r .lvs [i ] = rleafFrom (leaf , rvar , r )
266
+ r .lvs = make ([]rleaf , 0 , len (r .rvs ))
267
+ for i := range r .rvs {
268
+ rv := r .rvs [i ]
269
+ r .lvs = append (r .lvs , rleafFrom (rv .leaf , rv , r ))
390
270
}
391
271
392
272
// regroup leaves by holding branch
@@ -410,7 +290,6 @@ func newRTree(t *ttree, rvars []ReadVar, n int, beg, end int64) *rtree {
410
290
411
291
return r
412
292
}
413
-
414
293
func (r * rtree ) Close () error {
415
294
for i := range r .brs {
416
295
rb := & r .brs [i ]
@@ -426,50 +305,53 @@ func (r *rtree) reset() {
426
305
}
427
306
}
428
307
429
- func (r * rtree ) rcount (name string ) func () int {
308
+ func (r * rtree ) rcountFunc (name string ) func () int {
430
309
for _ , leaf := range r .lvs {
431
310
n := leaf .Leaf ().Name ()
432
311
if n != name {
433
312
continue
434
313
}
435
314
switch leaf := leaf .(type ) {
436
315
case * rleafValI8 :
437
- return func () int {
438
- return int (* leaf .v )
439
- }
316
+ return leaf .ivalue
440
317
case * rleafValI16 :
441
- return func () int {
442
- return int (* leaf .v )
443
- }
318
+ return leaf .ivalue
444
319
case * rleafValI32 :
445
- return func () int {
446
- return int (* leaf .v )
447
- }
320
+ return leaf .ivalue
448
321
case * rleafValI64 :
449
- return func () int {
450
- return int (* leaf .v )
451
- }
322
+ return leaf .ivalue
452
323
case * rleafValU8 :
453
- return func () int {
454
- return int (* leaf .v )
455
- }
324
+ return leaf .ivalue
456
325
case * rleafValU16 :
457
- return func () int {
458
- return int (* leaf .v )
459
- }
326
+ return leaf .ivalue
460
327
case * rleafValU32 :
461
- return func () int {
462
- return int (* leaf .v )
463
- }
328
+ return leaf .ivalue
464
329
case * rleafValU64 :
465
- return func () int {
466
- return int (* leaf .v )
467
- }
330
+ return leaf .ivalue
331
+ case * rleafElem :
332
+ leaf .bindCount ()
333
+ return leaf .ivalue
334
+
468
335
default :
469
336
panic (fmt .Errorf ("rleaf %T not implemented" , leaf ))
470
337
}
471
338
}
472
- panic ("impossible" )
339
+ panic (fmt .Errorf ("impossible: no leaf for %s" , name ))
340
+ }
341
+
342
+ func (r * rtree ) rcountLeaf (name string ) leafCount {
343
+ for _ , leaf := range r .lvs {
344
+ n := leaf .Leaf ().Name ()
345
+ if n != name {
346
+ continue
347
+ }
348
+ return & rleafCount {
349
+ Leaf : leaf .Leaf (),
350
+ n : r .rcountFunc (name ),
351
+ leaf : leaf ,
352
+ }
353
+ }
354
+ panic (fmt .Errorf ("impossible: no leaf for %s" , name ))
473
355
}
474
356
475
357
func (r * rtree ) run (off , beg , end int64 , f func (RCtx ) error ) error {
0 commit comments