package rrdbinary import ( "encoding/binary" "fmt" "math" "strconv" ) type Architecture struct { ByteOrder binary.ByteOrder // C `double` DoubleWidth int // always 8 -- we assume IEEE 754 doubles DoubleAlign int // C `short` ShortWidth int ShortAlign int // C `long` or `unsigned long` LongWidth int LongAlign int // C `union { unsigned long; double; }` UnivalWidth int // max(DoubleWidth, LongWidth) UnivalAlign int // max(DoubleAlign, LongAlign) // C `time_t` TimeWidth int TimeAlign int } type String string // \0-terminated type Double float64 // 8 bytes type ULong uint64 // 4 or 8 bytes type Long int64 // 4 or 8 bytes type Time int64 // 4 or 8 bytes, only has second-precision type EOF struct{} // 0 bytes type Unival struct { arch Architecture data []byte // 8 bytes } func (u Unival) AsULong() ULong { return ULong(u.arch.ByteOrder.Uint64(u.data)) } func (u Unival) AsDouble() Double { return Double(math.Float64frombits(u.arch.ByteOrder.Uint64(u.data))) } func (u Unival) String() string { return fmt.Sprintf("enum{ .ulong=%d; .double=%s; .cdefds=%v }", u.AsULong(), u.AsDouble(), u.AsRPNTokens()) } func (u Unival) MarshalText() ([]byte, error) { return []byte(u.String()), nil } func (f Double) MarshalJSON() ([]byte, error) { if math.IsNaN(float64(f)) { return []byte(`"NaN"`), nil } return f.MarshalText() } func (f Double) MarshalText() ([]byte, error) { return []byte(f.String()), nil } func (f Double) String() string { return strconv.FormatFloat(float64(f), 'e', 10, 64) } // Statically assert that each of the above types implements the // 'unmarshaler' interface. var _ unmarshaler = func() *String { return nil }() var _ unmarshaler = func() *Double { return nil }() var _ unmarshaler = func() *ULong { return nil }() var _ unmarshaler = func() *Long { return nil }() var _ unmarshaler = func() *Unival { return nil }() var _ unmarshaler = func() *Time { return nil }() var _ unmarshaler = func() *EOF { return nil }()