codec

package
v2.0.0-beta.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 23, 2020 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package codec provides various encoding/decoding functions for SenML Packs: http://github.com/farshidtz/senml

Index

Examples

Constants

View Source
const DefaultCSVHeader = "Time,Update Time,Name,Unit,Value,String Value,Boolean Value,Data Value,Sum"

DefaultCSVHeader is the default (currently fixed) CSV header

Variables

This section is empty.

Functions

func Decode

func Decode(mediaType string, b []byte, options ...Option) (senml.Pack, error)
Example
input := `[{"bn":"room1/temp","u":"Cel","t":1276020076.305,"v":23.5},{"u":"Cel","t":1276020091.305,"v":23.6}]`

// decode JSON
pack, err := Decode(senml.MediaTypeSenmlJSON, []byte(input))
if err != nil {
	panic(err) // handle the error
}

// validate the SenML Pack
err = pack.Validate()
if err != nil {
	panic(err) // handle the error
}

func Encode

func Encode(mediaType string, p senml.Pack, options ...Option) ([]byte, error)
Example
v := 23.1
var p senml.Pack = []senml.Record{
	{Value: &v, Unit: "Cel", Name: "urn:dev:ow:10e2073a01080063"},
}

dataOut, err := Encode(senml.MediaTypeSenmlJSON, p)
if err != nil {
	panic(err) // handle the error
}
fmt.Printf("%s", dataOut)
Output:

[{"n":"urn:dev:ow:10e2073a01080063","u":"Cel","v":23.1}]

func SetDefaultHeader

func SetDefaultHeader(o *codecOptions)

SetDefaultHeader enables header for CSV encoding/decoding

Example
var p senml.Pack = []senml.Record{
	{Time: 946684700, Name: "lamp/brightness", StringValue: "100", Unit: senml.UnitLumen},
	{Time: 946684800, Name: "lamp/brightness", StringValue: "500", Unit: senml.UnitLumen},
}

dataOut, err := EncodeCSV(p, SetDefaultHeader)
if err != nil {
	panic(err) // handle the error
}
fmt.Printf("%s", dataOut)
Output:

Time,Update Time,Name,Unit,Value,String Value,Boolean Value,Data Value,Sum
946684700,0,lamp/brightness,lm,,100,,,
946684800,0,lamp/brightness,lm,,500,,,

func SetPrettyPrint

func SetPrettyPrint(o *codecOptions)

SetPrettyPrint enables indentation for JSON and XML encoding

Example
var p senml.Pack = []senml.Record{
	{Time: 946684700, Name: "lamp/brightness", StringValue: "100", Unit: senml.UnitLumen},
	{Time: 946684800, Name: "lamp/brightness", StringValue: "500", Unit: senml.UnitLumen},
}

dataOut, err := EncodeJSON(p, SetPrettyPrint)
if err != nil {
	panic(err) // handle the error
}
fmt.Printf("%s", dataOut)
Output:

[
  {"n":"lamp/brightness","u":"lm","t":946684700,"vs":"100"},
  {"n":"lamp/brightness","u":"lm","t":946684800,"vs":"500"}
]

Types

type Decoder

type Decoder func(b []byte, options ...Option) (senml.Pack, error)

Decoder is the decoding function type

var DecodeCBOR Decoder = func(b []byte, options ...Option) (senml.Pack, error) {
	var p senml.Pack

	err := cbor.Unmarshal(b, &p)
	if err != nil {
		return nil, err
	}
	return p, nil
}

DecodeCBOR takes a SenML pack in CBOR bytes and decodes it into a Pack

var DecodeCSV Decoder = func(b []byte, options ...Option) (senml.Pack, error) {

	p, err := ReadCSV(bytes.NewReader(b), options...)
	if err != nil {
		return nil, err
	}

	return p, nil
}

DecodeCSV takes a SenML pack in CSV bytes and decodes it into a Pack

var DecodeJSON Decoder = func(b []byte, options ...Option) (senml.Pack, error) {
	var p senml.Pack

	err := json.Unmarshal(b, &p)
	if err != nil {
		return nil, err
	}
	return p, nil
}

DecodeJSON takes a SenML pack in JSON bytes and decodes it into a Pack

var DecodeXML Decoder = func(b []byte, options ...Option) (senml.Pack, error) {
	var temp xmlPack
	err := xml.Unmarshal(b, &temp)
	if err != nil {
		return nil, err
	}
	return temp.Pack, nil
}

DecodeXML takes a SenML pack in XML bytes and decodes it into a Pack

type Encoder

type Encoder func(p senml.Pack, options ...Option) ([]byte, error)

Encoder is the encoding function type

var EncodeCBOR Encoder = func(p senml.Pack, options ...Option) ([]byte, error) {

	return cbor.Marshal(p)
}

EncodeCBOR serializes the SenML pack into CBOR bytes

