NetMD.Query (NetMD v0.1.0)

Copy Markdown View Source

The NetMD query DSL: build command payloads and parse replies from printf/scanf-like format strings, as used by netmd-js and libnetmd.

Format strings mix literal hex bytes with % fields:

FieldMeaning
%b1-byte integer
%w2-byte integer
%d4-byte integer
%q8-byte integer
%xbinary preceded by 2 bytes of length
%snull-terminated binary preceded by 2 bytes of length
%zbinary preceded by 1 byte of length
%*raw binary (rest of input when scanning)
%#rest of input as binary (scan only)
%?ignore one byte (scan only)
%BBCD-encoded 1-byte number
%WBCD-encoded 2-byte number

Integers are big-endian by default; %< overrides to little-endian for the following field (%<d), %> explicitly selects big-endian.

Examples

iex> NetMD.Query.format("1808 %b 00", [2])
<<0x18, 0x08, 0x02, 0x00>>

iex> NetMD.Query.scan(<<0x18, 0x08, 0x02, 0x00>>, "1808 %b 00")
{:ok, [2]}

Summary

Types

A value produced or consumed by a % field.

Functions

Decode a binary-coded decimal binary to an integer.

Build a binary query from format and args.

Encode a non-negative integer as binary-coded decimal in length bytes.

Parse data according to format, returning the field values in order.

Same as scan/2 but raises NetMD.Query.ScanError on mismatch.

Types

value()

@type value() :: integer() | binary()

A value produced or consumed by a % field.

Functions

bcd_to_int(bcd)

@spec bcd_to_int(binary()) :: non_neg_integer()

Decode a binary-coded decimal binary to an integer.

iex> NetMD.Query.bcd_to_int(<<0x99, 0x99>>)
9999

format(format, args \\ [])

@spec format(String.t(), [value()]) :: binary()

Build a binary query from format and args.

Raises ArgumentError on malformed formats or mismatched arguments.

int_to_bcd(value, length \\ 1)

@spec int_to_bcd(non_neg_integer(), pos_integer()) :: binary()

Encode a non-negative integer as binary-coded decimal in length bytes.

iex> NetMD.Query.int_to_bcd(24, 1)
<<0x24>>

iex> NetMD.Query.int_to_bcd(9999, 2)
<<0x99, 0x99>>

scan(data, format)

@spec scan(binary(), String.t()) :: {:ok, [value()]} | {:error, term()}

Parse data according to format, returning the field values in order.

Literal bytes in the format must match the input exactly and the input must be fully consumed.

scan!(data, format)

@spec scan!(binary(), String.t()) :: [value()]

Same as scan/2 but raises NetMD.Query.ScanError on mismatch.