From 02003547bc96b3758355f0af0275170da1dba942 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 26 Jan 2020 21:46:56 -0500 Subject: wip --- rrdformat/rrdbinary/types.go | 11 +++-- rrdformat/rrdbinary/unmarshal.go | 99 +++++++++++++++++++++------------------- 2 files changed, 59 insertions(+), 51 deletions(-) (limited to 'rrdformat/rrdbinary') diff --git a/rrdformat/rrdbinary/types.go b/rrdformat/rrdbinary/types.go index 892bb25..36e89fa 100644 --- a/rrdformat/rrdbinary/types.go +++ b/rrdformat/rrdbinary/types.go @@ -21,11 +21,12 @@ type Architecture struct { TimeAlign int } -type String string // \0-terminatd -type Float float64 // 8 bytes -type Uint uint64 // 4 or 8 bytes -type Unival uint64 // 8 bytes -type Timestamp time.time // 8, 12, or 16 bytes +type String string // \0-terminated +type Float float64 // 8 bytes +type Uint uint64 // 4 or 8 bytes +type _Int int64 // 4 or 8 bytes +type Unival uint64 // 8 bytes +type Time int64 // 4 or 8 bytes, only has second-precision func (u Unival) AsUint64() uint64 { return uint64(u) } func (u Unival) AsFloat64() float64 { return math.Float64frombits(uint64(u)) } 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 } -- cgit v1.2.3-54-g00ecf