diff options
Diffstat (limited to 'rrdformat/rrdbinary/unmarshal.go')
-rw-r--r-- | rrdformat/rrdbinary/unmarshal.go | 99 |
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 } |