mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-04-24 04:58:31 -05:00
switch to go vendoring
This commit is contained in:
+55
@@ -0,0 +1,55 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/shamaton/msgpack/v2/def"
|
||||
)
|
||||
|
||||
func (d *decoder) isCodeBin(v byte) bool {
|
||||
switch v {
|
||||
case def.Bin8, def.Bin16, def.Bin32:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (d *decoder) asBin(offset int, k reflect.Kind) ([]byte, int, error) {
|
||||
code, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return emptyBytes, 0, err
|
||||
}
|
||||
|
||||
switch code {
|
||||
case def.Bin8:
|
||||
l, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return emptyBytes, 0, err
|
||||
}
|
||||
o := offset + int(uint8(l))
|
||||
return d.data[offset:o], o, nil
|
||||
case def.Bin16:
|
||||
bs, offset, err := d.readSize2(offset)
|
||||
o := offset + int(binary.BigEndian.Uint16(bs))
|
||||
if err != nil {
|
||||
return emptyBytes, 0, err
|
||||
}
|
||||
return d.data[offset:o], o, nil
|
||||
case def.Bin32:
|
||||
bs, offset, err := d.readSize4(offset)
|
||||
o := offset + int(binary.BigEndian.Uint32(bs))
|
||||
if err != nil {
|
||||
return emptyBytes, 0, err
|
||||
}
|
||||
return d.data[offset:o], o, nil
|
||||
}
|
||||
|
||||
return emptyBytes, 0, d.errorTemplate(code, k)
|
||||
}
|
||||
|
||||
func (d *decoder) asBinString(offset int, k reflect.Kind) (string, int, error) {
|
||||
bs, offset, err := d.asBin(offset, k)
|
||||
return *(*string)(unsafe.Pointer(&bs)), offset, err
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/shamaton/msgpack/v2/def"
|
||||
)
|
||||
|
||||
func (d *decoder) asBool(offset int, k reflect.Kind) (bool, int, error) {
|
||||
code := d.data[offset]
|
||||
offset++
|
||||
|
||||
switch code {
|
||||
case def.True:
|
||||
return true, offset, nil
|
||||
case def.False:
|
||||
return false, offset, nil
|
||||
}
|
||||
return false, 0, d.errorTemplate(code, k)
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
|
||||
"github.com/shamaton/msgpack/v2/def"
|
||||
)
|
||||
|
||||
func (d *decoder) asComplex64(offset int, k reflect.Kind) (complex64, int, error) {
|
||||
code, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
|
||||
switch code {
|
||||
case def.Fixext8:
|
||||
t, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
if int8(t) != def.ComplexTypeCode() {
|
||||
return complex(0, 0), 0, fmt.Errorf("fixext8. complex type is diffrent %d, %d", t, def.ComplexTypeCode())
|
||||
}
|
||||
rb, offset, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
ib, offset, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
r := math.Float32frombits(binary.BigEndian.Uint32(rb))
|
||||
i := math.Float32frombits(binary.BigEndian.Uint32(ib))
|
||||
return complex(r, i), offset, nil
|
||||
|
||||
case def.Fixext16:
|
||||
t, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
if int8(t) != def.ComplexTypeCode() {
|
||||
return complex(0, 0), 0, fmt.Errorf("fixext16. complex type is diffrent %d, %d", t, def.ComplexTypeCode())
|
||||
}
|
||||
rb, offset, err := d.readSize8(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
ib, offset, err := d.readSize8(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
r := math.Float64frombits(binary.BigEndian.Uint64(rb))
|
||||
i := math.Float64frombits(binary.BigEndian.Uint64(ib))
|
||||
return complex64(complex(r, i)), offset, nil
|
||||
|
||||
}
|
||||
|
||||
return complex(0, 0), 0, fmt.Errorf("should not reach this line!! code %x decoding %v", code, k)
|
||||
}
|
||||
|
||||
func (d *decoder) asComplex128(offset int, k reflect.Kind) (complex128, int, error) {
|
||||
code, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
|
||||
switch code {
|
||||
case def.Fixext8:
|
||||
t, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
if int8(t) != def.ComplexTypeCode() {
|
||||
return complex(0, 0), 0, fmt.Errorf("fixext8. complex type is diffrent %d, %d", t, def.ComplexTypeCode())
|
||||
}
|
||||
rb, offset, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
ib, offset, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
r := math.Float32frombits(binary.BigEndian.Uint32(rb))
|
||||
i := math.Float32frombits(binary.BigEndian.Uint32(ib))
|
||||
return complex128(complex(r, i)), offset, nil
|
||||
|
||||
case def.Fixext16:
|
||||
t, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
if int8(t) != def.ComplexTypeCode() {
|
||||
return complex(0, 0), 0, fmt.Errorf("fixext16. complex type is diffrent %d, %d", t, def.ComplexTypeCode())
|
||||
}
|
||||
rb, offset, err := d.readSize8(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
ib, offset, err := d.readSize8(offset)
|
||||
if err != nil {
|
||||
return complex(0, 0), 0, err
|
||||
}
|
||||
r := math.Float64frombits(binary.BigEndian.Uint64(rb))
|
||||
i := math.Float64frombits(binary.BigEndian.Uint64(ib))
|
||||
return complex(r, i), offset, nil
|
||||
|
||||
}
|
||||
|
||||
return complex(0, 0), 0, fmt.Errorf("should not reach this line!! code %x decoding %v", code, k)
|
||||
}
|
||||
+342
@@ -0,0 +1,342 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/shamaton/msgpack/v2/internal/common"
|
||||
)
|
||||
|
||||
type decoder struct {
|
||||
data []byte
|
||||
asArray bool
|
||||
common.Common
|
||||
}
|
||||
|
||||
// Decode analyzes the MessagePack-encoded data and stores
|
||||
// the result into the pointer of v.
|
||||
func Decode(data []byte, v interface{}, asArray bool) error {
|
||||
d := decoder{data: data, asArray: asArray}
|
||||
|
||||
if d.data == nil || len(d.data) < 1 {
|
||||
return fmt.Errorf("data is empty")
|
||||
}
|
||||
rv := reflect.ValueOf(v)
|
||||
if rv.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("holder must set pointer value. but got: %t", v)
|
||||
}
|
||||
|
||||
rv = rv.Elem()
|
||||
|
||||
last, err := d.decode(rv, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(data) != last {
|
||||
return fmt.Errorf("failed deserialization size=%d, last=%d", len(data), last)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *decoder) decode(rv reflect.Value, offset int) (int, error) {
|
||||
k := rv.Kind()
|
||||
switch k {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v, o, err := d.asInt(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv.SetInt(v)
|
||||
offset = o
|
||||
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v, o, err := d.asUint(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv.SetUint(v)
|
||||
offset = o
|
||||
|
||||
case reflect.Float32:
|
||||
v, o, err := d.asFloat32(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv.SetFloat(float64(v))
|
||||
offset = o
|
||||
|
||||
case reflect.Float64:
|
||||
v, o, err := d.asFloat64(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv.SetFloat(v)
|
||||
offset = o
|
||||
|
||||
case reflect.String:
|
||||
// byte slice
|
||||
if d.isCodeBin(d.data[offset]) {
|
||||
v, offset, err := d.asBinString(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv.SetString(v)
|
||||
return offset, nil
|
||||
}
|
||||
v, o, err := d.asString(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv.SetString(v)
|
||||
offset = o
|
||||
|
||||
case reflect.Bool:
|
||||
v, o, err := d.asBool(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv.SetBool(v)
|
||||
offset = o
|
||||
|
||||
case reflect.Slice:
|
||||
// nil
|
||||
if d.isCodeNil(d.data[offset]) {
|
||||
offset++
|
||||
return offset, nil
|
||||
}
|
||||
// byte slice
|
||||
if d.isCodeBin(d.data[offset]) {
|
||||
bs, offset, err := d.asBin(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv.SetBytes(bs)
|
||||
return offset, nil
|
||||
}
|
||||
// string to bytes
|
||||
if d.isCodeString(d.data[offset]) {
|
||||
l, offset, err := d.stringByteLength(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
bs, offset, err := d.asStringByteByLength(offset, l, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv.SetBytes(bs)
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
// get slice length
|
||||
l, o, err := d.sliceLength(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err = d.hasRequiredLeastSliceSize(o, l); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// check fixed type
|
||||
fixedOffset, found, err := d.asFixedSlice(rv, o, l)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if found {
|
||||
return fixedOffset, nil
|
||||
}
|
||||
|
||||
// create slice dynamically
|
||||
tmpSlice := reflect.MakeSlice(rv.Type(), l, l)
|
||||
for i := 0; i < l; i++ {
|
||||
v := tmpSlice.Index(i)
|
||||
if v.Kind() == reflect.Struct {
|
||||
o, err = d.setStruct(v, o, k)
|
||||
} else {
|
||||
o, err = d.decode(v, o)
|
||||
}
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
rv.Set(tmpSlice)
|
||||
offset = o
|
||||
|
||||
case reflect.Complex64:
|
||||
v, o, err := d.asComplex64(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv.SetComplex(complex128(v))
|
||||
offset = o
|
||||
|
||||
case reflect.Complex128:
|
||||
v, o, err := d.asComplex128(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv.SetComplex(v)
|
||||
offset = o
|
||||
|
||||
case reflect.Array:
|
||||
// nil
|
||||
if d.isCodeNil(d.data[offset]) {
|
||||
offset++
|
||||
return offset, nil
|
||||
}
|
||||
// byte slice
|
||||
if d.isCodeBin(d.data[offset]) {
|
||||
bs, offset, err := d.asBin(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(bs) > rv.Len() {
|
||||
return 0, fmt.Errorf("%v len is %d, but msgpack has %d elements", rv.Type(), rv.Len(), len(bs))
|
||||
}
|
||||
for i, b := range bs {
|
||||
rv.Index(i).SetUint(uint64(b))
|
||||
}
|
||||
return offset, nil
|
||||
}
|
||||
// string to bytes
|
||||
if d.isCodeString(d.data[offset]) {
|
||||
l, offset, err := d.stringByteLength(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if l > rv.Len() {
|
||||
return 0, fmt.Errorf("%v len is %d, but msgpack has %d elements", rv.Type(), rv.Len(), l)
|
||||
}
|
||||
bs, offset, err := d.asStringByteByLength(offset, l, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
for i, b := range bs {
|
||||
rv.Index(i).SetUint(uint64(b))
|
||||
}
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
// get slice length
|
||||
l, o, err := d.sliceLength(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if l > rv.Len() {
|
||||
return 0, fmt.Errorf("%v len is %d, but msgpack has %d elements", rv.Type(), rv.Len(), l)
|
||||
}
|
||||
|
||||
if err = d.hasRequiredLeastSliceSize(o, l); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// create array dynamically
|
||||
for i := 0; i < l; i++ {
|
||||
o, err = d.decode(rv.Index(i), o)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
offset = o
|
||||
|
||||
case reflect.Map:
|
||||
// nil
|
||||
if d.isCodeNil(d.data[offset]) {
|
||||
offset++
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
// get map length
|
||||
l, o, err := d.mapLength(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err = d.hasRequiredLeastMapSize(o, l); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// check fixed type
|
||||
fixedOffset, found, err := d.asFixedMap(rv, o, l)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if found {
|
||||
return fixedOffset, nil
|
||||
}
|
||||
|
||||
// create dynamically
|
||||
key := rv.Type().Key()
|
||||
value := rv.Type().Elem()
|
||||
if rv.IsNil() {
|
||||
rv.Set(reflect.MakeMapWithSize(rv.Type(), l))
|
||||
}
|
||||
for i := 0; i < l; i++ {
|
||||
k := reflect.New(key).Elem()
|
||||
v := reflect.New(value).Elem()
|
||||
o, err = d.decode(k, o)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
o, err = d.decode(v, o)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
rv.SetMapIndex(k, v)
|
||||
}
|
||||
offset = o
|
||||
|
||||
case reflect.Struct:
|
||||
o, err := d.setStruct(rv, offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
offset = o
|
||||
|
||||
case reflect.Ptr:
|
||||
// nil
|
||||
if d.isCodeNil(d.data[offset]) {
|
||||
offset++
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
if rv.Elem().Kind() == reflect.Invalid {
|
||||
n := reflect.New(rv.Type().Elem())
|
||||
rv.Set(n)
|
||||
}
|
||||
|
||||
o, err := d.decode(rv.Elem(), offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
offset = o
|
||||
|
||||
case reflect.Interface:
|
||||
if rv.Elem().Kind() == reflect.Ptr {
|
||||
o, err := d.decode(rv.Elem(), offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
offset = o
|
||||
} else {
|
||||
v, o, err := d.asInterface(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if v != nil {
|
||||
rv.Set(reflect.ValueOf(v))
|
||||
}
|
||||
offset = o
|
||||
}
|
||||
|
||||
default:
|
||||
return 0, fmt.Errorf("type(%v) is unsupported", rv.Kind())
|
||||
}
|
||||
return offset, nil
|
||||
}
|
||||
|
||||
func (d *decoder) errorTemplate(code byte, k reflect.Kind) error {
|
||||
return fmt.Errorf("msgpack : invalid code %x decoding %v", code, k)
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"github.com/shamaton/msgpack/v2/ext"
|
||||
"github.com/shamaton/msgpack/v2/time"
|
||||
)
|
||||
|
||||
var extCoderMap = map[int8]ext.Decoder{time.Decoder.Code(): time.Decoder}
|
||||
var extCoders = []ext.Decoder{time.Decoder}
|
||||
|
||||
// AddExtDecoder adds decoders for extension types.
|
||||
func AddExtDecoder(f ext.Decoder) {
|
||||
// ignore time
|
||||
if f.Code() == time.Decoder.Code() {
|
||||
return
|
||||
}
|
||||
|
||||
_, ok := extCoderMap[f.Code()]
|
||||
if !ok {
|
||||
extCoderMap[f.Code()] = f
|
||||
updateExtCoders()
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveExtDecoder removes decoders for extension types.
|
||||
func RemoveExtDecoder(f ext.Decoder) {
|
||||
// ignore time
|
||||
if f.Code() == time.Decoder.Code() {
|
||||
return
|
||||
}
|
||||
|
||||
_, ok := extCoderMap[f.Code()]
|
||||
if ok {
|
||||
delete(extCoderMap, f.Code())
|
||||
updateExtCoders()
|
||||
}
|
||||
}
|
||||
|
||||
func updateExtCoders() {
|
||||
extCoders = make([]ext.Decoder, len(extCoderMap))
|
||||
i := 0
|
||||
for k := range extCoderMap {
|
||||
extCoders[i] = extCoderMap[k]
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
var zero = time.Unix(0,0)
|
||||
|
||||
func (d *decoder) isDateTime(offset int) bool {
|
||||
code, offset := d.readSize1(offset)
|
||||
|
||||
if code == def.Fixext4 {
|
||||
t, _ := d.readSize1(offset)
|
||||
return int8(t) == def.TimeStamp
|
||||
} else if code == def.Fixext8 {
|
||||
t, _ := d.readSize1(offset)
|
||||
return int8(t) == def.TimeStamp
|
||||
} else if code == def.Ext8 {
|
||||
l, offset := d.readSize1(offset)
|
||||
t, _ := d.readSize1(offset)
|
||||
return l == 12 && int8(t) == def.TimeStamp
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (d *decoder) asDateTime(offset int, k reflect.Kind) (time.Time, int, error) {
|
||||
code, offset := d.readSize1(offset)
|
||||
|
||||
switch code {
|
||||
case def.Fixext4:
|
||||
_, offset = d.readSize1(offset)
|
||||
bs, offset := d.readSize4(offset)
|
||||
return time.Unix(int64(binary.BigEndian.Uint32(bs)), 0), offset, nil
|
||||
|
||||
case def.Fixext8:
|
||||
_, offset = d.readSize1(offset)
|
||||
bs, offset := d.readSize8(offset)
|
||||
data64 := binary.BigEndian.Uint64(bs)
|
||||
nano := int64(data64 >> 34)
|
||||
if nano > 999999999 {
|
||||
return zero, 0, fmt.Errorf("In timestamp 64 formats, nanoseconds must not be larger than 999999999 : %d", nano)
|
||||
}
|
||||
return time.Unix(int64(data64&0x00000003ffffffff), nano), offset, nil
|
||||
|
||||
case def.Ext8:
|
||||
_, offset = d.readSize1(offset)
|
||||
_, offset = d.readSize1(offset)
|
||||
nanobs, offset := d.readSize4(offset)
|
||||
secbs, offset := d.readSize8(offset)
|
||||
nano := binary.BigEndian.Uint32(nanobs)
|
||||
if nano > 999999999 {
|
||||
return zero, 0, fmt.Errorf("In timestamp 96 formats, nanoseconds must not be larger than 999999999 : %d", nano)
|
||||
}
|
||||
sec := binary.BigEndian.Uint64(secbs)
|
||||
return time.Unix(int64(sec), int64(nano)), offset, nil
|
||||
}
|
||||
|
||||
return zero, 0, d.errorTemplate(code, k)
|
||||
}
|
||||
*/
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"reflect"
|
||||
|
||||
"github.com/shamaton/msgpack/v2/def"
|
||||
)
|
||||
|
||||
func (d *decoder) asFloat32(offset int, k reflect.Kind) (float32, int, error) {
|
||||
code, _, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case code == def.Float32:
|
||||
offset++
|
||||
bs, offset, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
v := math.Float32frombits(binary.BigEndian.Uint32(bs))
|
||||
return v, offset, nil
|
||||
|
||||
case d.isPositiveFixNum(code), code == def.Uint8, code == def.Uint16, code == def.Uint32, code == def.Uint64:
|
||||
v, offset, err := d.asUint(offset, k)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
return float32(v), offset, nil
|
||||
|
||||
case d.isNegativeFixNum(code), code == def.Int8, code == def.Int16, code == def.Int32, code == def.Int64:
|
||||
v, offset, err := d.asInt(offset, k)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
return float32(v), offset, nil
|
||||
|
||||
case code == def.Nil:
|
||||
offset++
|
||||
return 0, offset, nil
|
||||
}
|
||||
return 0, 0, d.errorTemplate(code, k)
|
||||
}
|
||||
|
||||
func (d *decoder) asFloat64(offset int, k reflect.Kind) (float64, int, error) {
|
||||
code, _, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case code == def.Float64:
|
||||
offset++
|
||||
bs, offset, err := d.readSize8(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
v := math.Float64frombits(binary.BigEndian.Uint64(bs))
|
||||
return v, offset, nil
|
||||
|
||||
case code == def.Float32:
|
||||
offset++
|
||||
bs, offset, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
v := math.Float32frombits(binary.BigEndian.Uint32(bs))
|
||||
return float64(v), offset, nil
|
||||
|
||||
case d.isPositiveFixNum(code), code == def.Uint8, code == def.Uint16, code == def.Uint32, code == def.Uint64:
|
||||
v, offset, err := d.asUint(offset, k)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
return float64(v), offset, nil
|
||||
|
||||
case d.isNegativeFixNum(code), code == def.Int8, code == def.Int16, code == def.Int32, code == def.Int64:
|
||||
v, offset, err := d.asInt(offset, k)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
return float64(v), offset, nil
|
||||
|
||||
case code == def.Nil:
|
||||
offset++
|
||||
return 0, offset, nil
|
||||
}
|
||||
return 0, 0, d.errorTemplate(code, k)
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
|
||||
"github.com/shamaton/msgpack/v2/def"
|
||||
)
|
||||
|
||||
func (d *decoder) isPositiveFixNum(v byte) bool {
|
||||
return def.PositiveFixIntMin <= v && v <= def.PositiveFixIntMax
|
||||
}
|
||||
|
||||
func (d *decoder) isNegativeFixNum(v byte) bool {
|
||||
return def.NegativeFixintMin <= int8(v) && int8(v) <= def.NegativeFixintMax
|
||||
}
|
||||
|
||||
func (d *decoder) asInt(offset int, k reflect.Kind) (int64, int, error) {
|
||||
|
||||
code, _, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case d.isPositiveFixNum(code):
|
||||
b, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int64(b), offset, nil
|
||||
|
||||
case d.isNegativeFixNum(code):
|
||||
b, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int64(int8(b)), offset, nil
|
||||
|
||||
case code == def.Uint8:
|
||||
offset++
|
||||
b, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int64(uint8(b)), offset, nil
|
||||
|
||||
case code == def.Int8:
|
||||
offset++
|
||||
b, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int64(int8(b)), offset, nil
|
||||
|
||||
case code == def.Uint16:
|
||||
offset++
|
||||
bs, offset, err := d.readSize2(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
v := binary.BigEndian.Uint16(bs)
|
||||
return int64(v), offset, nil
|
||||
|
||||
case code == def.Int16:
|
||||
offset++
|
||||
bs, offset, err := d.readSize2(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
v := int16(binary.BigEndian.Uint16(bs))
|
||||
return int64(v), offset, nil
|
||||
|
||||
case code == def.Uint32:
|
||||
offset++
|
||||
bs, offset, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
v := binary.BigEndian.Uint32(bs)
|
||||
return int64(v), offset, nil
|
||||
|
||||
case code == def.Int32:
|
||||
offset++
|
||||
bs, offset, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
v := int32(binary.BigEndian.Uint32(bs))
|
||||
return int64(v), offset, nil
|
||||
|
||||
case code == def.Uint64:
|
||||
offset++
|
||||
bs, offset, err := d.readSize8(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int64(binary.BigEndian.Uint64(bs)), offset, nil
|
||||
|
||||
case code == def.Int64:
|
||||
offset++
|
||||
bs, offset, err := d.readSize8(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int64(binary.BigEndian.Uint64(bs)), offset, nil
|
||||
|
||||
case code == def.Float32:
|
||||
v, offset, err := d.asFloat32(offset, k)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int64(v), offset, nil
|
||||
|
||||
case code == def.Float64:
|
||||
v, offset, err := d.asFloat64(offset, k)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int64(v), offset, nil
|
||||
|
||||
case code == def.Nil:
|
||||
offset++
|
||||
return 0, offset, nil
|
||||
}
|
||||
|
||||
return 0, 0, d.errorTemplate(code, k)
|
||||
}
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/shamaton/msgpack/v2/def"
|
||||
)
|
||||
|
||||
func (d *decoder) asInterface(offset int, k reflect.Kind) (interface{}, int, error) {
|
||||
code, _, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case code == def.Nil:
|
||||
offset++
|
||||
return nil, offset, nil
|
||||
|
||||
case code == def.True, code == def.False:
|
||||
v, offset, err := d.asBool(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return v, offset, nil
|
||||
|
||||
case d.isPositiveFixNum(code), code == def.Uint8:
|
||||
v, offset, err := d.asUint(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return uint8(v), offset, err
|
||||
case code == def.Uint16:
|
||||
v, offset, err := d.asUint(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return uint16(v), offset, err
|
||||
case code == def.Uint32:
|
||||
v, offset, err := d.asUint(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return uint32(v), offset, err
|
||||
case code == def.Uint64:
|
||||
v, offset, err := d.asUint(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return v, offset, err
|
||||
|
||||
case d.isNegativeFixNum(code), code == def.Int8:
|
||||
v, offset, err := d.asInt(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return int8(v), offset, err
|
||||
case code == def.Int16:
|
||||
v, offset, err := d.asInt(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return int16(v), offset, err
|
||||
case code == def.Int32:
|
||||
v, offset, err := d.asInt(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return int32(v), offset, err
|
||||
case code == def.Int64:
|
||||
v, offset, err := d.asInt(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return v, offset, err
|
||||
|
||||
case code == def.Float32:
|
||||
v, offset, err := d.asFloat32(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return v, offset, err
|
||||
case code == def.Float64:
|
||||
v, offset, err := d.asFloat64(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return v, offset, err
|
||||
|
||||
case d.isFixString(code), code == def.Str8, code == def.Str16, code == def.Str32:
|
||||
v, offset, err := d.asString(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return v, offset, err
|
||||
|
||||
case code == def.Bin8, code == def.Bin16, code == def.Bin32:
|
||||
v, offset, err := d.asBin(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return v, offset, err
|
||||
|
||||
case d.isFixSlice(code), code == def.Array16, code == def.Array32:
|
||||
l, o, err := d.sliceLength(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
if err = d.hasRequiredLeastSliceSize(o, l); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
v := make([]interface{}, l)
|
||||
for i := 0; i < l; i++ {
|
||||
vv, o2, err := d.asInterface(o, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
v[i] = vv
|
||||
o = o2
|
||||
}
|
||||
offset = o
|
||||
return v, offset, nil
|
||||
|
||||
case d.isFixMap(code), code == def.Map16, code == def.Map32:
|
||||
l, o, err := d.mapLength(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
if err = d.hasRequiredLeastMapSize(o, l); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
v := make(map[interface{}]interface{}, l)
|
||||
for i := 0; i < l; i++ {
|
||||
if d.canSetAsMapKey(o) != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
key, o2, err := d.asInterface(o, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
value, o2, err := d.asInterface(o2, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
v[key] = value
|
||||
o = o2
|
||||
}
|
||||
offset = o
|
||||
return v, offset, nil
|
||||
}
|
||||
|
||||
/* use ext
|
||||
if d.isDateTime(offset) {
|
||||
v, offset, err := d.asDateTime(offset, k)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return v, offset, nil
|
||||
}
|
||||
*/
|
||||
|
||||
// ext
|
||||
for i := range extCoders {
|
||||
if extCoders[i].IsType(offset, &d.data) {
|
||||
v, offset, err := extCoders[i].AsValue(offset, k, &d.data)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return v, offset, nil
|
||||
}
|
||||
}
|
||||
return nil, 0, d.errorTemplate(code, k)
|
||||
}
|
||||
|
||||
func (d *decoder) canSetAsMapKey(index int) error {
|
||||
code, _, err := d.readSize1(index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch {
|
||||
case d.isFixSlice(code), code == def.Array16, code == def.Array32:
|
||||
return fmt.Errorf("can not use slice code for map key/ code: %x", code)
|
||||
case d.isFixMap(code), code == def.Map16, code == def.Map32:
|
||||
return fmt.Errorf("can not use map code for map key/ code: %x", code)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+750
@@ -0,0 +1,750 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"reflect"
|
||||
|
||||
"github.com/shamaton/msgpack/v2/def"
|
||||
)
|
||||
|
||||
var (
|
||||
typeMapStringInt = reflect.TypeOf(map[string]int{})
|
||||
typeMapStringInt8 = reflect.TypeOf(map[string]int8{})
|
||||
typeMapStringInt16 = reflect.TypeOf(map[string]int16{})
|
||||
typeMapStringInt32 = reflect.TypeOf(map[string]int32{})
|
||||
typeMapStringInt64 = reflect.TypeOf(map[string]int64{})
|
||||
|
||||
typeMapStringUint = reflect.TypeOf(map[string]uint{})
|
||||
typeMapStringUint8 = reflect.TypeOf(map[string]uint8{})
|
||||
typeMapStringUint16 = reflect.TypeOf(map[string]uint16{})
|
||||
typeMapStringUint32 = reflect.TypeOf(map[string]uint32{})
|
||||
typeMapStringUint64 = reflect.TypeOf(map[string]uint64{})
|
||||
|
||||
typeMapStringFloat32 = reflect.TypeOf(map[string]float32{})
|
||||
typeMapStringFloat64 = reflect.TypeOf(map[string]float64{})
|
||||
|
||||
typeMapStringBool = reflect.TypeOf(map[string]bool{})
|
||||
typeMapStringString = reflect.TypeOf(map[string]string{})
|
||||
|
||||
typeMapIntString = reflect.TypeOf(map[int]string{})
|
||||
typeMapInt8String = reflect.TypeOf(map[int8]string{})
|
||||
typeMapInt16String = reflect.TypeOf(map[int16]string{})
|
||||
typeMapInt32String = reflect.TypeOf(map[int32]string{})
|
||||
typeMapInt64String = reflect.TypeOf(map[int64]string{})
|
||||
typeMapIntBool = reflect.TypeOf(map[int]bool{})
|
||||
typeMapInt8Bool = reflect.TypeOf(map[int8]bool{})
|
||||
typeMapInt16Bool = reflect.TypeOf(map[int16]bool{})
|
||||
typeMapInt32Bool = reflect.TypeOf(map[int32]bool{})
|
||||
typeMapInt64Bool = reflect.TypeOf(map[int64]bool{})
|
||||
|
||||
typeMapUintString = reflect.TypeOf(map[uint]string{})
|
||||
typeMapUint8String = reflect.TypeOf(map[uint8]string{})
|
||||
typeMapUint16String = reflect.TypeOf(map[uint16]string{})
|
||||
typeMapUint32String = reflect.TypeOf(map[uint32]string{})
|
||||
typeMapUint64String = reflect.TypeOf(map[uint64]string{})
|
||||
typeMapUintBool = reflect.TypeOf(map[uint]bool{})
|
||||
typeMapUint8Bool = reflect.TypeOf(map[uint8]bool{})
|
||||
typeMapUint16Bool = reflect.TypeOf(map[uint16]bool{})
|
||||
typeMapUint32Bool = reflect.TypeOf(map[uint32]bool{})
|
||||
typeMapUint64Bool = reflect.TypeOf(map[uint64]bool{})
|
||||
|
||||
typeMapFloat32String = reflect.TypeOf(map[float32]string{})
|
||||
typeMapFloat64String = reflect.TypeOf(map[float64]string{})
|
||||
typeMapFloat32Bool = reflect.TypeOf(map[float32]bool{})
|
||||
typeMapFloat64Bool = reflect.TypeOf(map[float64]bool{})
|
||||
)
|
||||
|
||||
func (d *decoder) isFixMap(v byte) bool {
|
||||
return def.FixMap <= v && v <= def.FixMap+0x0f
|
||||
}
|
||||
|
||||
func (d *decoder) mapLength(offset int, k reflect.Kind) (int, int, error) {
|
||||
code, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case d.isFixMap(code):
|
||||
return int(code - def.FixMap), offset, nil
|
||||
case code == def.Map16:
|
||||
bs, offset, err := d.readSize2(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int(binary.BigEndian.Uint16(bs)), offset, nil
|
||||
case code == def.Map32:
|
||||
bs, offset, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int(binary.BigEndian.Uint32(bs)), offset, nil
|
||||
}
|
||||
|
||||
return 0, 0, d.errorTemplate(code, k)
|
||||
}
|
||||
|
||||
func (d *decoder) hasRequiredLeastMapSize(offset, length int) error {
|
||||
// minimum check (byte length)
|
||||
if len(d.data[offset:]) < length*2 {
|
||||
return errors.New("data length lacks to create map")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *decoder) asFixedMap(rv reflect.Value, offset int, l int) (int, bool, error) {
|
||||
t := rv.Type()
|
||||
|
||||
keyKind := t.Key().Kind()
|
||||
valueKind := t.Elem().Kind()
|
||||
|
||||
switch t {
|
||||
case typeMapStringInt:
|
||||
m := make(map[string]int, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asInt(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = int(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapStringUint:
|
||||
m := make(map[string]uint, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asUint(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = uint(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapStringFloat32:
|
||||
m := make(map[string]float32, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asFloat32(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapStringFloat64:
|
||||
m := make(map[string]float64, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asFloat64(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapStringBool:
|
||||
m := make(map[string]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asBool(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapStringString:
|
||||
m := make(map[string]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asString(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapStringInt8:
|
||||
m := make(map[string]int8, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asInt(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = int8(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapStringInt16:
|
||||
m := make(map[string]int16, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asInt(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = int16(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapStringInt32:
|
||||
m := make(map[string]int32, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asInt(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = int32(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapStringInt64:
|
||||
m := make(map[string]int64, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asInt(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapStringUint8:
|
||||
m := make(map[string]uint8, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asUint(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = uint8(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
case typeMapStringUint16:
|
||||
m := make(map[string]uint16, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asUint(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = uint16(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapStringUint32:
|
||||
m := make(map[string]uint32, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asUint(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = uint32(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapStringUint64:
|
||||
m := make(map[string]uint64, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asString(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asUint(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapIntString:
|
||||
m := make(map[int]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asInt(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asString(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[int(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapInt8String:
|
||||
m := make(map[int8]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asInt(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asString(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[int8(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapInt16String:
|
||||
m := make(map[int16]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asInt(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asString(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[int16(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapInt32String:
|
||||
m := make(map[int32]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asInt(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asString(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[int32(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapInt64String:
|
||||
m := make(map[int64]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asInt(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asString(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapIntBool:
|
||||
m := make(map[int]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asInt(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asBool(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[int(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapInt8Bool:
|
||||
m := make(map[int8]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asInt(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asBool(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[int8(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapInt16Bool:
|
||||
m := make(map[int16]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asInt(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asBool(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[int16(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapInt32Bool:
|
||||
m := make(map[int32]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asInt(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asBool(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[int32(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapInt64Bool:
|
||||
m := make(map[int64]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asInt(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asBool(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapUintString:
|
||||
m := make(map[uint]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asUint(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asString(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[uint(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapUint8String:
|
||||
m := make(map[uint8]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asUint(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asString(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[uint8(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapUint16String:
|
||||
m := make(map[uint16]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asUint(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asString(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[uint16(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapUint32String:
|
||||
m := make(map[uint32]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asUint(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asString(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[uint32(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapUint64String:
|
||||
m := make(map[uint64]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asUint(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asString(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapUintBool:
|
||||
m := make(map[uint]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asUint(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asBool(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[uint(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapUint8Bool:
|
||||
m := make(map[uint8]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asUint(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asBool(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[uint8(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapUint16Bool:
|
||||
m := make(map[uint16]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asUint(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asBool(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[uint16(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapUint32Bool:
|
||||
m := make(map[uint32]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asUint(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asBool(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[uint32(k)] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapUint64Bool:
|
||||
m := make(map[uint64]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asUint(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asBool(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapFloat32String:
|
||||
m := make(map[float32]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asFloat32(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asString(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapFloat64String:
|
||||
m := make(map[float64]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asFloat64(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asString(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapFloat32Bool:
|
||||
m := make(map[float32]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asFloat32(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asBool(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
|
||||
case typeMapFloat64Bool:
|
||||
m := make(map[float64]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
k, o, err := d.asFloat64(offset, keyKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
v, o, err := d.asBool(o, valueKind)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
m[k] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(m))
|
||||
return offset, true, nil
|
||||
}
|
||||
|
||||
return offset, false, nil
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package decoding
|
||||
|
||||
import "github.com/shamaton/msgpack/v2/def"
|
||||
|
||||
func (d *decoder) isCodeNil(v byte) bool {
|
||||
return def.Nil == v
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/shamaton/msgpack/v2/def"
|
||||
)
|
||||
|
||||
func (d *decoder) readSize1(index int) (byte, int, error) {
|
||||
rb := def.Byte1
|
||||
if len(d.data) < index+rb {
|
||||
return 0, 0, errors.New("too short bytes")
|
||||
}
|
||||
return d.data[index], index + rb, nil
|
||||
}
|
||||
|
||||
func (d *decoder) readSize2(index int) ([]byte, int, error) {
|
||||
return d.readSizeN(index, def.Byte2)
|
||||
}
|
||||
|
||||
func (d *decoder) readSize4(index int) ([]byte, int, error) {
|
||||
return d.readSizeN(index, def.Byte4)
|
||||
}
|
||||
|
||||
func (d *decoder) readSize8(index int) ([]byte, int, error) {
|
||||
return d.readSizeN(index, def.Byte8)
|
||||
}
|
||||
|
||||
func (d *decoder) readSizeN(index, n int) ([]byte, int, error) {
|
||||
if len(d.data) < index+n {
|
||||
return emptyBytes, 0, errors.New("too short bytes")
|
||||
}
|
||||
return d.data[index : index+n], index + n, nil
|
||||
}
|
||||
+258
@@ -0,0 +1,258 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"reflect"
|
||||
|
||||
"github.com/shamaton/msgpack/v2/def"
|
||||
)
|
||||
|
||||
var (
|
||||
typeIntSlice = reflect.TypeOf([]int{})
|
||||
typeInt8Slice = reflect.TypeOf([]int8{})
|
||||
typeInt16Slice = reflect.TypeOf([]int16{})
|
||||
typeInt32Slice = reflect.TypeOf([]int32{})
|
||||
typeInt64Slice = reflect.TypeOf([]int64{})
|
||||
|
||||
typeUintSlice = reflect.TypeOf([]uint{})
|
||||
typeUint8Slice = reflect.TypeOf([]uint8{})
|
||||
typeUint16Slice = reflect.TypeOf([]uint16{})
|
||||
typeUint32Slice = reflect.TypeOf([]uint32{})
|
||||
typeUint64Slice = reflect.TypeOf([]uint64{})
|
||||
|
||||
typeFloat32Slice = reflect.TypeOf([]float32{})
|
||||
typeFloat64Slice = reflect.TypeOf([]float64{})
|
||||
|
||||
typeStringSlice = reflect.TypeOf([]string{})
|
||||
|
||||
typeBoolSlice = reflect.TypeOf([]bool{})
|
||||
)
|
||||
|
||||
func (d *decoder) isFixSlice(v byte) bool {
|
||||
return def.FixArray <= v && v <= def.FixArray+0x0f
|
||||
}
|
||||
|
||||
func (d *decoder) sliceLength(offset int, k reflect.Kind) (int, int, error) {
|
||||
code, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case d.isFixSlice(code):
|
||||
return int(code - def.FixArray), offset, nil
|
||||
case code == def.Array16:
|
||||
bs, offset, err := d.readSize2(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int(binary.BigEndian.Uint16(bs)), offset, nil
|
||||
case code == def.Array32:
|
||||
bs, offset, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int(binary.BigEndian.Uint32(bs)), offset, nil
|
||||
}
|
||||
return 0, 0, d.errorTemplate(code, k)
|
||||
}
|
||||
|
||||
func (d *decoder) hasRequiredLeastSliceSize(offset, length int) error {
|
||||
// minimum check (byte length)
|
||||
if len(d.data[offset:]) < length {
|
||||
return errors.New("data length lacks to create map")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *decoder) asFixedSlice(rv reflect.Value, offset int, l int) (int, bool, error) {
|
||||
t := rv.Type()
|
||||
k := t.Elem().Kind()
|
||||
|
||||
switch t {
|
||||
case typeIntSlice:
|
||||
sli := make([]int, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asInt(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = int(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
|
||||
case typeUintSlice:
|
||||
sli := make([]uint, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asUint(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = uint(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
|
||||
case typeStringSlice:
|
||||
sli := make([]string, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asString(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
|
||||
case typeBoolSlice:
|
||||
sli := make([]bool, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asBool(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
|
||||
case typeFloat32Slice:
|
||||
sli := make([]float32, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asFloat32(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
|
||||
case typeFloat64Slice:
|
||||
sli := make([]float64, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asFloat64(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
|
||||
case typeInt8Slice:
|
||||
sli := make([]int8, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asInt(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = int8(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
|
||||
case typeInt16Slice:
|
||||
sli := make([]int16, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asInt(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = int16(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
|
||||
case typeInt32Slice:
|
||||
sli := make([]int32, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asInt(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = int32(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
|
||||
case typeInt64Slice:
|
||||
sli := make([]int64, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asInt(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
|
||||
case typeUint8Slice:
|
||||
sli := make([]uint8, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asUint(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = uint8(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
|
||||
case typeUint16Slice:
|
||||
sli := make([]uint16, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asUint(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = uint16(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
|
||||
case typeUint32Slice:
|
||||
sli := make([]uint32, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asUint(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = uint32(v)
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
|
||||
case typeUint64Slice:
|
||||
sli := make([]uint64, l)
|
||||
for i := range sli {
|
||||
v, o, err := d.asUint(offset, k)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
sli[i] = v
|
||||
offset = o
|
||||
}
|
||||
rv.Set(reflect.ValueOf(sli))
|
||||
return offset, true, nil
|
||||
}
|
||||
|
||||
return offset, false, nil
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
|
||||
"github.com/shamaton/msgpack/v2/def"
|
||||
)
|
||||
|
||||
var emptyString = ""
|
||||
var emptyBytes = []byte{}
|
||||
|
||||
func (d *decoder) isCodeString(code byte) bool {
|
||||
return d.isFixString(code) || code == def.Str8 || code == def.Str16 || code == def.Str32
|
||||
}
|
||||
|
||||
func (d *decoder) isFixString(v byte) bool {
|
||||
return def.FixStr <= v && v <= def.FixStr+0x1f
|
||||
}
|
||||
|
||||
func (d *decoder) stringByteLength(offset int, k reflect.Kind) (int, int, error) {
|
||||
code, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
if def.FixStr <= code && code <= def.FixStr+0x1f {
|
||||
l := int(code - def.FixStr)
|
||||
return l, offset, nil
|
||||
} else if code == def.Str8 {
|
||||
b, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int(b), offset, nil
|
||||
} else if code == def.Str16 {
|
||||
b, offset, err := d.readSize2(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int(binary.BigEndian.Uint16(b)), offset, nil
|
||||
} else if code == def.Str32 {
|
||||
b, offset, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return int(binary.BigEndian.Uint32(b)), offset, nil
|
||||
} else if code == def.Nil {
|
||||
return 0, offset, nil
|
||||
}
|
||||
return 0, 0, d.errorTemplate(code, k)
|
||||
}
|
||||
|
||||
func (d *decoder) asString(offset int, k reflect.Kind) (string, int, error) {
|
||||
bs, offset, err := d.asStringByte(offset, k)
|
||||
if err != nil {
|
||||
return emptyString, 0, err
|
||||
}
|
||||
return string(bs), offset, nil
|
||||
}
|
||||
|
||||
func (d *decoder) asStringByte(offset int, k reflect.Kind) ([]byte, int, error) {
|
||||
l, offset, err := d.stringByteLength(offset, k)
|
||||
if err != nil {
|
||||
return emptyBytes, 0, err
|
||||
}
|
||||
|
||||
return d.asStringByteByLength(offset, l, k)
|
||||
}
|
||||
|
||||
func (d *decoder) asStringByteByLength(offset int, l int, k reflect.Kind) ([]byte, int, error) {
|
||||
if l < 1 {
|
||||
return emptyBytes, offset, nil
|
||||
}
|
||||
|
||||
return d.readSizeN(offset, l)
|
||||
}
|
||||
+315
@@ -0,0 +1,315 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"github.com/shamaton/msgpack/v2/def"
|
||||
)
|
||||
|
||||
type structCacheTypeMap struct {
|
||||
keys [][]byte
|
||||
indexes []int
|
||||
}
|
||||
|
||||
type structCacheTypeArray struct {
|
||||
m []int
|
||||
}
|
||||
|
||||
// struct cache map
|
||||
var mapSCTM = sync.Map{}
|
||||
var mapSCTA = sync.Map{}
|
||||
|
||||
func (d *decoder) setStruct(rv reflect.Value, offset int, k reflect.Kind) (int, error) {
|
||||
/*
|
||||
if d.isDateTime(offset) {
|
||||
dt, offset, err := d.asDateTime(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rv.Set(reflect.ValueOf(dt))
|
||||
return offset, nil
|
||||
}
|
||||
*/
|
||||
|
||||
for i := range extCoders {
|
||||
if extCoders[i].IsType(offset, &d.data) {
|
||||
v, offset, err := extCoders[i].AsValue(offset, k, &d.data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// Validate that the receptacle is of the right value type.
|
||||
if rv.Type() == reflect.TypeOf(v) {
|
||||
rv.Set(reflect.ValueOf(v))
|
||||
return offset, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if d.asArray {
|
||||
return d.setStructFromArray(rv, offset, k)
|
||||
}
|
||||
return d.setStructFromMap(rv, offset, k)
|
||||
}
|
||||
|
||||
func (d *decoder) setStructFromArray(rv reflect.Value, offset int, k reflect.Kind) (int, error) {
|
||||
// get length
|
||||
l, o, err := d.sliceLength(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err = d.hasRequiredLeastSliceSize(o, l); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// find or create reference
|
||||
var scta *structCacheTypeArray
|
||||
cache, findCache := mapSCTA.Load(rv.Type())
|
||||
if !findCache {
|
||||
scta = &structCacheTypeArray{}
|
||||
for i := 0; i < rv.NumField(); i++ {
|
||||
if ok, _ := d.CheckField(rv.Type().Field(i)); ok {
|
||||
scta.m = append(scta.m, i)
|
||||
}
|
||||
}
|
||||
mapSCTA.Store(rv.Type(), scta)
|
||||
} else {
|
||||
scta = cache.(*structCacheTypeArray)
|
||||
}
|
||||
// set value
|
||||
for i := 0; i < l; i++ {
|
||||
if i < len(scta.m) {
|
||||
o, err = d.decode(rv.Field(scta.m[i]), o)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
o, err = d.jumpOffset(o)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func (d *decoder) setStructFromMap(rv reflect.Value, offset int, k reflect.Kind) (int, error) {
|
||||
// get length
|
||||
l, o, err := d.mapLength(offset, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err = d.hasRequiredLeastMapSize(o, l); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var sctm *structCacheTypeMap
|
||||
cache, cacheFind := mapSCTM.Load(rv.Type())
|
||||
if !cacheFind {
|
||||
sctm = &structCacheTypeMap{}
|
||||
for i := 0; i < rv.NumField(); i++ {
|
||||
if ok, name := d.CheckField(rv.Type().Field(i)); ok {
|
||||
sctm.keys = append(sctm.keys, []byte(name))
|
||||
sctm.indexes = append(sctm.indexes, i)
|
||||
}
|
||||
}
|
||||
mapSCTM.Store(rv.Type(), sctm)
|
||||
} else {
|
||||
sctm = cache.(*structCacheTypeMap)
|
||||
}
|
||||
|
||||
for i := 0; i < l; i++ {
|
||||
dataKey, o2, err := d.asStringByte(o, k)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
fieldIndex := -1
|
||||
for keyIndex, keyBytes := range sctm.keys {
|
||||
if len(keyBytes) != len(dataKey) {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldIndex = sctm.indexes[keyIndex]
|
||||
for dataIndex := range dataKey {
|
||||
if dataKey[dataIndex] != keyBytes[dataIndex] {
|
||||
fieldIndex = -1
|
||||
break
|
||||
}
|
||||
}
|
||||
if fieldIndex >= 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if fieldIndex >= 0 {
|
||||
o2, err = d.decode(rv.Field(fieldIndex), o2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
o2, err = d.jumpOffset(o2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
o = o2
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func (d *decoder) jumpOffset(offset int) (int, error) {
|
||||
code, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case code == def.True, code == def.False, code == def.Nil:
|
||||
// do nothing
|
||||
|
||||
case d.isPositiveFixNum(code) || d.isNegativeFixNum(code):
|
||||
// do nothing
|
||||
case code == def.Uint8, code == def.Int8:
|
||||
offset += def.Byte1
|
||||
case code == def.Uint16, code == def.Int16:
|
||||
offset += def.Byte2
|
||||
case code == def.Uint32, code == def.Int32, code == def.Float32:
|
||||
offset += def.Byte4
|
||||
case code == def.Uint64, code == def.Int64, code == def.Float64:
|
||||
offset += def.Byte8
|
||||
|
||||
case d.isFixString(code):
|
||||
offset += int(code - def.FixStr)
|
||||
case code == def.Str8, code == def.Bin8:
|
||||
b, o, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
o += int(b)
|
||||
offset = o
|
||||
case code == def.Str16, code == def.Bin16:
|
||||
bs, o, err := d.readSize2(offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
o += int(binary.BigEndian.Uint16(bs))
|
||||
offset = o
|
||||
case code == def.Str32, code == def.Bin32:
|
||||
bs, o, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
o += int(binary.BigEndian.Uint32(bs))
|
||||
offset = o
|
||||
|
||||
case d.isFixSlice(code):
|
||||
l := int(code - def.FixArray)
|
||||
for i := 0; i < l; i++ {
|
||||
offset, err = d.jumpOffset(offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
case code == def.Array16:
|
||||
bs, o, err := d.readSize2(offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
l := int(binary.BigEndian.Uint16(bs))
|
||||
for i := 0; i < l; i++ {
|
||||
o, err = d.jumpOffset(o)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
offset = o
|
||||
case code == def.Array32:
|
||||
bs, o, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
l := int(binary.BigEndian.Uint32(bs))
|
||||
for i := 0; i < l; i++ {
|
||||
o, err = d.jumpOffset(o)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
offset = o
|
||||
|
||||
case d.isFixMap(code):
|
||||
l := int(code - def.FixMap)
|
||||
for i := 0; i < l*2; i++ {
|
||||
offset, err = d.jumpOffset(offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
case code == def.Map16:
|
||||
bs, o, err := d.readSize2(offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
l := int(binary.BigEndian.Uint16(bs))
|
||||
for i := 0; i < l*2; i++ {
|
||||
o, err = d.jumpOffset(o)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
offset = o
|
||||
case code == def.Map32:
|
||||
bs, o, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
l := int(binary.BigEndian.Uint32(bs))
|
||||
for i := 0; i < l*2; i++ {
|
||||
o, err = d.jumpOffset(o)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
offset = o
|
||||
|
||||
case code == def.Fixext1:
|
||||
offset += def.Byte1 + def.Byte1
|
||||
case code == def.Fixext2:
|
||||
offset += def.Byte1 + def.Byte2
|
||||
case code == def.Fixext4:
|
||||
offset += def.Byte1 + def.Byte4
|
||||
case code == def.Fixext8:
|
||||
offset += def.Byte1 + def.Byte8
|
||||
case code == def.Fixext16:
|
||||
offset += def.Byte1 + def.Byte16
|
||||
|
||||
case code == def.Ext8:
|
||||
b, o, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
o += def.Byte1 + int(b)
|
||||
offset = o
|
||||
case code == def.Ext16:
|
||||
bs, o, err := d.readSize2(offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
o += def.Byte1 + int(binary.BigEndian.Uint16(bs))
|
||||
offset = o
|
||||
case code == def.Ext32:
|
||||
bs, o, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
o += def.Byte1 + int(binary.BigEndian.Uint32(bs))
|
||||
offset = o
|
||||
|
||||
}
|
||||
return offset, nil
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package decoding
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
|
||||
"github.com/shamaton/msgpack/v2/def"
|
||||
)
|
||||
|
||||
func (d *decoder) asUint(offset int, k reflect.Kind) (uint64, int, error) {
|
||||
|
||||
code, _, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case d.isPositiveFixNum(code):
|
||||
b, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return uint64(b), offset, nil
|
||||
|
||||
case d.isNegativeFixNum(code):
|
||||
b, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return uint64(int8(b)), offset, nil
|
||||
|
||||
case code == def.Uint8:
|
||||
offset++
|
||||
b, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return uint64(uint8(b)), offset, nil
|
||||
|
||||
case code == def.Int8:
|
||||
offset++
|
||||
b, offset, err := d.readSize1(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return uint64(int8(b)), offset, nil
|
||||
|
||||
case code == def.Uint16:
|
||||
offset++
|
||||
bs, offset, err := d.readSize2(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
v := binary.BigEndian.Uint16(bs)
|
||||
return uint64(v), offset, nil
|
||||
|
||||
case code == def.Int16:
|
||||
offset++
|
||||
bs, offset, err := d.readSize2(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
v := int16(binary.BigEndian.Uint16(bs))
|
||||
return uint64(v), offset, nil
|
||||
|
||||
case code == def.Uint32:
|
||||
offset++
|
||||
bs, offset, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
v := binary.BigEndian.Uint32(bs)
|
||||
return uint64(v), offset, nil
|
||||
|
||||
case code == def.Int32:
|
||||
offset++
|
||||
bs, offset, err := d.readSize4(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
v := int32(binary.BigEndian.Uint32(bs))
|
||||
return uint64(v), offset, nil
|
||||
|
||||
case code == def.Uint64:
|
||||
offset++
|
||||
bs, offset, err := d.readSize8(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return binary.BigEndian.Uint64(bs), offset, nil
|
||||
|
||||
case code == def.Int64:
|
||||
offset++
|
||||
bs, offset, err := d.readSize8(offset)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return binary.BigEndian.Uint64(bs), offset, nil
|
||||
|
||||
case code == def.Nil:
|
||||
offset++
|
||||
return 0, offset, nil
|
||||
}
|
||||
|
||||
return 0, 0, d.errorTemplate(code, k)
|
||||
}
|
||||
Reference in New Issue
Block a user