binary

package
v1.3.7 Latest Latest
Warning

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

Go to latest
Published: Mar 29, 2019 License: Apache-2.0 Imports: 12 Imported by: 0

README

Binary to Map Encoder

Presently this library only supports decoding from arbitary binary structures to a go map[string]interface{}.

This project is based on the kaitai project and supports a subset of the primities. Using simple yaml based spec, conversion from binary to other structures or json can be performed simply.

Notes and Caveats
  • Bitfields are not support at this time

Sample Data

The examples use the following C stucture, encoded to base64.

C Structure
#include <string.h>
#include <stdint.h>

typedef struct tagSensors {
    double ph;
    double ec;
} Sensors;

typedef struct tagReading {
    char probe_id[32];
    double temp;
    double humidity;
    Sensors sensors;
} Reading;

Reading N={ "000001", 12.0, 0.88, { 0.34, 0.45 }};
Base64 Value

MDAwMDAxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAKAAAAAAAAD/sKPXCj1wpP9XCj1wo9cM=

Sample Spec

The spec follows the kaitai format as closely as possible. There are two additional fields for sequence falues that are supported.

  1. omit - The value will be omitted from the final input.
  2. encodedValue - evaluation expression for the encoding the value (not yet supported).
meta:
  id: teralytic
  endian: be
seq:
  - id: probe_id
    type: str
    size: 32
  - id: temp
    type: f8
    doc: the temperature
  - id: humidity_raw
    type: f8
    doc: the raw humidity
    omit: true
  - id: sensors
    type: sensor_data
types:
  sensor_data:
    seq:
      - id: ph_raw
        type: f8
        omit: true
      - id: ec_raw
        type: f8
        omit: true
    instances:
      pH:
        value: seq(sensors, 'ph_raw') * 100
      ec:
        value: ec_decoder() / 2.3
instances:
  humidity:
    value: humidity_raw * 100

Initializing and Decoding the Spec

specData, err := ioutil.ReadFile("spec.yaml")
if err != nil {
    panic(err)
}

spec, err := binary.NewSpec(specData)
if err != nil {
    panic(err)
}
Initializing with Custom Functions
spec, err := binary.NewSpec(specData, map[string]binary.EvalFunc{
    "ec_decoder":
        func(ctx types.StringMap, args ...interface{}) (interface{}, error) {
            return ctx.Float64("sensors.ec_raw") * 1000, nil
    },
})
if err != nil {
    panic(err)
}

Decoding the Data and converting to JSON

Data is expected to be raw bytes.

rval, err := spec.Decode(data)
if err != nil {
    panic(err)
}

out, err := json.MarshalIndent(rval, "", "\t")
if err != nil {
    panic(err)
}

Output:

{
  "humidity": 88,
  "probe_id": "000001",
  "sensors": {
    "ec": 195.6521739130435,
    "pH": 34
  },
  "temp": 12
}

Decoding to a struct


import "gitlab.com/ModelRocket/sparks/util"

type reading struct {
    ProbeID  string `json:"probe_id"`
    Humidity int64
    Sensors  struct {
        EC float64
        PH float64
    }
    Temp float64
}

func main() {
    // ...

    r := &reading{}
    if err := util.MapStruct(r, rval); err != nil {
        panic(err)
    }
}

Documentation

Overview

Package binary provides helpers for encoding binary data from a spec file very loosely based on kaitai; see https://doc.kaitai.io.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ReadF32 added in v1.3.4

func ReadF32(rdr io.Reader, endian binary.ByteOrder) float32

ReadF32 reads a 32-bit float

func ReadF64 added in v1.3.4

func ReadF64(rdr io.Reader, endian binary.ByteOrder) float64

ReadF64 reads a 64-bit float

func ReadS8 added in v1.3.4

func ReadS8(rdr io.Reader, endian binary.ByteOrder) int8

ReadS8 reads an signed 8-bit integer

func ReadS16 added in v1.3.4

func ReadS16(rdr io.Reader, endian binary.ByteOrder) int16

ReadS16 reads an signed 16-bit integer

func ReadS32 added in v1.3.4

func ReadS32(rdr io.Reader, endian binary.ByteOrder) int32

ReadS32 reads an signed 32-bit integer

func ReadS64 added in v1.3.4

func ReadS64(rdr io.Reader, endian binary.ByteOrder) int64

ReadS64 reads an signed 64-bit integer

func ReadU8 added in v1.3.4

func ReadU8(rdr io.Reader, endian binary.ByteOrder) uint8

ReadU8 reads an unsigned 8-bit integer

func ReadU16 added in v1.3.4

func ReadU16(rdr io.Reader, endian binary.ByteOrder) uint16

ReadU16 reads an unsigned 16-bit integer

func ReadU32 added in v1.3.4

func ReadU32(rdr io.Reader, endian binary.ByteOrder) uint32

ReadU32 reads an unsigned 32-bit integer

func ReadU64 added in v1.3.4

func ReadU64(rdr io.Reader, endian binary.ByteOrder) uint64

ReadU64 reads an unsigned 64-bit integer

Types

type EvalFunc added in v1.3.7

type EvalFunc func(ctx types.StringMap, args ...interface{}) (interface{}, error)

EvalFunc is an evalutation function that can be used in specs

type Instance added in v1.3.4

type Instance struct {
	Sequence `yaml:",inline"`

	// Pos is the position of the data in the byte stream
	Pos *string `yaml:"pos,omitempty"`

	// Value is the computed value of the instance object
	Value *string `yaml:"value,omitempty"`
	// contains filtered or unexported fields
}

Instance is an instance definition

type Meta

type Meta struct {
	ID       string `yaml:"id"`
	Endian   string `yaml:"endian"`
	Encoding string `yaml:"encoding"`
}

Meta provides meta-information for the spec

type Sequence

type Sequence struct {
	// ID is the label for the field
	ID string `yaml:"id"`

	// Type defines the type, width, and byte order or a custom definde type
	Type string `yaml:"type"`

	// Size is the length of the field in bytes, or points to another sequence value
	Size *string `yaml:"size,omitempty"`

	// Repeat is used for array values
	Repeat *string `yaml:"repeat,omitempty"`

	// Omit when set will omit the sequence value from the final result
	Omit bool `yaml:"omit"`
	// contains filtered or unexported fields
}

Sequence is a field definition

type Spec

type Spec struct {
	Meta      Meta                 `yaml:"meta"`
	Sequence  []*Sequence          `yaml:"seq"`
	Instances map[string]*Instance `yaml:"instances"`
	Types     map[string]*Type     `yaml:"types,omitempty"`
	// contains filtered or unexported fields
}

Spec defines the specification

func NewSpec added in v1.3.7

func NewSpec(data []byte, evalFuncs ...map[string]EvalFunc) (*Spec, error)

NewSpec parses and initializes a new binary spec

func (*Spec) AddEvalFunc added in v1.3.7

func (s *Spec) AddEvalFunc(name string, handler EvalFunc)

AddEvalFunc add an evaluator function

func (*Spec) Decode added in v1.3.6

func (s *Spec) Decode(data []byte) (types.StringMap, error)

Decode decodes the binary data to a map using the spec

type Type added in v1.3.4

type Type struct {
	Sequence  []*Sequence          `yaml:"seq"`
	Instances map[string]*Instance `yaml:"instances"`
}

Type is a type definition

Jump to

Keyboard shortcuts

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