Skip to content

Commit

Permalink
Merge pull request #284 from illia-li/il/fix/marshal/smallint
Browse files Browse the repository at this point in the history
Fix marshal smallint
  • Loading branch information
dkropachev authored Oct 1, 2024
2 parents b4755c5 + f25f691 commit fe56500
Show file tree
Hide file tree
Showing 8 changed files with 938 additions and 362 deletions.
93 changes: 14 additions & 79 deletions marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

"gopkg.in/inf.v0"

"github.com/gocql/gocql/marshal/smallint"
"github.com/gocql/gocql/marshal/tinyint"
)

Expand Down Expand Up @@ -138,7 +139,7 @@ func Marshal(info TypeInfo, value interface{}) ([]byte, error) {
case TypeTinyInt:
return marshalTinyInt(value)
case TypeSmallInt:
return marshalSmallInt(info, value)
return marshalSmallInt(value)
case TypeInt:
return marshalInt(info, value)
case TypeBigInt, TypeCounter:
Expand Down Expand Up @@ -244,7 +245,7 @@ func Unmarshal(info TypeInfo, data []byte, value interface{}) error {
case TypeVarint:
return unmarshalVarint(info, data, value)
case TypeSmallInt:
return unmarshalSmallInt(info, data, value)
return unmarshalSmallInt(data, value)
case TypeTinyInt:
return unmarshalTinyInt(data, value)
case TypeFloat:
Expand Down Expand Up @@ -381,82 +382,12 @@ func unmarshalVarchar(info TypeInfo, data []byte, value interface{}) error {
return unmarshalErrorf("can not unmarshal %s into %T", info, value)
}

func marshalSmallInt(info TypeInfo, value interface{}) ([]byte, error) {
switch v := value.(type) {
case Marshaler:
return v.MarshalCQL(info)
case unsetColumn:
return nil, nil
case int16:
return encShort(v), nil
case uint16:
return encShort(int16(v)), nil
case int8:
return encShort(int16(v)), nil
case uint8:
return encShort(int16(v)), nil
case int:
if v > math.MaxInt16 || v < math.MinInt16 {
return nil, marshalErrorf("marshal smallint: value %d out of range", v)
}
return encShort(int16(v)), nil
case int32:
if v > math.MaxInt16 || v < math.MinInt16 {
return nil, marshalErrorf("marshal smallint: value %d out of range", v)
}
return encShort(int16(v)), nil
case int64:
if v > math.MaxInt16 || v < math.MinInt16 {
return nil, marshalErrorf("marshal smallint: value %d out of range", v)
}
return encShort(int16(v)), nil
case uint:
if v > math.MaxUint16 {
return nil, marshalErrorf("marshal smallint: value %d out of range", v)
}
return encShort(int16(v)), nil
case uint32:
if v > math.MaxUint16 {
return nil, marshalErrorf("marshal smallint: value %d out of range", v)
}
return encShort(int16(v)), nil
case uint64:
if v > math.MaxUint16 {
return nil, marshalErrorf("marshal smallint: value %d out of range", v)
}
return encShort(int16(v)), nil
case string:
n, err := strconv.ParseInt(v, 10, 16)
if err != nil {
return nil, marshalErrorf("can not marshal %T into %s: %v", value, info, err)
}
return encShort(int16(n)), nil
}

if value == nil {
return nil, nil
}

switch rv := reflect.ValueOf(value); rv.Type().Kind() {
case reflect.Int, reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8:
v := rv.Int()
if v > math.MaxInt16 || v < math.MinInt16 {
return nil, marshalErrorf("marshal smallint: value %d out of range", v)
}
return encShort(int16(v)), nil
case reflect.Uint, reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8:
v := rv.Uint()
if v > math.MaxUint16 {
return nil, marshalErrorf("marshal smallint: value %d out of range", v)
}
return encShort(int16(v)), nil
case reflect.Ptr:
if rv.IsNil() {
return nil, nil
}
func marshalSmallInt(value interface{}) ([]byte, error) {
data, err := smallint.Marshal(value)
if err != nil {
return nil, wrapMarshalError(err, "marshal error")
}

return nil, marshalErrorf("can not marshal %T into %s", value, info)
return data, nil
}

func marshalTinyInt(value interface{}) ([]byte, error) {
Expand Down Expand Up @@ -649,8 +580,12 @@ func unmarshalInt(info TypeInfo, data []byte, value interface{}) error {
return unmarshalIntlike(info, int64(decInt(data)), data, value)
}

func unmarshalSmallInt(info TypeInfo, data []byte, value interface{}) error {
return unmarshalIntlike(info, int64(decShort(data)), data, value)
func unmarshalSmallInt(data []byte, value interface{}) error {
err := smallint.Unmarshal(data, value)
if err != nil {
return wrapUnmarshalError(err, "unmarshal error")
}
return nil
}

func unmarshalTinyInt(data []byte, value interface{}) error {
Expand Down
74 changes: 74 additions & 0 deletions marshal/smallint/marshal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package smallint

import (
"math/big"
"reflect"
)

func Marshal(value interface{}) ([]byte, error) {
switch v := value.(type) {
case nil:
return nil, nil
case int8:
return EncInt8(v)
case int32:
return EncInt32(v)
case int16:
return EncInt16(v)
case int64:
return EncInt64(v)
case int:
return EncInt(v)

case uint8:
return EncUint8(v)
case uint16:
return EncUint16(v)
case uint32:
return EncUint32(v)
case uint64:
return EncUint64(v)
case uint:
return EncUint(v)

case big.Int:
return EncBigInt(v)
case string:
return EncString(v)

case *int8:
return EncInt8R(v)
case *int16:
return EncInt16R(v)
case *int32:
return EncInt32R(v)
case *int64:
return EncInt64R(v)
case *int:
return EncIntR(v)

case *uint8:
return EncUint8R(v)
case *uint16:
return EncUint16R(v)
case *uint32:
return EncUint32R(v)
case *uint64:
return EncUint64R(v)
case *uint:
return EncUintR(v)

case *big.Int:
return EncBigIntR(v)
case *string:
return EncStringR(v)
default:
// Custom types (type MyInt int) can be serialized only via `reflect` package.
// Later, when generic-based serialization is introduced we can do that via generics.
rv := reflect.TypeOf(value)
if rv.Kind() != reflect.Ptr {
return EncReflect(reflect.ValueOf(v))
}
return EncReflectR(reflect.ValueOf(v))
}
}
Loading

0 comments on commit fe56500

Please sign in to comment.