|
@@ -6,12 +6,14 @@ package gocql
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
"bytes"
|
|
"bytes"
|
|
|
|
|
+ "encoding/binary"
|
|
|
"fmt"
|
|
"fmt"
|
|
|
"math"
|
|
"math"
|
|
|
"math/big"
|
|
"math/big"
|
|
|
"reflect"
|
|
"reflect"
|
|
|
- "speter.net/go/exp/math/dec/inf"
|
|
|
|
|
"time"
|
|
"time"
|
|
|
|
|
+
|
|
|
|
|
+ "speter.net/go/exp/math/dec/inf"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
var (
|
|
@@ -59,6 +61,8 @@ func Marshal(info *TypeInfo, value interface{}) ([]byte, error) {
|
|
|
return marshalMap(info, value)
|
|
return marshalMap(info, value)
|
|
|
case TypeUUID, TypeTimeUUID:
|
|
case TypeUUID, TypeTimeUUID:
|
|
|
return marshalUUID(info, value)
|
|
return marshalUUID(info, value)
|
|
|
|
|
+ case TypeVarint:
|
|
|
|
|
+ return marshalVarint(info, value)
|
|
|
}
|
|
}
|
|
|
// TODO(tux21b): add the remaining types
|
|
// TODO(tux21b): add the remaining types
|
|
|
return nil, fmt.Errorf("can not marshal %T into %s", value, info)
|
|
return nil, fmt.Errorf("can not marshal %T into %s", value, info)
|
|
@@ -80,6 +84,8 @@ func Unmarshal(info *TypeInfo, data []byte, value interface{}) error {
|
|
|
return unmarshalInt(info, data, value)
|
|
return unmarshalInt(info, data, value)
|
|
|
case TypeBigInt, TypeCounter:
|
|
case TypeBigInt, TypeCounter:
|
|
|
return unmarshalBigInt(info, data, value)
|
|
return unmarshalBigInt(info, data, value)
|
|
|
|
|
+ case TypeVarint:
|
|
|
|
|
+ return unmarshalVarint(info, data, value)
|
|
|
case TypeFloat:
|
|
case TypeFloat:
|
|
|
return unmarshalFloat(info, data, value)
|
|
return unmarshalFloat(info, data, value)
|
|
|
case TypeDouble:
|
|
case TypeDouble:
|
|
@@ -229,117 +235,6 @@ func encInt(x int32) []byte {
|
|
|
return []byte{byte(x >> 24), byte(x >> 16), byte(x >> 8), byte(x)}
|
|
return []byte{byte(x >> 24), byte(x >> 16), byte(x >> 8), byte(x)}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func unmarshalInt(info *TypeInfo, data []byte, value interface{}) error {
|
|
|
|
|
- switch v := value.(type) {
|
|
|
|
|
- case Unmarshaler:
|
|
|
|
|
- return v.UnmarshalCQL(info, data)
|
|
|
|
|
- case *int:
|
|
|
|
|
- *v = int(decInt(data))
|
|
|
|
|
- return nil
|
|
|
|
|
- case *uint:
|
|
|
|
|
- x := decInt(data)
|
|
|
|
|
- if x < 0 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
- }
|
|
|
|
|
- *v = uint(x)
|
|
|
|
|
- return nil
|
|
|
|
|
- case *int64:
|
|
|
|
|
- *v = int64(decInt(data))
|
|
|
|
|
- return nil
|
|
|
|
|
- case *uint64:
|
|
|
|
|
- x := decInt(data)
|
|
|
|
|
- if x < 0 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
- }
|
|
|
|
|
- *v = uint64(x)
|
|
|
|
|
- return nil
|
|
|
|
|
- case *int32:
|
|
|
|
|
- *v = decInt(data)
|
|
|
|
|
- return nil
|
|
|
|
|
- case *uint32:
|
|
|
|
|
- x := decInt(data)
|
|
|
|
|
- if x < 0 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
- }
|
|
|
|
|
- *v = uint32(x)
|
|
|
|
|
- return nil
|
|
|
|
|
- case *int16:
|
|
|
|
|
- x := decInt(data)
|
|
|
|
|
- if x < math.MinInt16 || x > math.MaxInt16 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
- }
|
|
|
|
|
- *v = int16(x)
|
|
|
|
|
- return nil
|
|
|
|
|
- case *uint16:
|
|
|
|
|
- x := decInt(data)
|
|
|
|
|
- if x < 0 || x > math.MaxUint16 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
- }
|
|
|
|
|
- *v = uint16(x)
|
|
|
|
|
- return nil
|
|
|
|
|
- case *int8:
|
|
|
|
|
- x := decInt(data)
|
|
|
|
|
- if x < math.MinInt8 || x > math.MaxInt8 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
- }
|
|
|
|
|
- *v = int8(x)
|
|
|
|
|
- return nil
|
|
|
|
|
- case *uint8:
|
|
|
|
|
- x := decInt(data)
|
|
|
|
|
- if x < 0 || x > math.MaxUint8 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
- }
|
|
|
|
|
- *v = uint8(x)
|
|
|
|
|
- return nil
|
|
|
|
|
- }
|
|
|
|
|
- rv := reflect.ValueOf(value)
|
|
|
|
|
- if rv.Kind() != reflect.Ptr {
|
|
|
|
|
- return unmarshalErrorf("can not unmarshal into non-pointer %T", value)
|
|
|
|
|
- }
|
|
|
|
|
- rv = rv.Elem()
|
|
|
|
|
- switch rv.Type().Kind() {
|
|
|
|
|
- case reflect.Int, reflect.Int64, reflect.Int32:
|
|
|
|
|
- rv.SetInt(int64(decInt(data)))
|
|
|
|
|
- return nil
|
|
|
|
|
- case reflect.Int16:
|
|
|
|
|
- x := decInt(data)
|
|
|
|
|
- if x < math.MinInt16 || x > math.MaxInt16 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
- }
|
|
|
|
|
- rv.SetInt(int64(x))
|
|
|
|
|
- return nil
|
|
|
|
|
- case reflect.Int8:
|
|
|
|
|
- x := decInt(data)
|
|
|
|
|
- if x < math.MinInt8 || x > math.MaxInt8 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
- }
|
|
|
|
|
- rv.SetInt(int64(x))
|
|
|
|
|
- return nil
|
|
|
|
|
- case reflect.Uint, reflect.Uint64, reflect.Uint32:
|
|
|
|
|
- x := decInt(data)
|
|
|
|
|
- if x < 0 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
- }
|
|
|
|
|
- rv.SetUint(uint64(x))
|
|
|
|
|
- return nil
|
|
|
|
|
- case reflect.Uint16:
|
|
|
|
|
- x := decInt(data)
|
|
|
|
|
- if x < 0 || x > math.MaxUint16 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
- }
|
|
|
|
|
- rv.SetUint(uint64(x))
|
|
|
|
|
- return nil
|
|
|
|
|
- case reflect.Uint8:
|
|
|
|
|
- x := decInt(data)
|
|
|
|
|
- if x < 0 || x > math.MaxUint8 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
- }
|
|
|
|
|
- rv.SetUint(uint64(x))
|
|
|
|
|
- return nil
|
|
|
|
|
- }
|
|
|
|
|
- return unmarshalErrorf("can not unmarshal %s into %T", info, value)
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
func decInt(x []byte) int32 {
|
|
func decInt(x []byte) int32 {
|
|
|
if len(x) != 4 {
|
|
if len(x) != 4 {
|
|
|
return 0
|
|
return 0
|
|
@@ -377,6 +272,8 @@ func marshalBigInt(info *TypeInfo, value interface{}) ([]byte, error) {
|
|
|
return encBigInt(int64(v)), nil
|
|
return encBigInt(int64(v)), nil
|
|
|
case uint8:
|
|
case uint8:
|
|
|
return encBigInt(int64(v)), nil
|
|
return encBigInt(int64(v)), nil
|
|
|
|
|
+ case *big.Int:
|
|
|
|
|
+ return encBigInt2C(v), nil
|
|
|
}
|
|
}
|
|
|
rv := reflect.ValueOf(value)
|
|
rv := reflect.ValueOf(value)
|
|
|
switch rv.Type().Kind() {
|
|
switch rv.Type().Kind() {
|
|
@@ -400,148 +297,221 @@ func encBigInt(x int64) []byte {
|
|
|
byte(x >> 24), byte(x >> 16), byte(x >> 8), byte(x)}
|
|
byte(x >> 24), byte(x >> 16), byte(x >> 8), byte(x)}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func bytesToInt64(data []byte) (ret int64) {
|
|
|
|
|
+ for i := range data {
|
|
|
|
|
+ ret |= int64(data[i]) << (8 * uint(len(data)-i-1))
|
|
|
|
|
+ }
|
|
|
|
|
+ return ret
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func unmarshalBigInt(info *TypeInfo, data []byte, value interface{}) error {
|
|
func unmarshalBigInt(info *TypeInfo, data []byte, value interface{}) error {
|
|
|
|
|
+ return unmarshalIntlike(info, decBigInt(data), data, value)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func unmarshalInt(info *TypeInfo, data []byte, value interface{}) error {
|
|
|
|
|
+ return unmarshalIntlike(info, int64(decInt(data)), data, value)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func unmarshalVarint(info *TypeInfo, data []byte, value interface{}) error {
|
|
|
|
|
+ switch value.(type) {
|
|
|
|
|
+ case *big.Int, **big.Int:
|
|
|
|
|
+ return unmarshalIntlike(info, 0, data, value)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if len(data) > 8 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: varint value %v out of range for %T (use big.Int)", data, value)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int64Val := bytesToInt64(data)
|
|
|
|
|
+ if len(data) < 8 && data[0]&0x80 > 0 {
|
|
|
|
|
+ int64Val -= (1 << uint(len(data)*8))
|
|
|
|
|
+ }
|
|
|
|
|
+ return unmarshalIntlike(info, int64Val, data, value)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func marshalVarint(info *TypeInfo, value interface{}) ([]byte, error) {
|
|
|
|
|
+ var (
|
|
|
|
|
+ retBytes []byte
|
|
|
|
|
+ err error
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ switch v := value.(type) {
|
|
|
|
|
+ case uint64:
|
|
|
|
|
+ if v > uint64(math.MaxInt64) {
|
|
|
|
|
+ retBytes = make([]byte, 9)
|
|
|
|
|
+ binary.BigEndian.PutUint64(retBytes[1:], v)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ retBytes = make([]byte, 8)
|
|
|
|
|
+ binary.BigEndian.PutUint64(retBytes, v)
|
|
|
|
|
+ }
|
|
|
|
|
+ default:
|
|
|
|
|
+ retBytes, err = marshalBigInt(info, value)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if err == nil {
|
|
|
|
|
+ // trim down to most significant byte
|
|
|
|
|
+ i := 0
|
|
|
|
|
+ for ; i < len(retBytes)-1; i++ {
|
|
|
|
|
+ b0 := retBytes[i]
|
|
|
|
|
+ if b0 != 0 && b0 != 0xFF {
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ b1 := retBytes[i+1]
|
|
|
|
|
+ if b0 == 0 && b1 != 0 {
|
|
|
|
|
+ if b1&0x80 == 0 {
|
|
|
|
|
+ i++
|
|
|
|
|
+ }
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if b0 == 0xFF && b1 != 0xFF {
|
|
|
|
|
+ if b1&0x80 > 0 {
|
|
|
|
|
+ i++
|
|
|
|
|
+ }
|
|
|
|
|
+ break
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ retBytes = retBytes[i:]
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return retBytes, err
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func unmarshalIntlike(info *TypeInfo, int64Val int64, data []byte, value interface{}) error {
|
|
|
switch v := value.(type) {
|
|
switch v := value.(type) {
|
|
|
- case Unmarshaler:
|
|
|
|
|
- return v.UnmarshalCQL(info, data)
|
|
|
|
|
case *int:
|
|
case *int:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if ^uint(0) == math.MaxUint32 && (x < math.MinInt32 || x > math.MaxInt32) {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if ^uint(0) == math.MaxUint32 && (int64Val < math.MinInt32 || int64Val > math.MaxInt32) {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range for %T", int64Val, *v)
|
|
|
}
|
|
}
|
|
|
- *v = int(x)
|
|
|
|
|
|
|
+ *v = int(int64Val)
|
|
|
return nil
|
|
return nil
|
|
|
case *uint:
|
|
case *uint:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < 0 || (^uint(0) == math.MaxUint32 && x > math.MaxUint32) {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < 0 || (^uint(0) == math.MaxUint32 && int64Val > math.MaxUint32) {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range for %T", int64Val, *v)
|
|
|
}
|
|
}
|
|
|
- *v = uint(x)
|
|
|
|
|
|
|
+ *v = uint(int64Val)
|
|
|
return nil
|
|
return nil
|
|
|
case *int64:
|
|
case *int64:
|
|
|
- *v = decBigInt(data)
|
|
|
|
|
|
|
+ *v = int64Val
|
|
|
return nil
|
|
return nil
|
|
|
case *uint64:
|
|
case *uint64:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < 0 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < 0 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range for %T", int64Val, *v)
|
|
|
}
|
|
}
|
|
|
- *v = uint64(x)
|
|
|
|
|
|
|
+ *v = uint64(int64Val)
|
|
|
return nil
|
|
return nil
|
|
|
case *int32:
|
|
case *int32:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < math.MinInt32 || x > math.MaxInt32 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < math.MinInt32 || int64Val > math.MaxInt32 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range for %T", int64Val, *v)
|
|
|
}
|
|
}
|
|
|
- *v = int32(x)
|
|
|
|
|
|
|
+ *v = int32(int64Val)
|
|
|
return nil
|
|
return nil
|
|
|
case *uint32:
|
|
case *uint32:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < 0 || x > math.MaxUint32 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < 0 || int64Val > math.MaxUint32 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range for %T", int64Val, *v)
|
|
|
}
|
|
}
|
|
|
- *v = uint32(x)
|
|
|
|
|
|
|
+ *v = uint32(int64Val)
|
|
|
return nil
|
|
return nil
|
|
|
case *int16:
|
|
case *int16:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < math.MinInt16 || x > math.MaxInt16 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < math.MinInt16 || int64Val > math.MaxInt16 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range for %T", int64Val, *v)
|
|
|
}
|
|
}
|
|
|
- *v = int16(x)
|
|
|
|
|
|
|
+ *v = int16(int64Val)
|
|
|
return nil
|
|
return nil
|
|
|
case *uint16:
|
|
case *uint16:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < 0 || x > math.MaxUint16 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < 0 || int64Val > math.MaxUint16 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range for %T", int64Val, *v)
|
|
|
}
|
|
}
|
|
|
- *v = uint16(x)
|
|
|
|
|
|
|
+ *v = uint16(int64Val)
|
|
|
return nil
|
|
return nil
|
|
|
case *int8:
|
|
case *int8:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < math.MinInt8 || x > math.MaxInt8 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < math.MinInt8 || int64Val > math.MaxInt8 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range for %T", int64Val, *v)
|
|
|
}
|
|
}
|
|
|
- *v = int8(x)
|
|
|
|
|
|
|
+ *v = int8(int64Val)
|
|
|
return nil
|
|
return nil
|
|
|
case *uint8:
|
|
case *uint8:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < 0 || x > math.MaxUint8 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < 0 || int64Val > math.MaxUint8 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range for %T", int64Val, *v)
|
|
|
|
|
+ }
|
|
|
|
|
+ *v = uint8(int64Val)
|
|
|
|
|
+ return nil
|
|
|
|
|
+ case *big.Int:
|
|
|
|
|
+ decBigInt2C(data, v)
|
|
|
|
|
+ return nil
|
|
|
|
|
+ case **big.Int:
|
|
|
|
|
+ if len(data) == 0 {
|
|
|
|
|
+ *v = nil
|
|
|
|
|
+ } else {
|
|
|
|
|
+ *v = decBigInt2C(data, nil)
|
|
|
}
|
|
}
|
|
|
- *v = uint8(x)
|
|
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
rv := reflect.ValueOf(value)
|
|
rv := reflect.ValueOf(value)
|
|
|
if rv.Kind() != reflect.Ptr {
|
|
if rv.Kind() != reflect.Ptr {
|
|
|
return unmarshalErrorf("can not unmarshal into non-pointer %T", value)
|
|
return unmarshalErrorf("can not unmarshal into non-pointer %T", value)
|
|
|
}
|
|
}
|
|
|
rv = rv.Elem()
|
|
rv = rv.Elem()
|
|
|
|
|
+
|
|
|
switch rv.Type().Kind() {
|
|
switch rv.Type().Kind() {
|
|
|
case reflect.Int:
|
|
case reflect.Int:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if ^uint(0) == math.MaxUint32 && (x < math.MinInt32 || x > math.MaxInt32) {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if ^uint(0) == math.MaxUint32 && (int64Val < math.MinInt32 || int64Val > math.MaxInt32) {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range", int64Val)
|
|
|
}
|
|
}
|
|
|
- rv.SetInt(x)
|
|
|
|
|
|
|
+ rv.SetInt(int64Val)
|
|
|
return nil
|
|
return nil
|
|
|
case reflect.Int64:
|
|
case reflect.Int64:
|
|
|
- rv.SetInt(decBigInt(data))
|
|
|
|
|
|
|
+ rv.SetInt(int64Val)
|
|
|
return nil
|
|
return nil
|
|
|
case reflect.Int32:
|
|
case reflect.Int32:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < math.MinInt32 || x > math.MaxInt32 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < math.MinInt32 || int64Val > math.MaxInt32 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range", int64Val)
|
|
|
}
|
|
}
|
|
|
- rv.SetInt(x)
|
|
|
|
|
|
|
+ rv.SetInt(int64Val)
|
|
|
return nil
|
|
return nil
|
|
|
case reflect.Int16:
|
|
case reflect.Int16:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < math.MinInt16 || x > math.MaxInt16 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < math.MinInt16 || int64Val > math.MaxInt16 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range", int64Val)
|
|
|
}
|
|
}
|
|
|
- rv.SetInt(x)
|
|
|
|
|
|
|
+ rv.SetInt(int64Val)
|
|
|
return nil
|
|
return nil
|
|
|
case reflect.Int8:
|
|
case reflect.Int8:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < math.MinInt8 || x > math.MaxInt8 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < math.MinInt8 || int64Val > math.MaxInt8 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range", int64Val)
|
|
|
}
|
|
}
|
|
|
- rv.SetInt(x)
|
|
|
|
|
|
|
+ rv.SetInt(int64Val)
|
|
|
return nil
|
|
return nil
|
|
|
case reflect.Uint:
|
|
case reflect.Uint:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < 0 || (^uint(0) == math.MaxUint32 && x > math.MaxUint32) {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < 0 || (^uint(0) == math.MaxUint32 && int64Val > math.MaxUint32) {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range", int64Val)
|
|
|
}
|
|
}
|
|
|
- rv.SetUint(uint64(x))
|
|
|
|
|
|
|
+ rv.SetUint(uint64(int64Val))
|
|
|
return nil
|
|
return nil
|
|
|
case reflect.Uint64:
|
|
case reflect.Uint64:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < 0 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < 0 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range", int64Val)
|
|
|
}
|
|
}
|
|
|
- rv.SetUint(uint64(x))
|
|
|
|
|
|
|
+ rv.SetUint(uint64(int64Val))
|
|
|
return nil
|
|
return nil
|
|
|
case reflect.Uint32:
|
|
case reflect.Uint32:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < 0 || x > math.MaxUint32 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < 0 || int64Val > math.MaxUint32 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range", int64Val)
|
|
|
}
|
|
}
|
|
|
- rv.SetUint(uint64(x))
|
|
|
|
|
|
|
+ rv.SetUint(uint64(int64Val))
|
|
|
return nil
|
|
return nil
|
|
|
case reflect.Uint16:
|
|
case reflect.Uint16:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < 0 || x > math.MaxUint16 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < 0 || int64Val > math.MaxUint16 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range", int64Val)
|
|
|
}
|
|
}
|
|
|
- rv.SetUint(uint64(x))
|
|
|
|
|
|
|
+ rv.SetUint(uint64(int64Val))
|
|
|
return nil
|
|
return nil
|
|
|
case reflect.Uint8:
|
|
case reflect.Uint8:
|
|
|
- x := decBigInt(data)
|
|
|
|
|
- if x < 0 || x > math.MaxUint8 {
|
|
|
|
|
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
|
|
|
|
|
|
|
+ if int64Val < 0 || int64Val > math.MaxUint8 {
|
|
|
|
|
+ return unmarshalErrorf("unmarshal int: value %d out of range", int64Val)
|
|
|
}
|
|
}
|
|
|
- rv.SetUint(uint64(x))
|
|
|
|
|
|
|
+ rv.SetUint(uint64(int64Val))
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
return unmarshalErrorf("can not unmarshal %s into %T", info, value)
|
|
return unmarshalErrorf("can not unmarshal %s into %T", info, value)
|
|
@@ -715,7 +685,7 @@ func unmarshalDecimal(info *TypeInfo, data []byte, value interface{}) error {
|
|
|
case **inf.Dec:
|
|
case **inf.Dec:
|
|
|
if len(data) > 4 {
|
|
if len(data) > 4 {
|
|
|
scale := decInt(data[0:4])
|
|
scale := decInt(data[0:4])
|
|
|
- unscaled := decBigInt2C(data[4:])
|
|
|
|
|
|
|
+ unscaled := decBigInt2C(data[4:], nil)
|
|
|
*v = inf.NewDecBig(unscaled, inf.Scale(scale))
|
|
*v = inf.NewDecBig(unscaled, inf.Scale(scale))
|
|
|
return nil
|
|
return nil
|
|
|
} else if len(data) == 0 {
|
|
} else if len(data) == 0 {
|
|
@@ -731,8 +701,11 @@ func unmarshalDecimal(info *TypeInfo, data []byte, value interface{}) error {
|
|
|
// decBigInt2C sets the value of n to the big-endian two's complement
|
|
// decBigInt2C sets the value of n to the big-endian two's complement
|
|
|
// value stored in the given data. If data[0]&80 != 0, the number
|
|
// value stored in the given data. If data[0]&80 != 0, the number
|
|
|
// is negative. If data is empty, the result will be 0.
|
|
// is negative. If data is empty, the result will be 0.
|
|
|
-func decBigInt2C(data []byte) *big.Int {
|
|
|
|
|
- n := new(big.Int).SetBytes(data)
|
|
|
|
|
|
|
+func decBigInt2C(data []byte, n *big.Int) *big.Int {
|
|
|
|
|
+ if n == nil {
|
|
|
|
|
+ n = new(big.Int)
|
|
|
|
|
+ }
|
|
|
|
|
+ n.SetBytes(data)
|
|
|
if len(data) > 0 && data[0]&0x80 > 0 {
|
|
if len(data) > 0 && data[0]&0x80 > 0 {
|
|
|
n.Sub(n, new(big.Int).Lsh(bigOne, uint(len(data))*8))
|
|
n.Sub(n, new(big.Int).Lsh(bigOne, uint(len(data))*8))
|
|
|
}
|
|
}
|
|
@@ -1167,6 +1140,8 @@ func (t Type) String() string {
|
|
|
return "map"
|
|
return "map"
|
|
|
case TypeSet:
|
|
case TypeSet:
|
|
|
return "set"
|
|
return "set"
|
|
|
|
|
+ case TypeVarint:
|
|
|
|
|
+ return "varint"
|
|
|
default:
|
|
default:
|
|
|
return "unknown"
|
|
return "unknown"
|
|
|
}
|
|
}
|