1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
package rrdformat
import (
"encoding"
"fmt"
"git.lukeshu.com/go/librrd/rrdformat/rrdbinary"
)
func (rrd *RRD) UnmarshalBinary(data []byte) error {
var err error
var parsed RRD
parsed.Architecture, err = SniffArchitecture(data)
if err != nil {
return err
}
decoder := rrdbinary.NewDecoder(parsed.Architecture, data)
if err := decoder.Decode(&parsed.Header, ""); err != nil {
return fmt.Errorf("field %s: %w", "Header", err)
}
// allocate memory based on .Header values
parsed.DSDefs = make([]DSDef, parsed.Header.DSCnt)
parsed.RRADefs = make([]RRADef, parsed.Header.RRACnt)
parsed.PDPPreps = make([]PDPPrep, parsed.Header.DSCnt)
parsed.CDPPreps = make([]CDPPrep, parsed.Header.DSCnt*parsed.Header.RRACnt)
parsed.RRAPtrs = make([]RRAPtr, parsed.Header.RRACnt)
// resume decoding
if err := decoder.Decode(&parsed.DSDefs, ""); err != nil {
return fmt.Errorf("field %s: %w", "DSDefs", err)
}
if err := decoder.Decode(&parsed.RRADefs, ""); err != nil {
return fmt.Errorf("field %s: %w", "RRADefs", err)
}
// allocate memory based on .RRADefs
val_cnt := 0
for i := range parsed.RRADefs {
val_cnt += int(parsed.RRADefs[i].RowCnt * parsed.Header.DSCnt)
}
vals := make([]Value, val_cnt)
parsed.Values = vals
// set up some of pointers
for rra_i := range parsed.RRADefs {
parsed.RRADefs[rra_i].CDPPrep = &parsed.CDPPreps[rra_i]
parsed.RRADefs[rra_i].Database = make([][]Value, parsed.RRADefs[rra_i].RowCnt)
for row_i := 0; row_i < int(parsed.RRADefs[rra_i].RowCnt); row_i++ {
parsed.RRADefs[rra_i].Database[row_i] = vals[:parsed.Header.DSCnt]
vals = vals[parsed.Header.DSCnt:]
}
}
// resume decoding
var lastUpdatedPtr interface{}
switch parsed.Header.Version {
case RRD_VERSION1, RRD_VERSION2:
lastUpdatedPtr = &parsed.LastUpdated.Sec
case RRD_VERSION3, RRD_VERSION4, RRD_VERSION5:
lastUpdatedPtr = &parsed.LastUpdated
default:
// version number already validated by SniffArchitecture
panic("should not happen")
}
if err := decoder.Decode(lastUpdatedPtr, ""); err != nil {
return fmt.Errorf("field %s: %w", "LastUpdated", err)
}
if err := decoder.Decode(&parsed.PDPPreps, ""); err != nil {
return fmt.Errorf("field %s: %w", "PDPPreps", err)
}
if err := decoder.Decode(&parsed.CDPPreps, ""); err != nil {
return fmt.Errorf("field %s: %w", "CDPPreps", err)
}
if err := decoder.Decode(&parsed.RRAPtrs, ""); err != nil {
return fmt.Errorf("field %s: %w", "RRAPtrs", err)
}
if err := decoder.Decode(&parsed.Values, ""); err != nil {
return fmt.Errorf("field %s: %w", "Values", err)
}
if err := decoder.Decode(&rrdbinary.EOF{}, ""); err != nil {
return fmt.Errorf("field %s: %w", "EOF", err)
}
*rrd = parsed
return nil
}
//var _ encoding.BinaryMarshaler = &RRD{}
var _ encoding.BinaryUnmarshaler = &RRD{}
|