summaryrefslogtreecommitdiff
path: root/rrdformat/rrdbinary/unmarshal.go
diff options
context:
space:
mode:
Diffstat (limited to 'rrdformat/rrdbinary/unmarshal.go')
-rw-r--r--rrdformat/rrdbinary/unmarshal.go99
1 files changed, 53 insertions, 46 deletions
diff --git a/rrdformat/rrdbinary/unmarshal.go b/rrdformat/rrdbinary/unmarshal.go
index 34fc537..e0f8988 100644
--- a/rrdformat/rrdbinary/unmarshal.go
+++ b/rrdformat/rrdbinary/unmarshal.go
@@ -44,10 +44,12 @@ func (d *unmarshaler) unmarshal(v reflect.Value, tag string) error {
return d.unmarshalFloat(v, tag)
case reflect.TypeOf(Uint(0)):
return d.unmarshalUint(v, tag)
+ case reflect.TypeOf(_Int(0)):
+ return d.unmarshalInt(v, tag)
case reflect.TypeOf(Unival(0)):
return d.unmarshalUnival(v, tag)
- case reflect.TypeOf(Timestamp{}):
- return d.unmarshalTimestamp(v, tag)
+ case reflect.TypeOf(Time(0)):
+ return d.unmarshalTime(v, tag)
default:
switch v.Type().Kind() {
case reflect.Struct:
@@ -210,6 +212,42 @@ func (d *unmarshaler) unmarshalUint(v reflect.Value, tag string) error {
return nil
}
+func (d *unmarshaler) unmarshalInt(v reflect.Value, tag string) error {
+ panicUnless(v.Type() == reflect.TypeOf(_Int(0)))
+ panicUnless(v.CanSet())
+
+ if d.arch.IntWidth != 4 && d.arch.IntWidth != 8 {
+ return archErrorf("rrdbinary does not support IntWidth=%d; only supports 4 or 8", d.arch.IntWidth)
+ }
+ if tag != "" {
+ return typeErrorf("invalid rrdbinary struct tag for int: %q", tag)
+ }
+
+ data := d.data[d.pos:]
+
+ padding := 0
+ if d.pos%d.arch.IntAlign != 0 {
+ padding = d.arch.IntAlign - (d.pos % d.arch.IntAlign)
+ }
+ if len(data) < padding {
+ return d.binErrorf(padding+d.arch.IntWidth, "unexpected end-of-file in %d-byte padding-before-int", padding)
+ }
+ data = data[padding:]
+
+ if len(data) < d.arch.IntWidth {
+ return d.binErrorf(d.arch.IntWidth, "unexpected end-of-file in %d-byte int", d.arch.IntWidth)
+ }
+
+ switch d.arch.IntWidth {
+ case 4:
+ v.SetInt(int64(int32(d.arch.ByteOrder.Uint32(data))))
+ case 8:
+ v.SetInt(int64(d.arch.ByteOrder.Uint64(data)))
+ }
+ d.pos += padding + d.arch.IntWidth
+ return nil
+}
+
func (d *unmarshaler) unmarshalUnival(v reflect.Value, tag string) error {
panicUnless(v.Type() == reflect.TypeOf(Unival(0)))
panicUnless(v.CanSet())
@@ -241,69 +279,38 @@ func (d *unmarshaler) unmarshalUnival(v reflect.Value, tag string) error {
return nil
}
-func (d *unmarshaler) unmarshalTimestamp(v reflect.Value, tag string) error {
- panicUnless(v.Type() == reflect.TypeOf(Timestamp{}))
+func (d *unmarshaler) unmarshalTime(v reflect.Value, tag string) error {
+ panicUnless(v.Type() == reflect.TypeOf(Time(0)))
panicUnless(v.CanSet())
+ if d.arch.TimeWidth != 4 && d.arch.TimeWidth != 8 {
+ return archErrorf("rrdbinary does not support TimeWidth=%d; only supports 4 or 8", d.arch.TimeWidth)
+ }
if tag != "" {
- return typeErrorf("invalid rrdbinary struct tag for timestamp: %q", tag)
+ return typeErrorf("invalid rrdbinary struct tag for time: %q", tag)
}
data := d.data[d.pos:]
- var sec, usec int64
- // seconds -- time_t
- if d.arch.TimeWidth != 4 && d.arch.TimeWidth != 8 {
- return archErrorf("rrdbinary does not support TimeWidth=%d; only supports 4 or 8", d.arch.TimeWidth)
- }
- // padding
padding := 0
if d.pos%d.arch.TimeAlign != 0 {
padding = d.arch.TimeAlign - (d.pos % d.arch.TimeAlign)
}
if len(data) < padding {
- return d.binErrorf(padding+d.arch.TimeWidth, "unexpected end-of-file in %d-byte padding-before-time_t", padding)
+ return d.binErrorf(padding+d.arch.TimeWidth, "unexpected end-of-file in %d-byte padding-before-time", padding)
}
data = data[padding:]
- // value
+
if len(data) < d.arch.TimeWidth {
- return d.binErrorf(d.arch.TimeWidth, "unexpected end-of-file in %d-byte time_t", d.arch.TimeWidth)
+ return d.binErrorf(d.arch.TimeWidth, "unexpected end-of-file in %d-byte time", d.arch.TimeWidth)
}
- switch d.arch.TimeWidth {
- case 4:
- sec = int64(d.arch.ByteOrder.Int32(data))
- case 8:
- sec = d.arch.ByteOrder.Int64(data)
- }
- data = data[d.arch.TimeWidth:]
- // nanoseconds -- long
- if d.arch.IntWidth != 4 && d.arch.IntWidth != 8 {
- return archErrorf("rrdbinary does not support IntWidth=%d; only supports 4 or 8", d.arch.IntWidth)
- }
- // padding
- padding = 0
- if d.pos%d.arch.IntAlign != 0 {
- padding = d.arch.IntAlign - (d.pos % d.arch.IntAlign)
- }
- if len(data) < padding {
- return d.binErrorf(padding+d.arch.IntWidth, "unexpected end-of-file in %d-byte padding-before-int", padding)
- }
- data = data[padding:]
- // value
- if len(data) < d.arch.IntWidth {
- return d.binErrorf(d.arch.IntWidth, "unexpected end-of-file in %d-byte int", d.arch.IntWidth)
- }
- switch d.arch.IntWidth {
+ switch d.arch.TimeWidth {
case 4:
- usec = int64(d.arch.ByteOrder.Int32(data))
+ v.SetInt(int64(int32(d.arch.ByteOrder.Uint32(data))))
case 8:
- usec = d.arch.ByteOrder.Int64(data)
+ v.SetInt(int64(d.arch.ByteOrder.Uint64(data)))
}
- data = data[d.arch.IntWidth:]
-
- // put it all together
- v.Set(reflect.ValueOf(time.Unix(sec, usec*1000)))
- d.pos = len(pos.data) - len(data)
+ d.pos += padding + d.arch.TimeWidth
return nil
}