2019-10-04 12:28:45 +02:00
|
|
|
package ssob
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
2021-08-21 22:29:18 +02:00
|
|
|
"fmt"
|
2020-05-24 19:05:04 +02:00
|
|
|
"math"
|
2019-10-04 12:28:45 +02:00
|
|
|
"reflect"
|
|
|
|
)
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalBool(e []byte) (ie []byte, ret bool, err error) {
|
|
|
|
if len(e) < 1 {
|
|
|
|
return e, ret, ErrValueInvalid
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
if e[0] == 0 {
|
|
|
|
ret = true
|
|
|
|
} else {
|
|
|
|
ret = false
|
2019-10-05 22:12:53 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
return e[1:], ret, err
|
2019-10-05 22:12:53 +02:00
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalUint8(e []byte) (ie []byte, ret uint8, err error) {
|
|
|
|
if len(e) < 1 {
|
|
|
|
return e, ret, ErrValueInvalid
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
return e[1:], uint8(byte(e[0])), err
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalUint16(e []byte) (ie []byte, ret uint16, err error) {
|
|
|
|
if len(e) < 2 {
|
|
|
|
return e, ret, ErrValueInvalid
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
return e[2:], binary.BigEndian.Uint16(e), err
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalUint32(e []byte) (ie []byte, ret uint32, err error) {
|
|
|
|
if len(e) < 4 {
|
|
|
|
return e, ret, ErrValueInvalid
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
return e[4:], binary.BigEndian.Uint32(e), err
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalUint64(e []byte) (ie []byte, ret uint64, err error) {
|
|
|
|
if len(e) < 8 {
|
|
|
|
return e, ret, ErrValueInvalid
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
return e[8:], binary.BigEndian.Uint64(e), err
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalInt8(e []byte) (ie []byte, ret int8, err error) {
|
|
|
|
if len(e) < 1 {
|
|
|
|
return e, ret, ErrValueInvalid
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
return e[1:], int8(byte(e[0])), err
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalInt16(e []byte) (ie []byte, ret int16, err error) {
|
|
|
|
if len(e) < 2 {
|
|
|
|
return e, ret, ErrValueInvalid
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
return e[2:], int16(binary.BigEndian.Uint16(e)), err
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalInt32(e []byte) (ie []byte, ret int32, err error) {
|
|
|
|
if len(e) < 4 {
|
|
|
|
return e, ret, ErrValueInvalid
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
return e[4:], int32(binary.BigEndian.Uint32(e)), err
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalInt64(e []byte) (ie []byte, ret int64, err error) {
|
|
|
|
if len(e) < 4 {
|
|
|
|
return e, ret, ErrValueInvalid
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
return e[8:], int64(binary.BigEndian.Uint64(e)), err
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalFloat32(e []byte) (ie []byte, ret float32, err error) {
|
|
|
|
if len(e) < 4 {
|
|
|
|
return e, ret, ErrValueInvalid
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
return e[4:], float32(math.Float32frombits(binary.BigEndian.Uint32(e))), err
|
2019-10-04 12:28:45 +02:00
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalFloat64(e []byte) (ie []byte, ret float64, err error) {
|
|
|
|
if len(e) < 8 {
|
|
|
|
return e, ret, ErrValueInvalid
|
2019-10-05 01:42:09 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
return e[8:], float64(math.Float64frombits(binary.BigEndian.Uint64(e))), err
|
2019-10-05 01:42:09 +02:00
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalString(e []byte) (ie []byte, ret string, err error) {
|
|
|
|
ie = e
|
2021-09-02 00:08:59 +02:00
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
if len(ie) < 4 {
|
|
|
|
return ie, ret, ErrValueInvalid
|
2021-09-02 00:08:59 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
slen := binary.BigEndian.Uint32(e)
|
|
|
|
ie = ie[4:]
|
2021-09-02 00:08:59 +02:00
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
if len(ie) < int(slen) {
|
|
|
|
return ie, ret, ErrValueInvalid
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
ret = string(ie[:slen])
|
|
|
|
ie = ie[slen:]
|
|
|
|
return ie, ret, err
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalNil(e []byte) (ie []byte, ret uint16, err error) {
|
2021-09-06 23:33:50 +02:00
|
|
|
return unmarshalUint16(e)
|
|
|
|
}
|
|
|
|
|
|
|
|
func unmarshalPtrIfNil(e []byte, ntype *NType) (ie []byte, ret interface{}, isNil bool, err error) {
|
|
|
|
if ntype.Indirection == 0 {
|
|
|
|
return e, nil, false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = ntype.alloc()
|
|
|
|
|
|
|
|
var nl uint16
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, eId, err := unmarshalTypeId(e)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, isNil, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
if eId == ST_NIL {
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, nl, err = unmarshalNil(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, isNil, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
err = setTypeNil(ret, int(nl))
|
|
|
|
return ie, ret, true, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if ntype.ValType == ST_ERROR {
|
|
|
|
return e, ret, false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if eId != ntype.ValType {
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, false, ErrTypeInvalid
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return ie, ret, false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func unmarshalError(e []byte, ntype *NType) (ie []byte, ret interface{}, err error) {
|
|
|
|
ret = ntype.alloc()
|
|
|
|
|
|
|
|
var nl uint16
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, eId, err := unmarshalTypeId(e)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
if eId == ST_NIL {
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, nl, err = unmarshalNil(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
err = setTypeNil(ret, int(nl))
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if eId != ST_STRING {
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, ErrTypeInvalid
|
|
|
|
}
|
|
|
|
ie, v, err := unmarshalString(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
err = setTypeVal(ret, fmt.Errorf(v), ntype)
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
func unmarshalTypeId(e []byte) (ie []byte, ret uint32, err error) {
|
2021-09-06 23:33:50 +02:00
|
|
|
return unmarshalUint32(e)
|
|
|
|
}
|
|
|
|
|
|
|
|
func unmarshalCommon(e []byte, ntype *NType) (ie []byte, ret interface{}, err error) {
|
|
|
|
ctype := getTypeById(ntype.ValType)
|
|
|
|
if ctype == nil {
|
2021-09-07 16:05:04 +02:00
|
|
|
return e, ret, ErrTypeUnknown
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// pointer could be nil
|
|
|
|
ie, ptrNil, isNil, err := unmarshalPtrIfNil(e, ntype)
|
|
|
|
if err != nil {
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, err
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ptrNil != nil {
|
|
|
|
if isNil {
|
|
|
|
return ie, ptrNil, err
|
|
|
|
}
|
|
|
|
ret = ptrNil
|
|
|
|
}
|
|
|
|
if ret == nil {
|
|
|
|
ret = ntype.alloc()
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ctype.Id {
|
|
|
|
case ST_BOOL:
|
|
|
|
var v bool
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, v, err = unmarshalBool(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
setTypeVal(ret, v, ntype)
|
|
|
|
return ie, ret, err
|
|
|
|
case ST_UINT8:
|
|
|
|
var v uint8
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, v, err = unmarshalUint8(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
setTypeVal(ret, v, ntype)
|
|
|
|
return ie, ret, err
|
|
|
|
case ST_UINT16:
|
|
|
|
var v uint16
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, v, err = unmarshalUint16(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
setTypeVal(ret, v, ntype)
|
|
|
|
return ie, ret, err
|
|
|
|
case ST_UINT32:
|
|
|
|
var v uint32
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, v, err = unmarshalUint32(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
setTypeVal(ret, v, ntype)
|
|
|
|
return ie, ret, err
|
|
|
|
case ST_UINT64:
|
|
|
|
var v uint64
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, v, err = unmarshalUint64(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
setTypeVal(ret, v, ntype)
|
|
|
|
return ie, ret, err
|
|
|
|
case ST_INT8:
|
|
|
|
var v int8
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, v, err = unmarshalInt8(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
setTypeVal(ret, v, ntype)
|
|
|
|
return ie, ret, err
|
|
|
|
case ST_INT16:
|
|
|
|
var v int16
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, v, err = unmarshalInt16(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
setTypeVal(ret, v, ntype)
|
|
|
|
return ie, ret, err
|
|
|
|
case ST_INT32:
|
|
|
|
var v int32
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, v, err = unmarshalInt32(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
setTypeVal(ret, v, ntype)
|
|
|
|
return ie, ret, err
|
|
|
|
case ST_INT64:
|
|
|
|
var v int64
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, v, err = unmarshalInt64(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
setTypeVal(ret, v, ntype)
|
|
|
|
return ie, ret, err
|
|
|
|
case ST_FLOAT32:
|
|
|
|
var v float32
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, v, err = unmarshalFloat32(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
setTypeVal(ret, v, ntype)
|
|
|
|
return ie, ret, err
|
|
|
|
case ST_FLOAT64:
|
|
|
|
var v float64
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, v, err = unmarshalFloat64(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
setTypeVal(ret, v, ntype)
|
|
|
|
return ie, ret, err
|
|
|
|
case ST_STRING:
|
|
|
|
var v string
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, v, err = unmarshalString(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
setTypeVal(ret, v, ntype)
|
|
|
|
return ie, ret, err
|
|
|
|
case ST_ERROR:
|
|
|
|
return unmarshalError(ie, ntype)
|
|
|
|
default:
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, ErrTypeUnknown
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func unmarshalSlice(e []byte, ntype *NType) (ie []byte, ret interface{}, err error) {
|
|
|
|
ret = ntype.alloc()
|
|
|
|
rv := getVal(ret)
|
2021-09-08 13:27:39 +02:00
|
|
|
rv = traverseValuePtr(rv)
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, l, err := unmarshalUint32(e)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
|
|
|
|
stype := getTypeById(ntype.ValType)
|
|
|
|
if stype == nil {
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, ErrTypeUnknown
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
var v interface{}
|
|
|
|
for i := 0; i < int(l); i++ {
|
|
|
|
ie, v, err = unmarshalType(ie, stype)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
// TODO: checks?
|
2021-09-06 23:33:50 +02:00
|
|
|
rv.Set(reflect.Append(rv, getVal(v)))
|
|
|
|
}
|
|
|
|
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func unmarshalArray(e []byte, ntype *NType) (ie []byte, ret interface{}, err error) {
|
|
|
|
ret = ntype.alloc()
|
|
|
|
rv := getVal(ret)
|
2021-09-08 13:27:39 +02:00
|
|
|
rv = traverseValuePtr(rv)
|
2021-09-06 23:33:50 +02:00
|
|
|
|
|
|
|
stype := getTypeById(ntype.ValType)
|
|
|
|
if stype == nil {
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, ErrTypeUnknown
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
var v interface{}
|
|
|
|
ie = e
|
|
|
|
for i := 0; i < ntype.arrayLen; i++ {
|
|
|
|
ie, v, err = unmarshalType(ie, stype)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
// TODO: checks?
|
2021-09-06 23:33:50 +02:00
|
|
|
rv.Index(i).Set(getVal(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func unmarshalStruct(e []byte, ntype *NType) (ie []byte, ret interface{}, err error) {
|
|
|
|
ret = ntype.alloc()
|
|
|
|
rv := getVal(ret)
|
2021-09-08 13:27:39 +02:00
|
|
|
rv = traverseValuePtr(rv)
|
2021-09-06 23:33:50 +02:00
|
|
|
ie = e
|
|
|
|
|
|
|
|
stype := getTypeById(ntype.ValType)
|
|
|
|
if stype == nil {
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, ErrTypeUnknown
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
var v interface{}
|
|
|
|
for i, field := range stype.structFields {
|
2021-09-07 21:35:35 +02:00
|
|
|
if field.SId > rv.NumField() {
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, ErrTypeInvalid
|
|
|
|
}
|
|
|
|
if rv.Field(field.SId).CanSet() {
|
|
|
|
ftype := getTypeById(field.Id)
|
|
|
|
if ftype == nil {
|
|
|
|
return ie, ret, ErrTypeUnknown
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, v, err = unmarshalType(ie, ftype)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
2021-09-07 16:05:04 +02:00
|
|
|
// TODO: checks?
|
|
|
|
rv.Field(i).Set(getVal(v))
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func unmarshalInterface(e []byte, ntype *NType) (ie []byte, ret interface{}, err error) {
|
|
|
|
ie = e
|
|
|
|
stype := getTypeById(ntype.ValType)
|
|
|
|
if stype == nil {
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, ErrTypeUnknown
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return unmarshalCommon(ie, ntype)
|
|
|
|
}
|
|
|
|
|
|
|
|
func unmarshalType(e []byte, ntype *NType) (ie []byte, ret interface{}, err error) {
|
|
|
|
switch ntype.MainTypeId {
|
|
|
|
case ST_COMMON:
|
|
|
|
return unmarshalCommon(e, ntype)
|
|
|
|
case ST_SLICE:
|
|
|
|
return unmarshalSlice(e, ntype)
|
|
|
|
case ST_ARRAY:
|
|
|
|
return unmarshalArray(e, ntype)
|
|
|
|
case ST_STRUCT:
|
|
|
|
return unmarshalStruct(e, ntype)
|
|
|
|
case ST_INTERFACE:
|
|
|
|
return unmarshalInterface(e, ntype)
|
|
|
|
default:
|
2021-09-07 16:05:04 +02:00
|
|
|
return e, ret, ErrTypeUnknown
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func unmarshalVal(e []byte) (ie []byte, ret interface{}, err error) {
|
|
|
|
if len(e) < ST_ID_SIZE {
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, ErrValueInvalid
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// type id
|
|
|
|
var tid uint32
|
2021-09-07 16:05:04 +02:00
|
|
|
ie, tid, err = unmarshalTypeId(e)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
2021-09-06 23:33:50 +02:00
|
|
|
vt := getTypeById(tid)
|
|
|
|
if vt == nil {
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, ErrTypeUnknown
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// alloc
|
|
|
|
ret = vt.alloc()
|
|
|
|
|
|
|
|
// check for nil
|
|
|
|
if len(ie) < 1 {
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, ErrValueInvalid
|
|
|
|
}
|
|
|
|
ie, isNil, err := unmarshalBool(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
if isNil {
|
|
|
|
if len(ie) < 2 {
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, ErrValueInvalid
|
|
|
|
}
|
|
|
|
ie, nl, err := unmarshalNil(ie)
|
|
|
|
if err != nil {
|
|
|
|
return ie, ret, err
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
if int(nl) > vt.Indirection {
|
2021-09-07 16:05:04 +02:00
|
|
|
return ie, ret, ErrValueInvalid
|
2021-09-06 23:33:50 +02:00
|
|
|
}
|
|
|
|
err = setTypeNil(ret, int(nl))
|
|
|
|
return ie, ret, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return unmarshalType(ie, vt)
|
|
|
|
}
|