var EncodeCSV Encoder = func(p senml.Pack, options ...Option) ([]byte, error) {

	var buf bytes.Buffer
	err := WriteCSV(p, &buf, options...)
	if err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

EncodeCSV serializes the SenML pack into CSV bytes

var EncodeJSON Encoder = func(p senml.Pack, options ...Option) ([]byte, error) {
	o := &codecOptions{
		prettyPrint: false,
	}
	for _, opt := range options {
		opt(o)
	}

	if o.prettyPrint {
		var buf bytes.Buffer
		buf.WriteString("[\n  ")
		for i, r := range p {
			if i != 0 {
				buf.WriteString(",\n  ")
			}
			recData, err := json.Marshal(r)
			if err != nil {
				return nil, err
			}
			buf.Write(recData)
		}
		buf.WriteString("\n]\n")
		return buf.Bytes(), nil
	}

	return json.Marshal(p)
}

EncodeJSON serializes the SenML pack into JSON bytes

var EncodeXML Encoder = func(p senml.Pack, options ...Option) ([]byte, error) {
	o := &codecOptions{
		prettyPrint: false,
	}
	for _, opt := range options {
		opt(o)
	}

	xmlPack := xmlPack{
		Pack:  p,
		XMLNS: "urn:ietf:params:xml:ns:senml",
	}

	if o.prettyPrint {
		return xml.MarshalIndent(&xmlPack, "", "  ")
	}

	return xml.Marshal(&xmlPack)
}

EncodeXML serializes the SenML pack into XML bytes

type Option

type Option func(*codecOptions)

Option is the function type for setting codec options

type Reader

type Reader func(r io.Reader, options ...Option) (senml.Pack, error)

Reader is the reading function type

var ReadCSV Reader = func(r io.Reader, options ...Option) (senml.Pack, error) {
	o := &codecOptions{
		header: false,
	}
	for _, opt := range options {
		opt(o)
	}

	csvReader := csv.NewReader(r)

	if o.header {
		row, err := csvReader.Read()
		if err == io.EOF {
			return nil, fmt.Errorf("missing header or no input")
		}
		if err != nil {
			return nil, err
		}
		if joined := strings.Join(row, ","); joined != DefaultCSVHeader {
			return nil, fmt.Errorf("unexpected header: %s. Expected: %s", joined, DefaultCSVHeader)
		}
	}

	var p senml.Pack
	for {
		row, err := csvReader.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			return nil, err
		}

		var record senml.Record

		record.Time, err = strconv.ParseFloat(row[0], 10)
		if err != nil {
			return nil, err
		}

		record.UpdateTime, err = strconv.ParseFloat(row[1], 10)
		if err != nil {
			return nil, err
		}

		record.Name = row[2]

		record.Unit = row[3]

		if row[4] != "" {
			value, err := strconv.ParseFloat(row[4], 10)
			if err != nil {
				return nil, err
			}
			record.Value = &value
		}

		record.StringValue = row[5]

		if row[6] != "" {
			boolValue, err := strconv.ParseBool(row[6])
			if err != nil {
				return nil, err
			}
			record.BoolValue = &boolValue
		}

		record.DataValue = row[7]

		if row[8] != "" {
			sum, err := strconv.ParseFloat(row[8], 10)
			if err != nil {
				return nil, err
			}
			record.Sum = &sum
		}

		p = append(p, record)
	}

	return p, nil
}

type Writer

type Writer func(p senml.Pack, w io.Writer, options ...Option) error

Write is the writing function type

var WriteCSV Writer = func(p senml.Pack, w io.Writer, options ...Option) error {
	o := &codecOptions{
		header: false,
	}
	for _, opt := range options {
		opt(o)
	}

	csvWriter := csv.NewWriter(w)

	if o.header {
		err := csvWriter.Write(strings.Split(DefaultCSVHeader, ","))
		if err != nil {
			return err
		}
	}

	p.Normalize()

	for i := range p {
		row := make([]string, 9)
		row[0] = strconv.FormatFloat(p[i].Time, 'f', -1, 64)
		row[1] = strconv.FormatFloat(p[i].UpdateTime, 'f', -1, 64)
		row[2] = p[i].Name
		row[3] = p[i].Unit
		if p[i].Value != nil {
			row[4] = strconv.FormatFloat(*p[i].Value, 'f', -1, 64)
		}
		row[5] = p[i].StringValue
		if p[i].BoolValue != nil {
			row[6] = fmt.Sprintf("%t", *p[i].BoolValue)
		}
		row[7] = p[i].DataValue
		if p[i].Sum != nil {
			row[8] = strconv.FormatFloat(*p[i].Sum, 'f', -1, 64)
		}

		err := csvWriter.Write(row)
		if err != nil {
			return err
		}
		csvWriter.Flush()
	}
	if err := csvWriter.Error(); err != nil {
		return err
	}
	return nil
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL