On Sun, Oct 29, 2017 at 11:40:36PM -0700, hui zhang wrote:

> type variastrt struct {
> len int32
> data []int32  //  data length = len   [len]int32
> }
> 
> Is there a way or lib to read a binary into a this structure in one line 
> code?
> 
> how about more complicate struct ?
> type complicatestrt struct {
>       len int32
>       strData []variastrt
> }

Such encoding is colloquially called "TLV" -- "Type (or Tag), Length,
Value" [1]
In your particular case it's reduced -- there's no type field -- but the
general approach still holds.

A simple search [2] yields plenty of code to read, for instance, [3].


There are problem with parsing your data into arbitrary structs: while
the fields must be read in order -- first the length and then the
payload, -- there's no logical connection between the two fields, that
is, nothing in the definition of "len" tells that it's the length of the
data to put into the following field.

So I'm afraid you will need to implement this yourself.


I see two ways to approach it:

- Take any working TLV implementation, grab the code from it, reduce it
  to just "LV" and then operate on that generic type which is able to
  deserialize []byte to a type implementing an LV.

- Write some complicated code which uses reflection -- just like
  the stock encoding/binary does -- to understand how to interpret the
  fields of any custom struct type based on that type's tags (or just
  "shape" -- that is, the types and relative order of its fields).

For the latter, take into account that while there's no mention of the
format of the field tag in the language spec, the convention for their
format is documented at [4]:

| By convention, tag strings are a concatenation of optionally
| space-separated key:"value" pairs. Each key is a non-empty string
| consisting of non-control characters other than space (U+0020 ' '),
| quote (U+0022 '"'), and colon (U+003A ':'). Each value is quoted using
| U+0022 '"' characters and Go string literal syntax.

Hence you could come up with something like:

  type variastrt struct {
      len  int32   `var:"value:data endian:big"`
          data []int32 `var:"endian:little"`
  }

And then you'd reflect over the type the user supplied to your
unmarshaling code, and in that reflection code you'd parse the field's
tag, get the value associated with the "var" key and parse that, in
turn, to know the name of the field to unmarshal the value into, and the
endianness of the elements of that value (if applicable).

1. https://en.wikipedia.org/wiki/Type-length-value
2. https://www.google.com/search?q=golang+TLV+read
3. https://github.com/Akagi201/tlv/blob/master/tlv.go#L90
4. https://golang.org/pkg/reflect/#StructTag

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to