abstract class BinData
- BinData
- Reference
- Object
Overview
Declarative reader/writer for structured binary data.
Subclass BinData, declare the wire layout with the field / bit_field /
group / endian DSL, and the class learns how to (de)serialize itself from
any IO:
class Packet < BinData
endian big
field size : UInt16, value: -> { payload.size }
field payload : Bytes, length: -> { size }
end
packet = io.read_bytes(Packet) # decode
io.write_bytes(packet) # encode
See #field for the supported field types and their options.
Direct Known Subclasses
Defined in:
bindata.crbindata/exceptions.cr
Constant Summary
-
BIT_PARTS =
[{more => {UInt8, nil}, tag_number => {UInt8, nil}}, {tag_class => {UInt8, nil}, constructed => {UInt8, nil}, tag_number => {UInt8, nil}}, {long => {UInt8, nil}, length_indicator => {UInt8, nil}}] of Nil -
CUSTOM_TYPES =
[BER, ASN1::BER, ASN1::BER::ExtendedIdentifier, ASN1::BER::Identifier, ASN1::BER::Length] of BinData.class -
INDEX =
[2] -
RESERVED_NAMES =
["inherited", "included", "extended", "method_missing", "method_added", "finished", "new", "inspect", "read", "write", "to_io", "from_io", "to_slice", "from_slice", "to_s", "bit_fields", "parent", "endian", "field", "bits", "enum_bits", "bool", "bit_field", "group", "remaining_bytes", "skip", "before_serialize", "after_deserialize", "custom", "enum_field", "array", "variable_array", "string", "bytes", "uint8", "uint8be", "uint8le", "int8", "int8be", "int8le", "uint16", "uint16be", "uint16le", "int16", "int16be", "int16le", "uint32", "uint32be", "uint32le", "int32", "int32be", "int32le", "uint64", "uint64be", "uint64le", "int64", "int64be", "int64le", "uint128", "uint128be", "uint128le", "int128", "int128be", "int128le", "float32", "float32be", "float32le", "float64", "float64be", "float64le"] -
Names the per-type shortcut macro (generated in
inherited) must never take, otherwise defining a subclass whose underscored name matches one of these would clobber a Crystal hook, a DSL macro, or a public method globally.NOTE when adding a new DSL macro to this class, add its name here too, otherwise a subclass named after it will silently clobber it.
Class Method Summary
- .bit_fields
-
.from_io(io : IO, format : IO::ByteFormat = IO::ByteFormat::SystemEndian)
Reads an instance from io (
IO#read_bytesentry point). -
.from_slice(bytes : Slice, format : IO::ByteFormat = IO::ByteFormat::SystemEndian)
Decodes an instance from a byte slice.
Macro Summary
-
__add_enum_field(name, cls, onlyif, verify, value, encoding, enum_type)
this needs to be split out so we can resolve the enum base_type
- __build_methods__
-
after_deserialize(&block)
Registers a callback run on the instance just after it is read, e.g.
-
array(name, length, onlyif = nil, verify = nil, value = nil)
DEPRECATED Use
#fieldinstead -
before_serialize(&block)
Registers a callback run on the instance just before it is written, e.g.
- bit_field(onlyif = nil, verify = nil, endian = nil, &block)
-
bits(size, name, value = nil, default = nil)
Declares a size-bit field inside a
bit_fieldblock (1 to 128 bits). -
bool(name, default = false)
Declares a single-bit boolean field inside a
bit_fieldblock. -
bytes(name, length, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
custom(name, onlyif = nil, verify = nil, value = nil)
DEPRECATED Use
#fieldinstead -
endian(format)
Sets the default byte order for every field of the type.
-
enum_bits(size, name)
DEPRECATED Use
#bitsinstead -
enum_field(size, name, onlyif = nil, verify = nil, value = nil)
DEPRECATED Use
#fieldinstead -
field(type_declaration, onlyif = nil, verify = nil, value = nil, length = nil, read_next = nil, encoding = nil, endian = nil)
Declares a binary field from a type declaration (
name : Type [= default]). -
float32(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
float32be(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
float32le(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
float64(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
float64be(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
float64le(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
group(name, onlyif = nil, verify = nil, value = nil, &block)
Declares a nested, isolated group of fields as its own
BinDataclass. -
int128(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int128be(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int128le(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int16(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int16be(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int16le(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int32(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int32be(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int32le(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int64(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int64be(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int64le(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int8(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int8be(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
int8le(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
remaining_bytes(name, onlyif = nil, verify = nil, default = nil)
Reads every remaining byte of the
IO(until EOF) into aBytesfield. -
skip(length, onlyif = nil, verify = nil)
Reads and discards length bytes (advancing the
IO) without storing them, for sections you don't need to keep. -
string(name, onlyif = nil, verify = nil, length = nil, value = nil, encoding = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint128(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint128be(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint128le(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint16(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint16be(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint16le(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint32(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint32be(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint32le(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint64(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint64be(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint64le(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint8(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint8be(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
uint8le(name, onlyif = nil, verify = nil, value = nil, default = nil)
DEPRECATED Use
#fieldinstead -
variable_array(name, read_next, onlyif = nil, verify = nil, value = nil)
DEPRECATED Use
#fieldinstead
Instance Method Summary
- #__format__ : IO::ByteFormat
-
#read(io : IO) : IO
Reads the fields of this instance from io, in declaration order, and returns io.
-
#to_io(io : IO, format : IO::ByteFormat = IO::ByteFormat::SystemEndian)
Writes this instance to io (
IO#write_bytesentry point). - #to_s(io)
-
#to_slice
Encodes this instance to a freshly allocated byte slice.
-
#write(io : IO)
Writes the fields of this instance to io in declaration order.
Class Method Detail
Reads an instance from io (IO#read_bytes entry point). The type's
declared endian is used; format is accepted but not applied.
Decodes an instance from a byte slice.
The declared endian of the type is used; the format argument is accepted
for IO interoperability but does not override it.
Macro Detail
this needs to be split out so we can resolve the enum base_type
Registers a callback run on the instance just after it is read, e.g. to expose a friendlier representation of the raw fields.
DEPRECATED Use #field instead
Registers a callback run on the instance just before it is written, e.g. to derive raw fields from a friendlier representation.
Groups bits / bool fields that are not byte-aligned. The total number of
bits declared in the block must be divisible by 8. Use only when fields share
a byte; byte-aligned values should be plain fields.
Bit fields follow the class endian: little byte-swaps the bitfield's bytes
(the bitfield is read/written as a little-endian integer, fields taken from its
most significant bit), while big / network / system / no declaration are
big-endian. Pass endian: :little / :big to override a single bit field.
Declare endian before the bit_field for the class default to apply.
Accepts the same onlyif / verify callbacks as field.
Declares a size-bit field inside a bit_field block (1 to 128 bits).
The accessor is typed as the smallest unsigned integer that holds size
bits. A name : EnumType declaration exposes the value as that enum.
bit_field do
bits 5, reserved
bits 2, input : Inputs = Inputs::HDMI
end
DEPRECATED Use #field instead
DEPRECATED Use #field instead
Sets the default byte order for every field of the type.
Accepts little, big, network (an alias for big-endian) or system.
Individual fields may still override it with the field ..., endian: option.
class Header < BinData
endian big
end
DEPRECATED Use #field instead
Declares a binary field from a type declaration (name : Type [= default]).
The supported field types are:
- integers (
UInt8..UInt128,Int8..Int128) and floats (Float32/Float64) String— null-terminated, or fixed-size withlength:(and optionalencoding:)Bytes— requires alength:callbackEnumtypes — require a default valueArray/Set— requirelength:(fixed) orread_next:(variable)- any other
BinData/ IO-serializable type (custom field)
Options (all accept a Proc, evaluated against the instance):
- onlyif — read/write the field only when the callback returns true
- verify — raise
BinData::VerificationExceptionunless the callback returns true - value — compute the field's value just before writing (e.g. a length/checksum)
- length — element/byte count for sized
Bytes/String/Array/Set - read_next — keep reading array elements while the callback returns true
- encoding — string encoding for fixed-size
Stringfields - endian — override the type's byte order for this field (numeric fields)
field size : UInt16, value: -> { text.bytesize }
field text : String, length: -> { size }
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
Declares a nested, isolated group of fields as its own BinData class.
The group exposes a parent accessor for callbacks that need data from the
enclosing type, and accepts the same onlyif / verify / value options as
field. Useful for related or optional sub-structures.
group :header, onlyif: -> { start == 0xFF } do
field version : UInt8
end
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
Reads every remaining byte of the IO (until EOF) into a Bytes field. Must
be the last field. Works with any IO, including streaming ones (sockets,
pipes). Accepts onlyif / verify callbacks.
Reads and discards length bytes (advancing the IO) without storing them,
for sections you don't need to keep. There is no accessor. On write the region
is emitted as length zero bytes, so the structure round-trips to the same
size. Accepts onlyif / verify callbacks.
field section_size : UInt32
skip -> { section_size - 4 }
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
DEPRECATED Use #field instead
Instance Method Detail
Reads the fields of this instance from io, in declaration order, and
returns io. Raises BinData::ParseError (or BinData::VerificationException)
on malformed input.
Writes this instance to io (IO#write_bytes entry point). The type's
declared endian is used; format is accepted but not applied.
Writes the fields of this instance to io in declaration order. Raises
BinData::WriteError (or BinData::VerificationException) on failure.