Documentation ¶
Overview ¶
Package tlv provides functionality to map Go structures to TLV encoded data and vice versa.
The mapping is done based on TLV templates. A 'Template' object is bound explicitly to a Go struct type (not the object value of that type). For a Template to be constructed, struct type fields must be annotated with tags, which provide mapping instructions (see (Template).Parse() for available annotations).
A Template is an immutable object and thus may be constructed once and be used thought out the program's lifetime (see 'templates' package for template registry).
Index ¶
- Constants
- func IsConsistent(b []byte) bool
- func Marshal(v interface{}) ([]byte, error)
- func Unmarshal(data []byte, v interface{}) error
- type Constructor
- type Encoder
- func (e *Encoder) Bytes() []byte
- func (e *Encoder) PrependBinary(bin []byte) (uint64, error)
- func (e *Encoder) PrependHeader(tag uint16, isNonCritical, isForwardUnknown bool, valueLen uint64) (uint64, error)
- func (e *Encoder) PrependUint64(value uint64) (uint64, error)
- func (e *Encoder) PrependUint64E(value uint64) (uint64, error)
- func (e *Encoder) PrependUint8(value uint64) (uint64, error)
- func (e *Encoder) PrependUint8E(value uint64) (uint64, error)
- func (e *Encoder) PrependUtf8(str string) (uint64, error)
- type HeaderMask
- type Template
- type Tlv
- func (t *Tlv) Binary() ([]byte, error)
- func (t *Tlv) Extract(path ...uint16) (*Tlv, error)
- func (t *Tlv) Imprint() ([]byte, error)
- func (t *Tlv) Length() int
- func (t *Tlv) ParseNested(tmpl *Template) error
- func (t *Tlv) SetValue(value []byte) error
- func (t *Tlv) String() string
- func (t *Tlv) ToObject(v interface{}, templateInput *Template, ctx unsafe.Pointer) error
- func (t *Tlv) Uint64() (uint64, error)
- func (t *Tlv) Uint64E() (uint64, error)
- func (t *Tlv) Uint8() (uint64, error)
- func (t *Tlv) Uint8E() (uint64, error)
- func (t *Tlv) Utf8() (string, error)
- func (t *Tlv) Utf8E() (string, error)
- func (t *Tlv) Value() []byte
- type TlvObj
Constants ¶
const ( // HeaderFlag16 is mask for 16bit flag. HeaderFlag16 = HeaderMask(0x80) // HeaderFlagN is mask for Non-Critical flag. HeaderFlagN = HeaderMask(0x40) // HeaderFlagF is mask for Forward Unknown flag. HeaderFlagF = HeaderMask(0x20) // HeaderTypeMask is mask for type in the first header byte. HeaderTypeMask = HeaderMask(0x1f) )
const ( // MaxValueLength is the maximum size of the TLV value. MaxValueLength = 0xffff // MaxHeaderSize is the maximum size of the TLV header. MaxHeaderSize = 4 // MaxBufferSize is the maximum size of the buffer needed to store any TLV. MaxBufferSize = MaxHeaderSize + MaxValueLength // MaxTagValue is the maximum size of the TLV tag value. MaxTagValue = 0x1fff )
const ( IUnknown = templateIndex(-4) // Index unknown. IWhatever = templateIndex(-3) // Index can be anything. IFirst = templateIndex(-2) // Must be first element. ILast = templateIndex(-1) // Must be last element. IBase = templateIndex(0) // Index >= IBase is a concrete element position. Count0_1 = templateCount(-3) // Zero or one occurrences. Count0_N = templateCount(-2) // Zero to many occurrences. Count1_N = templateCount(-1) // One to many occurrences. CountBase = templateCount(0) // Count >= CountBase is concrete count value. GroupNone = templateGroup(-1) VTImprint = templateType(-1) // Value (of struct field) must be *hash.Imprint. VTInt = templateType(-2) // Value (of struct field) must be *uint64. VTNested = templateType(-3) // Value (of struct field) must be *<struct>. VTUtf8 = templateType(-4) // Value (of struct field) must be *string. VTbin = templateType(-5) // Value (of struct field) must be *[]byte. VTTlvObj = templateType(-6) // Value (of struct field) must be *<struct, implements TlvObj>. VTNestedTlvObj = templateType(-7) // Value (of struct field) must be *<struct, implements TlvObj>. VTBaseTlv = templateType(-8) // Value (of struct field) must be *tlv.Tlc. VTUnknown = templateType(-9) // Unknown value type. VTInt8 = templateType(-10) // Value (of struct field) must be *uint64. VTContext = templateType(-11) // Value (of struct field) must be *<something>. )
Variables ¶
This section is empty.
Functions ¶
func IsConsistent ¶
IsConsistent verifies whether the input stream contains a complete TLV structure.
func Marshal ¶
Marshal returns the binary TLV encoding of v.
Marshal traverses the value v recursively. If an encountered value implements the TlvObj interface and is not a nil pointer, Marshal calls its ToTlv method to produce TLV.
Marshal uses default type-dependent encodings as described in (Template).Parse.
Types ¶
type Constructor ¶
type Constructor func(*tlv) error
Constructor is constructor for TLV. See ConstructEmpty, ConstructFromObject, ConstructFromReader and ConstructFromSlice.
func ConstructEmpty ¶
func ConstructEmpty(tag uint16, nc bool, fu bool) Constructor
ConstructEmpty is an option for constructing an empty TLV with initialized header values. For setting a value see (Tlv).SetValue().
func ConstructFromObject ¶
func ConstructFromObject(v interface{}, templateInput *Template) Constructor
ConstructFromObject is an option for constructing TLV structure by traversing the value v recursively.
Note that the value v must point to an existing object that is bound to provided template, otherwise the output is undefined.
func ConstructFromReader ¶
func ConstructFromReader(r io.Reader) Constructor
ConstructFromReader is an option for constructing TLV object from TLV binary stream.
func ConstructFromSlice ¶
func ConstructFromSlice(b []byte) Constructor
ConstructFromSlice is an option for constructing TLV object from TLV binary slice.
type Encoder ¶
type Encoder struct {
// contains filtered or unexported fields
}
Encoder keeps the TLV serialization state.
Serialization of TLV structures is performed from the most inner structure up to the root TLV.
func NewEncoder ¶
NewEncoder creates memory buffer ready to store serialized TLV.
func (*Encoder) PrependBinary ¶
PrependBinary function serializes binary slice as big-endian beginning from position towards smaller indexes.
func (*Encoder) PrependHeader ¶
func (e *Encoder) PrependHeader(tag uint16, isNonCritical, isForwardUnknown bool, valueLen uint64) (uint64, error)
PrependHeader function serializes TLV header with given parameters as big-endian beginning from position towards smaller indexes.
func (*Encoder) PrependUint64 ¶
PrependUint64 function serializes uint64 as big-endian beginning from position towards smaller indexes.
func (*Encoder) PrependUint64E ¶
PrependUint64E function serializes uint64 as big-endian beginning from position towards smaller indexes. When value is 0, TLV is built without a value.
func (*Encoder) PrependUint8 ¶
PrependUint8 function serializes uint64 as big-endian beginning from position towards smaller indexes. Note that input is still uint64 but its size is limited with 1 byte.
func (*Encoder) PrependUint8E ¶
PrependUint8E function serializes uint64 as big-endian beginning from position towards smaller indexes. Note that input is still uint64 but its size is limited with 1 byte. When value is 0, TLV is built without a value.
type HeaderMask ¶
type HeaderMask byte
HeaderMask holds mask values for different bits in TLV header.
type Template ¶
type Template struct {
// contains filtered or unexported fields
}
Template is used to convert binary stream into TLV and Go struct. That process can also be reversed where a Go structure is converted back into TLV encoded binary stream. TLV Template is generated using reflection and as it is immutable object, TLV Template is only generated once and can be reused in multiple goroutines. Note that after generation, Template uses reflection only slightly, thus not slowing it down.
To create a new empty TLV Template, see function NewTemplate. In order to bind newly created TLV Template with a struct, see function Parse.
func NewTemplate ¶
NewTemplate is a function that creates an empty nested TLV Template with TLV tag(s).
func (*Template) IsMatchingTag ¶
IsMatchingTag checks if TLV tag is matching with the template.
func (*Template) Parse ¶
Parse is a function that derives a TLV Template for a struct from its reflection.Type. In order to parse TLV Template for a struct, an empty TLV Template with value type VTNested must be created. Secondly, the struct must contain struct field tags describing how each struct field is related to TLV and what kind of type the fields should contain. To improve error handling, the type is not determined by reflection automatically but the real type and user given type must match.
Possible struct field tags to bind struct field with TLV:
tlv:"<TLV type>, bin | int | int8 | imp | nstd | nstd+tlvobj | tlvobj | utf8, [C], [I], [G], [!G].., [&G].., [N], [F], [E]" where: <TLV type> - TLV type value in hex (e.g 1a). bin - Field is *[]byte or *[][]byte. int - Field is *uint64 or *[]uint64. int8 - Field is *uint64 or *[]uint64. imp - Field is *hash.Imprint or *[]hash.Imprint. nstd - Field is *<some struct> or *[]*<some struct>. Note that list contains POINTERS! nstd+tlvobj - Field is *<some struct> or *[]*<some struct>. Note that list contains POINTERS and <some struct> MUST implement TlvObject interface! tlvobj - Field is *<some struct> or *[]*<some struct>. Note that list contains POINTERS and <some struct> MUST implement TlvObject interface! utf8 - Field is utf8 *string or *[]string. C - Expected count. C0_1 (default), C0_N, C1_N or C<num> (e.g. C5). Option is Group dependant (see description of option 'G'). Meaning that if a group number is applied, the count number is relevant only within that Group. I - Expected position. IW (any position, default), IF (first), IL (last) or I<num> (e.g. I5). G - Field belongs to a group. GNone (no group, default), G<num> (e.g. G0). !G - Conflicting groups !G<num> (e.g. !G0 indicates that this field can not coexist with fields belonging to group G0). &G - Dependency groups &G<num> (e.g. &G0 indicates that if this field contains a value, the fields belonging to group G0 must also have a value). N - Non-Critical TLV. F - Forward unknown (valid with N). E - Permit usage of empty values (e.g integer 0 has no value part.) tlv:"basetlv" - Field must be *tlv.Tlv. During TLV to object this field is going to store the base TLV of the struct itself. tlv:"context,name" - Field must be pointer to something and name must verify its type for error handling (for *dummy name must be 'dummy').
Usage example:
type nestedStruct struct { msg *string `tlv:"10,utf8"` unrelatedField uint8 } type example struct { suffix *[]bin `tlv:"1,bin,IF"` id *uint64 `tlv:"2,int"` value *nestedStruct `tlv:"2,nstd"` prefix *[]bin `tlv:"4,bin,IL"` basetlv *tlv.Tlv `tlv:"basetlv"` } t := reflect.TypeOf(example) template,_ := NewTemplate(VTNested, 0x2) err := template.Parse(t)
type Tlv ¶
type Tlv struct { NonCritical bool // If set, this TLV is non-critical. ForwardUnknown bool // If set together with NonCritical, this TLV may be skipped by receiver. Is16 bool // If set, this TLV is 16bit. Tag uint16 // TLV type. Nested []*Tlv // List of nested elements. Raw []byte // Raw slice holds entire TLV structure. // contains filtered or unexported fields }
TLV holds Type-Length-Value encoded data. Entire object is held in single byte array that can be accessed via TLV structure.
func NewTlv ¶
func NewTlv(constructor Constructor) (*Tlv, error)
NewTlv is a constructor for a TLV object.
func (*Tlv) Imprint ¶
Imprint is getter for hash imprint value. If imprint format is invalid, error is returned.
func (*Tlv) Length ¶
Length returns the size of the TLV in bytes (header size + value length). The value length can be obtained via the slice (Tlv).value.
func (*Tlv) ParseNested ¶
ParseNested parses TLV value part with given Template. When parsing is complete, list of nested TLVs should be under input TLV.
func (*Tlv) SetValue ¶
SetValue sets the TLV value. Note that it will also affect the TLV header according the value length.
See (Tlv).NewTlv option ConstructEmpty for initializing a parent TLV object.
See Marshal for serializing object state into binary TLV value.
func (*Tlv) ToObject ¶
ToObject decodes structured TLV object (see (Tlv).ParseNested()) and stores the result into value v.
Note that the value v must point to an existing object that is bound to provided template, otherwise the output is undefined.
func (*Tlv) Uint64 ¶
Uint64 is getter for uint64. If TLV is empty or TLV value is larger than 8 bits, error is returned.
func (*Tlv) Uint64E ¶
Uint64E is getter for uint64. If TLV is empty, 0 is returned. If TLV value is larger than 8 bits, error is returned.
func (*Tlv) Uint8 ¶
Uint8 is getter for uint8. If TLV is empty or TLV value is larger than 1 bit, error is returned.
func (*Tlv) Uint8E ¶
Uint8E is getter for uint8. If TLV is empty, 0 is returned. If TLV value is larger than 1 bit, error is returned.
func (*Tlv) Utf8 ¶
Utf8 is getter for string. TLV value must end with 0 octet that is left out from returned string. If TLV is empty, error is returned.
type TlvObj ¶
type TlvObj interface { // FromTlv function configures existing object with the data retrieved from input TLV. FromTlv(*Tlv) error // ToTlv functions encodes existing object as TLV. Function is provided by buffer which must be filled from highest // index to the lowest as TLV serialization must start from the deepest TLV. Note that TLV is still encoded in // big-endian. // // Example: // // ToTlv gets input buffer that is a slice from a larger structure. Input extBuf is from position 0 to x. TLV is // serialized from position y to x. Entire structure is located from y to n. // // index : i=0 i=y i=x i=n // extBuf: [ UNUSED EMPTY BUFFER ][ type:len:value ][ PREVIOUS TLVs ] ToTlv(*Encoder) (*Tlv, error) }
TlvObj is interface that provides custom functionality to get object from TLV, or to encode object as TLV. This interface is used by functions (Tlv).ToObject and by TLV constructor ConstructFromObject.