From b3d7493f5e8b20378ec2e41a10459e4339d538e9 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 1 Feb 2020 18:08:43 -0500 Subject: wip --- rrdformat/format.go | 55 +++++++++++++++++++++++-------------------- rrdformat/format_test.go | 14 ----------- rrdformat/marshal_xml.go | 41 ++++++++++++-------------------- rrdformat/sniff.go | 2 +- rrdformat/unmarshal_binary.go | 22 +++++++---------- 5 files changed, 53 insertions(+), 81 deletions(-) delete mode 100644 rrdformat/format_test.go diff --git a/rrdformat/format.go b/rrdformat/format.go index d004e86..bb37761 100644 --- a/rrdformat/format.go +++ b/rrdformat/format.go @@ -38,6 +38,13 @@ import ( // * added CF_FAILURES // // - "0001" (the original in rrdtool 1.0.0, 1999-07-15) +const ( + RRD_VERSION1 = "0001" + RRD_VERSION2 = "0002" + RRD_VERSION3 = "0003" + RRD_VERSION4 = "0004" + RRD_VERSION5 = "0005" +) type Value = rrdbinary.Double @@ -51,6 +58,17 @@ type Header struct { Parameters [10]rrdbinary.Unival `xml:"-"` } +// Data Source Types +const ( + DST_COUNTER = "COUNTER" // version >= RRD_VERSION1 + DST_ABSOLUTE = "ABSOLUTE" // version >= RRD_VERSION1 + DST_GAUGE = "GAUGE" // version >= RRD_VERSION1 + DST_DERIVE = "DERIVE" // version >= RRD_VERSION1 + DST_CDEF = "CDEF" // version >= RRD_VERSION2 + DST_DCOUNTER = "DCOUNTER" // version >= RRD_VERSION5 + DST_DDERIV = "DDERIV" // version >= RRD_VERSION5 +) + type DSDef struct { DSName rrdbinary.String `rrdbinary:"size=20" xml:"name"` DSType rrdbinary.String `rrdbinary:"size=20" xml:"type"` @@ -68,7 +86,7 @@ type RRADef struct { type TimeWithUsec struct { Sec rrdbinary.Time - Usec rrdbinary.Long // signed, but always >= 0 + Usec rrdbinary.Long // signed, but always >= 0 (version >= RRD_VERSION3) } func (ts TimeWithUsec) Time() time.Time { @@ -96,29 +114,14 @@ type RRAPtr struct { CurRow rrdbinary.ULong } -type RRDv0005 = RRDv0004 -type RRDv0004 = RRDv0003 - -type RRDv0003 struct { - Header Header - 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 []Value // Σ .RRADefs[i].RowCnt*.Header.DSCnt -} - -type RRDv0002 = RRDv0001 - -type RRDv0001 struct { - Header Header - 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 []Value // Σ .RRADefs[i].RowCnt*.Header.DSCnt +type RRD struct { + Architecture rrdbinary.Architecture `rrdbinary:"-" xml:"-"` + Header Header + 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 []Value // Σ .RRADefs[i].RowCnt*.Header.DSCnt } diff --git a/rrdformat/format_test.go b/rrdformat/format_test.go deleted file mode 100644 index 7c5711e..0000000 --- a/rrdformat/format_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package rrdformat - -import ( - "encoding/xml" - "testing" -) - -func TestXML(t *testing.T) { - out, err := xml.Marshal(&Header{ - Version: "0003", - PDPStep: 300, - }) - t.Log(string(out), err) -} diff --git a/rrdformat/marshal_xml.go b/rrdformat/marshal_xml.go index 2d0269b..033073c 100644 --- a/rrdformat/marshal_xml.go +++ b/rrdformat/marshal_xml.go @@ -7,10 +7,6 @@ import ( //const XMLNS = "https://oss.oetiker.ch/rrdtool/rrdtool-dump.xml" -func (rrd RRD) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - return e.EncodeElement(rrd.Data, start) -} - func xmlStart(name string) xml.StartElement { return xml.StartElement{ Name: xml.Name{ @@ -19,7 +15,7 @@ func xmlStart(name string) xml.StartElement { } } -func (rrd RRDv0005) MarshalXML(e *xml.Encoder, start xml.StartElement) error { +func (rrd RRD) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if err := e.EncodeToken(xml.Comment(" Round Robin Database Dump ")); err != nil { return err } @@ -30,19 +26,28 @@ func (rrd RRDv0005) MarshalXML(e *xml.Encoder, start xml.StartElement) error { return err } - // 1. Header - if err := e.Encode(rrd.Header); err != nil { + // 1. Version + if err := e.EncodeElement(rrd.Header.Version, xmlStart("version")); err != nil { + return err + } + // 2. Step + if err := e.EncodeElement(rrd.Header.PDPStep, xmlStart("step")); err != nil { + return err + } + if err := e.EncodeToken(xml.CharData(" ")); err != nil { return err } - // 2. Last Updated + if err := e.EncodeToken(xml.Comment(" Seconds ")); err != nil { + return err + } + // 3. Step if err := e.EncodeElement(rrd.LastUpdated, xmlStart("lastupdate")); err != nil { return err } - + // blank line if err := e.EncodeToken(xml.CharData("\n")); err != nil { return err } - // 3. Data Sources for _, ds := range rrd.DSDefs { if err := e.EncodeElement(ds, xmlStart("ds")); err != nil { @@ -85,19 +90,3 @@ func (t TimeWithoutUsec) MarshalXML(e *xml.Encoder, start xml.StartElement) erro } 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/sniff.go b/rrdformat/sniff.go index de1e67b..d8b5eb3 100644 --- a/rrdformat/sniff.go +++ b/rrdformat/sniff.go @@ -26,7 +26,7 @@ func SniffArchitecture(data []byte) (rrdbinary.Architecture, error) { // 1. File format version string switch header.Version { - case "0001", "0002", "0003", "0004", "0005": + case RRD_VERSION1, RRD_VERSION2, RRD_VERSION3, RRD_VERSION4, RRD_VERSION5: // do nothing default: return rrdbinary.Architecture{}, rrdbinary.NewBinError(fmt.Sprintf("can't handle RRD file version %q", header.Version), data, 4, 5) diff --git a/rrdformat/unmarshal_binary.go b/rrdformat/unmarshal_binary.go index 67dc4ff..8681f48 100644 --- a/rrdformat/unmarshal_binary.go +++ b/rrdformat/unmarshal_binary.go @@ -7,19 +7,16 @@ import ( "git.lukeshu.com/go/librrd/rrdformat/rrdbinary" ) -type RRD struct { - Architecture rrdbinary.Architecture `xml:"-"` - Data RRDv0005 `xml:",innerxml"` -} - func (rrd *RRD) UnmarshalBinary(data []byte) error { - arch, err := SniffArchitecture(data) + var err error + var parsed RRD + + parsed.Architecture, err = SniffArchitecture(data) if err != nil { return err } - decoder := rrdbinary.NewDecoder(arch, data) - var parsed RRDv0005 + decoder := rrdbinary.NewDecoder(parsed.Architecture, data) if err := decoder.Decode(&parsed.Header, ""); err != nil { return fmt.Errorf("field %s: %w", "Header", err) @@ -57,9 +54,9 @@ func (rrd *RRD) UnmarshalBinary(data []byte) error { // resume decoding var lastUpdatedPtr interface{} switch parsed.Header.Version { - case "0001", "0002": + case RRD_VERSION1, RRD_VERSION2: lastUpdatedPtr = &parsed.LastUpdated.Sec - case "0003", "0004", "0005": + case RRD_VERSION3, RRD_VERSION4, RRD_VERSION5: lastUpdatedPtr = &parsed.LastUpdated default: // version number already validated by SniffArchitecture @@ -84,10 +81,7 @@ func (rrd *RRD) UnmarshalBinary(data []byte) error { return fmt.Errorf("field %s: %w", "EOF", err) } - *rrd = RRD{ - Architecture: arch, - Data: parsed, - } + *rrd = parsed return nil } -- cgit v1.1-4-g5e80