mirror of
https://github.com/safing/portbase
synced 2025-09-04 03:29:59 +00:00
Add GenCode support to dsd
This commit is contained in:
parent
0de310503a
commit
3b68c8ea4c
5 changed files with 1037 additions and 43 deletions
|
@ -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,28 +55,32 @@ 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
|
||||||
|
// case BSON:
|
||||||
|
// err := bson.Unmarshal(data[read:], t)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// return t, nil
|
||||||
|
case GenCode:
|
||||||
|
genCodeStruct, ok := t.(GenCodeCompatible)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("dsd: gencode is not supported by the given data structure")
|
||||||
|
}
|
||||||
|
_, err := genCodeStruct.GenCodeUnmarshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("dsd: failed to unpack gencode data: %s", err)
|
||||||
}
|
}
|
||||||
return t, nil
|
return t, nil
|
||||||
// case BSON:
|
|
||||||
// err := bson.Unmarshal(data[read:], t)
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
// return t, nil
|
|
||||||
// case MSGP:
|
|
||||||
// err := t.UnmarshalMsg(data[read:])
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, 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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
835
formats/dsd/gencode_test.go
Normal 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
|
||||||
|
}
|
9
formats/dsd/interfaces.go
Normal file
9
formats/dsd/interfaces.go
Normal 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
23
formats/dsd/tests.gencode
Normal 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
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue