summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2020-01-28 08:58:49 -0500
committerLuke Shumaker <lukeshu@lukeshu.com>2020-01-28 08:58:49 -0500
commit036f7ab20b7bdcddcdbac4071e359602b1a0728f (patch)
treef35f183c3f3243a2c07ca034139dfe117bed7f25
parent140ad92a3bbab485ef0f27c7be03d62d10ffd067 (diff)
wip xml
-rw-r--r--rrdformat/format.go29
-rw-r--r--rrdformat/marshal_xml.go84
-rw-r--r--rrdformat/rrdbinary/types.go10
-rw-r--r--rrdformat/unmarshal_binary.go11
4 files changed, 111 insertions, 23 deletions
diff --git a/rrdformat/format.go b/rrdformat/format.go
index 91e5669..a2d95af 100644
--- a/rrdformat/format.go
+++ b/rrdformat/format.go
@@ -39,9 +39,7 @@ import (
//
// - "0001" (the original in rrdtool 1.0.0, 1999-07-15)
-const XMLNS = "https://oss.oetiker.ch/rrdtool/rrdtool-dump.xml"
-
-type RRDValue = rrdbinary.Float
+type Value = rrdbinary.Float
type Header struct {
Cookie rrdbinary.String `rrdbinary:"size=4" xml:"-"`
@@ -60,10 +58,11 @@ type DSDef struct {
}
type RRADef struct {
- CFName rrdbinary.String `rrdbinary:"size=20"`
- RowCnt rrdbinary.Uint
- PDPCnt rrdbinary.Uint
- Paameters [10]rrdbinary.Unival
+ CFName rrdbinary.String `rrdbinary:"size=20"`
+ RowCnt rrdbinary.Uint
+ PDPCnt rrdbinary.Uint
+ Parameters [10]rrdbinary.Unival
+ Values []Value `rrdbinary:"-"`
}
type TimeWithUsec struct {
@@ -104,10 +103,10 @@ type RRDv0003 struct {
DSDefs []DSDef // .Header.DSCnt
RRADefs []RRADef // .Header.RRACnt
LastUpdated TimeWithUsec
- PDPPreps []PDPPrep // .Header.DSCnt
- CDPPreps []CDPPrep // .Header.DSCnt * .Header.RRACnt
- RRAPtrs []RRAPtr // .Header.RRACnt
- Values []RRDValue // Σ .RRADefs[i].RowCnt*.Header.DSCnt
+ PDPPreps []PDPPrep // .Header.DSCnt
+ CDPPreps []CDPPrep // .Header.DSCnt * .Header.RRACnt
+ RRAPtrs []RRAPtr // .Header.RRACnt
+ Values []Value // Σ .RRADefs[i].RowCnt*.Header.DSCnt
}
type RRDv0002 = RRDv0001
@@ -117,8 +116,8 @@ type RRDv0001 struct {
DSDefs []DSDef // .Header.DSCnt
RRADefs []RRADef // .Header.RRACnt
LastUpdated TimeWithoutUsec
- PDPPreps []PDPPrep // .Header.DSCnt
- CDPPreps []CDPPrep // .Header.DSCnt * .Header.RRACnt
- RRAPtrs []RRAPtr // .Header.RRACnt
- Values []RRDValue // Σ .RRADefs[i].RowCnt*.Header.DSCnt
+ PDPPreps []PDPPrep // .Header.DSCnt
+ CDPPreps []CDPPrep // .Header.DSCnt * .Header.RRACnt
+ RRAPtrs []RRAPtr // .Header.RRACnt
+ Values []Value // Σ .RRADefs[i].RowCnt*.Header.DSCnt
}
diff --git a/rrdformat/marshal_xml.go b/rrdformat/marshal_xml.go
index dfb0556..7263810 100644
--- a/rrdformat/marshal_xml.go
+++ b/rrdformat/marshal_xml.go
@@ -1,19 +1,93 @@
package rrdformat
import (
+ "strconv"
"encoding/xml"
)
-func (h *Header) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
- if err := e.EncodeElement(h.Version, xml.StartElement{Name: xml.Name{Local: "version", Space: XMLNS}}); err != nil {
+//const XMLNS = "https://oss.oetiker.ch/rrdtool/rrdtool-dump.xml"
+
+func (rrd RRD) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ return e.Encode(rrd.Data)
+}
+
+func xmlStart(name string) xml.StartElement {
+ return xml.StartElement{
+ Name: xml.Name{
+ Local: name,
+ },
+ }
+}
+
+func (rrd RRDv0005) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ if err := e.EncodeToken(xml.Comment(" Round Robin Database Dump ")); err != nil {
+ return err
+ }
+ if err := e.EncodeToken(xml.CharData("\n")); err != nil {
+ return err
+ }
+ if err := e.EncodeToken(start); err != nil {
+ return err
+ }
+
+ // 1. Header
+ if err := e.Encode(rrd.Header); err != nil {
+ return err
+ }
+ // 2
+ if err := e.Encode(rrd.LastUpdated); err != nil {
return err
}
- if err := e.EncodeElement(h.PDPStep, xml.StartElement{Name: xml.Name{Local: "step", Space: XMLNS}}); err != nil {
+ if err := e.EncodeToken(xml.CharData("\n")); err != nil {
+ return err
+ }
+ for _, ds := range rrd.DSDefs {
+ if err := e.Encode(ds); err != nil {
+ return err
+ }
+ }
+
+ if err := e.EncodeToken(start.End()); err != nil {
return err
}
return nil
}
-var _ xml.Marshaler = &Header{}
+func (t TimeWithUsec) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ return TimeWithoutUsec{Sec: t.Sec}.MarshalXML(e, start)
+}
-//var _ xml.Unmarshaler = &Header{}
+func (t TimeWithoutUsec) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ if err := e.EncodeToken(start); err != nil {
+ return err
+ }
+ if err := e.EncodeToken(xml.CharData(strconv.FormatInt(int64(t.Sec), 10))); err != nil {
+ return err
+ }
+ if err := e.EncodeToken(start.End()); err != nil {
+ return err
+ }
+ if err := e.EncodeToken(xml.CharData(" ")); err != nil {
+ return err
+ }
+ if err := e.EncodeToken(xml.Comment(t.Time().Format(" 2006-01-02 15:04:05 MST "))); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (h Header) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ if err := e.EncodeElement(h.Version, xmlStart("version")); err != nil {
+ return err
+ }
+ if err := e.EncodeElement(h.PDPStep, xmlStart("step")); err != nil {
+ return err
+ }
+ if err := e.EncodeToken(xml.CharData(" ")); err != nil {
+ return err
+ }
+ if err := e.EncodeToken(xml.Comment(" Seconds ")); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/rrdformat/rrdbinary/types.go b/rrdformat/rrdbinary/types.go
index 0bf4913..a6fa881 100644
--- a/rrdformat/rrdbinary/types.go
+++ b/rrdformat/rrdbinary/types.go
@@ -2,6 +2,7 @@ package rrdbinary
import (
"encoding/binary"
+ "encoding/json"
"math"
)
@@ -32,6 +33,15 @@ type EOF struct{} // 0 bytes
func (u Unival) AsUint64() uint64 { return uint64(u) }
func (u Unival) AsFloat64() float64 { return math.Float64frombits(uint64(u)) }
+// MarshalJSON is for my own debugging.
+func (f Float) MarshalJSON() ([]byte, error) {
+ raw := float64(f)
+ if math.IsNaN(raw) {
+ return json.Marshal("NaN")
+ }
+ return json.Marshal(raw)
+}
+
// Statically assert that each of the above types implements the
// 'unmarshaler' interface.
var _ unmarshaler = func() *String { return nil }()
diff --git a/rrdformat/unmarshal_binary.go b/rrdformat/unmarshal_binary.go
index 923ccb1..bd4c005 100644
--- a/rrdformat/unmarshal_binary.go
+++ b/rrdformat/unmarshal_binary.go
@@ -8,8 +8,8 @@ import (
)
type RRD struct {
- Architecture rrdbinary.Architecture
- Data RRDv0005
+ Architecture rrdbinary.Architecture `xml:"-"`
+ Data RRDv0005 `xml:",innerxml"`
}
func (rrd *RRD) UnmarshalBinary(data []byte) error {
@@ -42,7 +42,12 @@ func (rrd *RRD) UnmarshalBinary(data []byte) error {
for i := range parsed.RRADefs {
val_cnt += int(parsed.RRADefs[i].RowCnt * parsed.Header.DSCnt)
}
- parsed.Values = make([]RRDValue, val_cnt)
+ vals := make([]Value, val_cnt)
+ parsed.Values = vals
+ for i := range parsed.RRADefs {
+ parsed.RRADefs[i].Values = vals[:parsed.RRADefs[i].RowCnt*parsed.Header.DSCnt]
+ vals = vals[parsed.RRADefs[i].RowCnt*parsed.Header.DSCnt:]
+ }
// resume decoding
var lastUpdatedPtr interface{}
switch parsed.Header.Version {