Add GenCode support to dsd

This commit is contained in:
Daniel 2019-07-19 21:29:26 +02:00
parent 0de310503a
commit 3b68c8ea4c
5 changed files with 1037 additions and 43 deletions

View file

@ -1,5 +1,3 @@
// Copyright Safing ICS Technologies GmbH. Use of this source code is governed by the AGPL license that can be found in the LICENSE file.
package dsd package dsd
// dynamic structured data // dynamic structured data
@ -22,7 +20,7 @@ const (
BYTES = 88 // X BYTES = 88 // X
JSON = 74 // J JSON = 74 // J
BSON = 66 // B BSON = 66 // B
GenCode = 71 // G (reserved) GenCode = 71 // G
) )
// define errors // define errors
@ -30,6 +28,7 @@ var errNoMoreSpace = errors.New("dsd: no more space left after reading dsd type"
var errUnknownType = errors.New("dsd: tried to unpack unknown type") var errUnknownType = errors.New("dsd: tried to unpack unknown type")
var errNotImplemented = errors.New("dsd: this type is not yet implemented") var errNotImplemented = errors.New("dsd: this type is not yet implemented")
// Load loads an dsd structured data blob into the given interface.
func Load(data []byte, t interface{}) (interface{}, error) { func Load(data []byte, t interface{}) (interface{}, error) {
if len(data) < 2 { if len(data) < 2 {
return nil, errNoMoreSpace return nil, errNoMoreSpace
@ -46,6 +45,7 @@ func Load(data []byte, t interface{}) (interface{}, error) {
return LoadAsFormat(data[read:], format, t) return LoadAsFormat(data[read:], format, t)
} }
// LoadAsFormat loads a data blob into the interface using the specified format.
func LoadAsFormat(data []byte, format uint8, t interface{}) (interface{}, error) { func LoadAsFormat(data []byte, format uint8, t interface{}) (interface{}, error) {
switch format { switch format {
case STRING: case STRING:
@ -55,7 +55,7 @@ func LoadAsFormat(data []byte, format uint8, t interface{}) (interface{}, error)
case JSON: case JSON:
err := json.Unmarshal(data, t) err := json.Unmarshal(data, t)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("dsd: failed to unpack json data: %s", data)
} }
return t, nil return t, nil
// case BSON: // case BSON:
@ -64,19 +64,23 @@ func LoadAsFormat(data []byte, format uint8, t interface{}) (interface{}, error)
// return nil, err // return nil, err
// } // }
// return t, nil // return t, nil
// case MSGP: case GenCode:
// err := t.UnmarshalMsg(data[read:]) genCodeStruct, ok := t.(GenCodeCompatible)
// if err != nil { if !ok {
// return nil, err return nil, errors.New("dsd: gencode is not supported by the given data structure")
// } }
// return t, nil _, err := genCodeStruct.GenCodeUnmarshal(data)
if err != nil {
return nil, fmt.Errorf("dsd: failed to unpack gencode data: %s", err)
}
return t, nil
default: default:
return nil, errors.New(fmt.Sprintf("dsd: tried to load unknown type %d, data: %v", format, data)) return nil, fmt.Errorf("dsd: tried to load unknown type %d, data: %v", format, data)
} }
} }
// Dump stores the interface as a dsd formatted data structure.
func Dump(t interface{}, format uint8) ([]byte, error) { func Dump(t interface{}, format uint8) ([]byte, error) {
if format == AUTO { if format == AUTO {
switch t.(type) { switch t.(type) {
case string: case string:
@ -107,18 +111,19 @@ func Dump(t interface{}, format uint8) ([]byte, error) {
// if err != nil { // if err != nil {
// return nil, err // return nil, err
// } // }
// case MSGP: case GenCode:
// data, err := t.MarshalMsg(nil) genCodeStruct, ok := t.(GenCodeCompatible)
// if err != nil { if !ok {
// return nil, err return nil, errors.New("dsd: gencode is not supported by the given data structure")
// } }
data, err = genCodeStruct.GenCodeMarshal(nil)
if err != nil {
return nil, fmt.Errorf("dsd: failed to pack gencode struct: %s", err)
}
default: default:
return nil, errors.New(fmt.Sprintf("dsd: tried to dump unknown type %d", format)) return nil, fmt.Errorf("dsd: tried to dump unknown type %d", format)
} }
r := append(f, data...) r := append(f, data...)
// log.Tracef("packing %v to %s", t, string(r))
// return nil, errors.New(fmt.Sprintf("dsd: dumped bytes are: %v", r))
return r, nil return r, nil
} }

View file

@ -10,6 +10,7 @@ import (
//go:generate msgp //go:generate msgp
// SimpleTestStruct is used for testing.
type SimpleTestStruct struct { type SimpleTestStruct struct {
S string S string
B byte B byte
@ -21,11 +22,11 @@ type ComplexTestStruct struct {
I16 int16 I16 int16
I32 int32 I32 int32
I64 int64 I64 int64
Ui uint UI uint
Ui8 uint8 UI8 uint8
Ui16 uint16 UI16 uint16
Ui32 uint32 UI32 uint32
Ui64 uint64 UI64 uint64
S string S string
Sp *string Sp *string
Sa []string Sa []string
@ -38,6 +39,25 @@ type ComplexTestStruct struct {
Mp *map[string]string Mp *map[string]string
} }
type GenCodeTestStruct struct {
I8 int8
I16 int16
I32 int32
I64 int64
UI8 uint8
UI16 uint16
UI32 uint32
UI64 uint64
S string
Sp *string
Sa []string
Sap *[]string
B byte
Bp *byte
Ba []byte
Bap *[]byte
}
func TestConversion(t *testing.T) { func TestConversion(t *testing.T) {
// STRING // STRING
@ -113,7 +133,26 @@ func TestConversion(t *testing.T) {
}, },
} }
// TODO: test all formats genCodeSubject := GenCodeTestStruct{
-2,
-3,
-4,
-5,
2,
3,
4,
5,
"a",
&bString,
[]string{"c", "d", "e"},
&[]string{"f", "g", "h"},
0x01,
&bBytes,
[]byte{0x03, 0x04, 0x05},
&[]byte{0x05, 0x06, 0x07},
}
// test all formats (complex)
formats := []uint8{JSON} formats := []uint8{JSON}
for _, format := range formats { for _, format := range formats {
@ -163,20 +202,20 @@ func TestConversion(t *testing.T) {
if complexSubject.I64 != co.I64 { if complexSubject.I64 != co.I64 {
t.Errorf("Load (complex struct): struct.I64 is not equal (%v != %v)", complexSubject.I64, co.I64) t.Errorf("Load (complex struct): struct.I64 is not equal (%v != %v)", complexSubject.I64, co.I64)
} }
if complexSubject.Ui != co.Ui { if complexSubject.UI != co.UI {
t.Errorf("Load (complex struct): struct.Ui is not equal (%v != %v)", complexSubject.Ui, co.Ui) t.Errorf("Load (complex struct): struct.UI is not equal (%v != %v)", complexSubject.UI, co.UI)
} }
if complexSubject.Ui8 != co.Ui8 { if complexSubject.UI8 != co.UI8 {
t.Errorf("Load (complex struct): struct.Ui8 is not equal (%v != %v)", complexSubject.Ui8, co.Ui8) t.Errorf("Load (complex struct): struct.UI8 is not equal (%v != %v)", complexSubject.UI8, co.UI8)
} }
if complexSubject.Ui16 != co.Ui16 { if complexSubject.UI16 != co.UI16 {
t.Errorf("Load (complex struct): struct.Ui16 is not equal (%v != %v)", complexSubject.Ui16, co.Ui16) t.Errorf("Load (complex struct): struct.UI16 is not equal (%v != %v)", complexSubject.UI16, co.UI16)
} }
if complexSubject.Ui32 != co.Ui32 { if complexSubject.UI32 != co.UI32 {
t.Errorf("Load (complex struct): struct.Ui32 is not equal (%v != %v)", complexSubject.Ui32, co.Ui32) t.Errorf("Load (complex struct): struct.UI32 is not equal (%v != %v)", complexSubject.UI32, co.UI32)
} }
if complexSubject.Ui64 != co.Ui64 { if complexSubject.UI64 != co.UI64 {
t.Errorf("Load (complex struct): struct.Ui64 is not equal (%v != %v)", complexSubject.Ui64, co.Ui64) t.Errorf("Load (complex struct): struct.UI64 is not equal (%v != %v)", complexSubject.UI64, co.UI64)
} }
if complexSubject.S != co.S { if complexSubject.S != co.S {
t.Errorf("Load (complex struct): struct.S is not equal (%v != %v)", complexSubject.S, co.S) t.Errorf("Load (complex struct): struct.S is not equal (%v != %v)", complexSubject.S, co.S)
@ -211,4 +250,87 @@ func TestConversion(t *testing.T) {
} }
// test all formats
formats = []uint8{JSON, GenCode}
for _, format := range formats {
// simple
b, err := Dump(&simpleSubject, format)
if err != nil {
t.Fatalf("Dump error (simple struct): %s", err)
}
o, err := Load(b, &SimpleTestStruct{})
if err != nil {
t.Fatalf("Load error (simple struct): %s", err)
}
if !reflect.DeepEqual(&simpleSubject, o) {
t.Errorf("Load (simple struct): subject does not match loaded object")
t.Errorf("Encoded: %v", string(b))
t.Errorf("Compared: %v == %v", &simpleSubject, o)
}
// complex
b, err = Dump(&genCodeSubject, format)
if err != nil {
t.Fatalf("Dump error (complex struct): %s", err)
}
o, err = Load(b, &GenCodeTestStruct{})
if err != nil {
t.Fatalf("Load error (complex struct): %s", err)
}
co := o.(*GenCodeTestStruct)
if genCodeSubject.I8 != co.I8 {
t.Errorf("Load (complex struct): struct.I8 is not equal (%v != %v)", genCodeSubject.I8, co.I8)
}
if genCodeSubject.I16 != co.I16 {
t.Errorf("Load (complex struct): struct.I16 is not equal (%v != %v)", genCodeSubject.I16, co.I16)
}
if genCodeSubject.I32 != co.I32 {
t.Errorf("Load (complex struct): struct.I32 is not equal (%v != %v)", genCodeSubject.I32, co.I32)
}
if genCodeSubject.I64 != co.I64 {
t.Errorf("Load (complex struct): struct.I64 is not equal (%v != %v)", genCodeSubject.I64, co.I64)
}
if genCodeSubject.UI8 != co.UI8 {
t.Errorf("Load (complex struct): struct.UI8 is not equal (%v != %v)", genCodeSubject.UI8, co.UI8)
}
if genCodeSubject.UI16 != co.UI16 {
t.Errorf("Load (complex struct): struct.UI16 is not equal (%v != %v)", genCodeSubject.UI16, co.UI16)
}
if genCodeSubject.UI32 != co.UI32 {
t.Errorf("Load (complex struct): struct.UI32 is not equal (%v != %v)", genCodeSubject.UI32, co.UI32)
}
if genCodeSubject.UI64 != co.UI64 {
t.Errorf("Load (complex struct): struct.UI64 is not equal (%v != %v)", genCodeSubject.UI64, co.UI64)
}
if genCodeSubject.S != co.S {
t.Errorf("Load (complex struct): struct.S is not equal (%v != %v)", genCodeSubject.S, co.S)
}
if !reflect.DeepEqual(genCodeSubject.Sp, co.Sp) {
t.Errorf("Load (complex struct): struct.Sp is not equal (%v != %v)", genCodeSubject.Sp, co.Sp)
}
if !reflect.DeepEqual(genCodeSubject.Sa, co.Sa) {
t.Errorf("Load (complex struct): struct.Sa is not equal (%v != %v)", genCodeSubject.Sa, co.Sa)
}
if !reflect.DeepEqual(genCodeSubject.Sap, co.Sap) {
t.Errorf("Load (complex struct): struct.Sap is not equal (%v != %v)", genCodeSubject.Sap, co.Sap)
}
if genCodeSubject.B != co.B {
t.Errorf("Load (complex struct): struct.B is not equal (%v != %v)", genCodeSubject.B, co.B)
}
if !reflect.DeepEqual(genCodeSubject.Bp, co.Bp) {
t.Errorf("Load (complex struct): struct.Bp is not equal (%v != %v)", genCodeSubject.Bp, co.Bp)
}
if !reflect.DeepEqual(genCodeSubject.Ba, co.Ba) {
t.Errorf("Load (complex struct): struct.Ba is not equal (%v != %v)", genCodeSubject.Ba, co.Ba)
}
if !reflect.DeepEqual(genCodeSubject.Bap, co.Bap) {
t.Errorf("Load (complex struct): struct.Bap is not equal (%v != %v)", genCodeSubject.Bap, co.Bap)
}
}
} }

835
formats/dsd/gencode_test.go Normal file
View file

@ -0,0 +1,835 @@
package dsd
import (
"io"
"time"
"unsafe"
)
var (
_ = unsafe.Sizeof(0)
_ = io.ReadFull
_ = time.Now()
)
func (d *SimpleTestStruct) Size() (s uint64) {
{
l := uint64(len(d.S))
{
t := l
for t >= 0x80 {
t >>= 7
s++
}
s++
}
s += l
}
s++
return
}
func (d *SimpleTestStruct) GenCodeMarshal(buf []byte) ([]byte, error) {
size := d.Size()
{
if uint64(cap(buf)) >= size {
buf = buf[:size]
} else {
buf = make([]byte, size)
}
}
i := uint64(0)
{
l := uint64(len(d.S))
{
t := uint64(l)
for t >= 0x80 {
buf[i+0] = byte(t) | 0x80
t >>= 7
i++
}
buf[i+0] = byte(t)
i++
}
copy(buf[i+0:], d.S)
i += l
}
{
buf[i+0] = d.B
}
return buf[:i+1], nil
}
func (d *SimpleTestStruct) GenCodeUnmarshal(buf []byte) (uint64, error) {
i := uint64(0)
{
l := uint64(0)
{
bs := uint8(7)
t := uint64(buf[i+0] & 0x7F)
for buf[i+0]&0x80 == 0x80 {
i++
t |= uint64(buf[i+0]&0x7F) << bs
bs += 7
}
i++
l = t
}
d.S = string(buf[i+0 : i+0+l])
i += l
}
{
d.B = buf[i+0]
}
return i + 1, nil
}
func (d *GenCodeTestStruct) Size() (s uint64) {
{
l := uint64(len(d.S))
{
t := l
for t >= 0x80 {
t >>= 7
s++
}
s++
}
s += l
}
{
if d.Sp != nil {
{
l := uint64(len((*d.Sp)))
{
t := l
for t >= 0x80 {
t >>= 7
s++
}
s++
}
s += l
}
s += 0
}
}
{
l := uint64(len(d.Sa))
{
t := l
for t >= 0x80 {
t >>= 7
s++
}
s++
}
for k0 := range d.Sa {
{
l := uint64(len(d.Sa[k0]))
{
t := l
for t >= 0x80 {
t >>= 7
s++
}
s++
}
s += l
}
}
}
{
if d.Sap != nil {
{
l := uint64(len((*d.Sap)))
{
t := l
for t >= 0x80 {
t >>= 7
s++
}
s++
}
for k0 := range *d.Sap {
{
l := uint64(len((*d.Sap)[k0]))
{
t := l
for t >= 0x80 {
t >>= 7
s++
}
s++
}
s += l
}
}
}
s += 0
}
}
{
if d.Bp != nil {
s++
}
}
{
l := uint64(len(d.Ba))
{
t := l
for t >= 0x80 {
t >>= 7
s++
}
s++
}
s += l
}
{
if d.Bap != nil {
{
l := uint64(len((*d.Bap)))
{
t := l
for t >= 0x80 {
t >>= 7
s++
}
s++
}
s += l
}
s += 0
}
}
s += 35
return
}
func (d *GenCodeTestStruct) GenCodeMarshal(buf []byte) ([]byte, error) {
size := d.Size()
{
if uint64(cap(buf)) >= size {
buf = buf[:size]
} else {
buf = make([]byte, size)
}
}
i := uint64(0)
{
buf[0+0] = byte(d.I8 >> 0)
}
{
buf[0+1] = byte(d.I16 >> 0)
buf[1+1] = byte(d.I16 >> 8)
}
{
buf[0+3] = byte(d.I32 >> 0)
buf[1+3] = byte(d.I32 >> 8)
buf[2+3] = byte(d.I32 >> 16)
buf[3+3] = byte(d.I32 >> 24)
}
{
buf[0+7] = byte(d.I64 >> 0)
buf[1+7] = byte(d.I64 >> 8)
buf[2+7] = byte(d.I64 >> 16)
buf[3+7] = byte(d.I64 >> 24)
buf[4+7] = byte(d.I64 >> 32)
buf[5+7] = byte(d.I64 >> 40)
buf[6+7] = byte(d.I64 >> 48)
buf[7+7] = byte(d.I64 >> 56)
}
{
buf[0+15] = byte(d.UI8 >> 0)
}
{
buf[0+16] = byte(d.UI16 >> 0)
buf[1+16] = byte(d.UI16 >> 8)
}
{
buf[0+18] = byte(d.UI32 >> 0)
buf[1+18] = byte(d.UI32 >> 8)
buf[2+18] = byte(d.UI32 >> 16)
buf[3+18] = byte(d.UI32 >> 24)
}
{
buf[0+22] = byte(d.UI64 >> 0)
buf[1+22] = byte(d.UI64 >> 8)
buf[2+22] = byte(d.UI64 >> 16)
buf[3+22] = byte(d.UI64 >> 24)
buf[4+22] = byte(d.UI64 >> 32)
buf[5+22] = byte(d.UI64 >> 40)
buf[6+22] = byte(d.UI64 >> 48)
buf[7+22] = byte(d.UI64 >> 56)
}
{
l := uint64(len(d.S))
{
t := uint64(l)
for t >= 0x80 {
buf[i+30] = byte(t) | 0x80
t >>= 7
i++
}
buf[i+30] = byte(t)
i++
}
copy(buf[i+30:], d.S)
i += l
}
{
if d.Sp == nil {
buf[i+30] = 0
} else {
buf[i+30] = 1
{
l := uint64(len((*d.Sp)))
{
t := uint64(l)
for t >= 0x80 {
buf[i+31] = byte(t) | 0x80
t >>= 7
i++
}
buf[i+31] = byte(t)
i++
}
copy(buf[i+31:], (*d.Sp))
i += l
}
i += 0
}
}
{
l := uint64(len(d.Sa))
{
t := uint64(l)
for t >= 0x80 {
buf[i+31] = byte(t) | 0x80
t >>= 7
i++
}
buf[i+31] = byte(t)
i++
}
for k0 := range d.Sa {
{
l := uint64(len(d.Sa[k0]))
{
t := uint64(l)
for t >= 0x80 {
buf[i+31] = byte(t) | 0x80
t >>= 7
i++
}
buf[i+31] = byte(t)
i++
}
copy(buf[i+31:], d.Sa[k0])
i += l
}
}
}
{
if d.Sap == nil {
buf[i+31] = 0
} else {
buf[i+31] = 1
{
l := uint64(len((*d.Sap)))
{
t := uint64(l)
for t >= 0x80 {
buf[i+32] = byte(t) | 0x80
t >>= 7
i++
}
buf[i+32] = byte(t)
i++
}
for k0 := range *d.Sap {
{
l := uint64(len((*d.Sap)[k0]))
{
t := uint64(l)
for t >= 0x80 {
buf[i+32] = byte(t) | 0x80
t >>= 7
i++
}
buf[i+32] = byte(t)
i++
}
copy(buf[i+32:], (*d.Sap)[k0])
i += l
}
}
}
i += 0
}
}
{
buf[i+32] = d.B
}
{
if d.Bp == nil {
buf[i+33] = 0
} else {
buf[i+33] = 1
{
buf[i+34] = (*d.Bp)
}
i++
}
}
{
l := uint64(len(d.Ba))
{
t := uint64(l)
for t >= 0x80 {
buf[i+34] = byte(t) | 0x80
t >>= 7
i++
}
buf[i+34] = byte(t)
i++
}
copy(buf[i+34:], d.Ba)
i += l
}
{
if d.Bap == nil {
buf[i+34] = 0
} else {
buf[i+34] = 1
{
l := uint64(len((*d.Bap)))
{
t := uint64(l)
for t >= 0x80 {
buf[i+35] = byte(t) | 0x80
t >>= 7
i++
}
buf[i+35] = byte(t)
i++
}
copy(buf[i+35:], (*d.Bap))
i += l
}
i += 0
}
}
return buf[:i+35], nil
}
func (d *GenCodeTestStruct) GenCodeUnmarshal(buf []byte) (uint64, error) {
i := uint64(0)
{
d.I8 = 0 | (int8(buf[i+0+0]) << 0)
}
{
d.I16 = 0 | (int16(buf[i+0+1]) << 0) | (int16(buf[i+1+1]) << 8)
}
{
d.I32 = 0 | (int32(buf[i+0+3]) << 0) | (int32(buf[i+1+3]) << 8) | (int32(buf[i+2+3]) << 16) | (int32(buf[i+3+3]) << 24)
}
{
d.I64 = 0 | (int64(buf[i+0+7]) << 0) | (int64(buf[i+1+7]) << 8) | (int64(buf[i+2+7]) << 16) | (int64(buf[i+3+7]) << 24) | (int64(buf[i+4+7]) << 32) | (int64(buf[i+5+7]) << 40) | (int64(buf[i+6+7]) << 48) | (int64(buf[i+7+7]) << 56)
}
{
d.UI8 = 0 | (uint8(buf[i+0+15]) << 0)
}
{
d.UI16 = 0 | (uint16(buf[i+0+16]) << 0) | (uint16(buf[i+1+16]) << 8)
}
{
d.UI32 = 0 | (uint32(buf[i+0+18]) << 0) | (uint32(buf[i+1+18]) << 8) | (uint32(buf[i+2+18]) << 16) | (uint32(buf[i+3+18]) << 24)
}
{
d.UI64 = 0 | (uint64(buf[i+0+22]) << 0) | (uint64(buf[i+1+22]) << 8) | (uint64(buf[i+2+22]) << 16) | (uint64(buf[i+3+22]) << 24) | (uint64(buf[i+4+22]) << 32) | (uint64(buf[i+5+22]) << 40) | (uint64(buf[i+6+22]) << 48) | (uint64(buf[i+7+22]) << 56)
}
{
l := uint64(0)
{
bs := uint8(7)
t := uint64(buf[i+30] & 0x7F)
for buf[i+30]&0x80 == 0x80 {
i++
t |= uint64(buf[i+30]&0x7F) << bs
bs += 7
}
i++
l = t
}
d.S = string(buf[i+30 : i+30+l])
i += l
}
{
if buf[i+30] == 1 {
if d.Sp == nil {
d.Sp = new(string)
}
{
l := uint64(0)
{
bs := uint8(7)
t := uint64(buf[i+31] & 0x7F)
for buf[i+31]&0x80 == 0x80 {
i++
t |= uint64(buf[i+31]&0x7F) << bs
bs += 7
}
i++
l = t
}
(*d.Sp) = string(buf[i+31 : i+31+l])
i += l
}
i += 0
} else {
d.Sp = nil
}
}
{
l := uint64(0)
{
bs := uint8(7)
t := uint64(buf[i+31] & 0x7F)
for buf[i+31]&0x80 == 0x80 {
i++
t |= uint64(buf[i+31]&0x7F) << bs
bs += 7
}
i++
l = t
}
if uint64(cap(d.Sa)) >= l {
d.Sa = d.Sa[:l]
} else {
d.Sa = make([]string, l)
}
for k0 := range d.Sa {
{
l := uint64(0)
{
bs := uint8(7)
t := uint64(buf[i+31] & 0x7F)
for buf[i+31]&0x80 == 0x80 {
i++
t |= uint64(buf[i+31]&0x7F) << bs
bs += 7
}
i++
l = t
}
d.Sa[k0] = string(buf[i+31 : i+31+l])
i += l
}
}
}
{
if buf[i+31] == 1 {
if d.Sap == nil {
d.Sap = new([]string)
}
{
l := uint64(0)
{
bs := uint8(7)
t := uint64(buf[i+32] & 0x7F)
for buf[i+32]&0x80 == 0x80 {
i++
t |= uint64(buf[i+32]&0x7F) << bs
bs += 7
}
i++
l = t
}
if uint64(cap((*d.Sap))) >= l {
(*d.Sap) = (*d.Sap)[:l]
} else {
(*d.Sap) = make([]string, l)
}
for k0 := range *d.Sap {
{
l := uint64(0)
{
bs := uint8(7)
t := uint64(buf[i+32] & 0x7F)
for buf[i+32]&0x80 == 0x80 {
i++
t |= uint64(buf[i+32]&0x7F) << bs
bs += 7
}
i++
l = t
}
(*d.Sap)[k0] = string(buf[i+32 : i+32+l])
i += l
}
}
}
i += 0
} else {
d.Sap = nil
}
}
{
d.B = buf[i+32]
}
{
if buf[i+33] == 1 {
if d.Bp == nil {
d.Bp = new(byte)
}
{
(*d.Bp) = buf[i+34]
}
i++
} else {
d.Bp = nil
}
}
{
l := uint64(0)
{
bs := uint8(7)
t := uint64(buf[i+34] & 0x7F)
for buf[i+34]&0x80 == 0x80 {
i++
t |= uint64(buf[i+34]&0x7F) << bs
bs += 7
}
i++
l = t
}
if uint64(cap(d.Ba)) >= l {
d.Ba = d.Ba[:l]
} else {
d.Ba = make([]byte, l)
}
copy(d.Ba, buf[i+34:])
i += l
}
{
if buf[i+34] == 1 {
if d.Bap == nil {
d.Bap = new([]byte)
}
{
l := uint64(0)
{
bs := uint8(7)
t := uint64(buf[i+35] & 0x7F)
for buf[i+35]&0x80 == 0x80 {
i++
t |= uint64(buf[i+35]&0x7F) << bs
bs += 7
}
i++
l = t
}
if uint64(cap((*d.Bap))) >= l {
(*d.Bap) = (*d.Bap)[:l]
} else {
(*d.Bap) = make([]byte, l)
}
copy((*d.Bap), buf[i+35:])
i += l
}
i += 0
} else {
d.Bap = nil
}
}
return i + 35, nil
}

View file

@ -0,0 +1,9 @@
package dsd
// GenCodeCompatible is an interface to identify and use gencode compatible structs.
type GenCodeCompatible interface {
// GenCodeMarshal gencode marshalls the struct into the given byte array, or a new one if its too small.
GenCodeMarshal(buf []byte) ([]byte, error)
// GenCodeUnmarshal gencode unmarshalls the struct and returns the bytes read.
GenCodeUnmarshal(buf []byte) (uint64, error)
}

23
formats/dsd/tests.gencode Normal file
View file

@ -0,0 +1,23 @@
struct SimpleTestStruct {
S string
B byte
}
struct GenCodeTestStructure {
I8 int8
I16 int16
I32 int32
I64 int64
UI8 uint8
UI16 uint16
UI32 uint32
UI64 uint64
S string
Sp *string
Sa []string
Sap *[]string
B byte
Bp *byte
Ba []byte
Bap *[]byte
}