Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix marshal smallint #284

Merged
merged 2 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading