| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069 |
- // Copyright (c) 2012 The gocql Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package gocql
- import (
- "bytes"
- "fmt"
- "math"
- "reflect"
- "time"
- "tux21b.org/v1/gocql/uuid"
- )
- // Marshaler is the interface implemented by objects that can marshal
- // themselves into values understood by Cassandra.
- type Marshaler interface {
- MarshalCQL(info *TypeInfo) ([]byte, error)
- }
- // Unmarshaler is the interface implemented by objects that can unmarshal
- // a Cassandra specific description of themselves.
- type Unmarshaler interface {
- UnmarshalCQL(info *TypeInfo, data []byte) error
- }
- // Marshal returns the CQL encoding of the value for the Cassandra
- // internal type described by the info parameter.
- func Marshal(info *TypeInfo, value interface{}) ([]byte, error) {
- if v, ok := value.(Marshaler); ok {
- return v.MarshalCQL(info)
- }
- switch info.Type {
- case TypeVarchar, TypeAscii, TypeBlob:
- return marshalVarchar(info, value)
- case TypeBoolean:
- return marshalBool(info, value)
- case TypeInt:
- return marshalInt(info, value)
- case TypeBigInt, TypeCounter:
- return marshalBigInt(info, value)
- case TypeFloat:
- return marshalFloat(info, value)
- case TypeDouble:
- return marshalDouble(info, value)
- case TypeTimestamp:
- return marshalTimestamp(info, value)
- case TypeList, TypeSet:
- return marshalList(info, value)
- case TypeMap:
- return marshalMap(info, value)
- case TypeUUID, TypeTimeUUID:
- return marshalUUID(info, value)
- }
- // TODO(tux21b): add the remaining types
- return nil, fmt.Errorf("can not marshal %T into %s", value, info)
- }
- // Unmarshal parses the CQL encoded data based on the info parameter that
- // describes the Cassandra internal data type and stores the result in the
- // value pointed by value.
- func Unmarshal(info *TypeInfo, data []byte, value interface{}) error {
- if v, ok := value.(Unmarshaler); ok {
- return v.UnmarshalCQL(info, data)
- }
- switch info.Type {
- case TypeVarchar, TypeAscii, TypeBlob:
- return unmarshalVarchar(info, data, value)
- case TypeBoolean:
- return unmarshalBool(info, data, value)
- case TypeInt:
- return unmarshalInt(info, data, value)
- case TypeBigInt, TypeCounter:
- return unmarshalBigInt(info, data, value)
- case TypeFloat:
- return unmarshalFloat(info, data, value)
- case TypeDouble:
- return unmarshalDouble(info, data, value)
- case TypeTimestamp:
- return unmarshalTimestamp(info, data, value)
- case TypeList, TypeSet:
- return unmarshalList(info, data, value)
- case TypeMap:
- return unmarshalMap(info, data, value)
- case TypeTimeUUID:
- return unmarshalTimeUUID(info, data, value)
- case TypeUUID:
- return unmarshalUUID(info, data, value)
- case TypeInet:
- return unmarshalInet(info, data, value)
- }
- // TODO(tux21b): add the remaining types
- return fmt.Errorf("can not unmarshal %s into %T", info, value)
- }
- func marshalVarchar(info *TypeInfo, value interface{}) ([]byte, error) {
- switch v := value.(type) {
- case Marshaler:
- return v.MarshalCQL(info)
- case string:
- return []byte(v), nil
- case []byte:
- return v, nil
- }
- rv := reflect.ValueOf(value)
- t := rv.Type()
- k := t.Kind()
- switch {
- case k == reflect.String:
- return []byte(rv.String()), nil
- case k == reflect.Slice && t.Elem().Kind() == reflect.Uint8:
- return rv.Bytes(), nil
- case k == reflect.Ptr:
- return marshalVarchar(info, rv.Elem().Interface())
- }
- return nil, marshalErrorf("can not marshal %T into %s", value, info)
- }
- func unmarshalVarchar(info *TypeInfo, data []byte, value interface{}) error {
- switch v := value.(type) {
- case Unmarshaler:
- return v.UnmarshalCQL(info, data)
- case *string:
- *v = string(data)
- return nil
- case *[]byte:
- var dataCopy []byte
- if data != nil {
- dataCopy = make([]byte, len(data))
- copy(dataCopy, data)
- }
- *v = dataCopy
- return nil
- }
- rv := reflect.ValueOf(value)
- if rv.Kind() != reflect.Ptr {
- return unmarshalErrorf("can not unmarshal into non-pointer %T", value)
- }
- rv = rv.Elem()
- t := rv.Type()
- k := t.Kind()
- switch {
- case k == reflect.String:
- rv.SetString(string(data))
- return nil
- case k == reflect.Slice && t.Elem().Kind() == reflect.Uint8:
- var dataCopy []byte
- if data != nil {
- dataCopy = make([]byte, len(data))
- copy(dataCopy, data)
- }
- rv.SetBytes(dataCopy)
- return nil
- }
- return unmarshalErrorf("can not unmarshal %s into %T", info, value)
- }
- func marshalInt(info *TypeInfo, value interface{}) ([]byte, error) {
- switch v := value.(type) {
- case Marshaler:
- return v.MarshalCQL(info)
- case int:
- if v > math.MaxInt32 || v < math.MinInt32 {
- return nil, marshalErrorf("marshal int: value %d out of range", v)
- }
- return encInt(int32(v)), nil
- case uint:
- if v > math.MaxInt32 {
- return nil, marshalErrorf("marshal int: value %d out of range", v)
- }
- return encInt(int32(v)), nil
- case int64:
- if v > math.MaxInt32 || v < math.MinInt32 {
- return nil, marshalErrorf("marshal int: value %d out of range", v)
- }
- return encInt(int32(v)), nil
- case uint64:
- if v > math.MaxInt32 {
- return nil, marshalErrorf("marshal int: value %d out of range", v)
- }
- return encInt(int32(v)), nil
- case int32:
- return encInt(v), nil
- case uint32:
- if v > math.MaxInt32 {
- return nil, marshalErrorf("marshal int: value %d out of range", v)
- }
- return encInt(int32(v)), nil
- case int16:
- return encInt(int32(v)), nil
- case uint16:
- return encInt(int32(v)), nil
- case int8:
- return encInt(int32(v)), nil
- case uint8:
- return encInt(int32(v)), nil
- }
- rv := reflect.ValueOf(value)
- switch rv.Type().Kind() {
- case reflect.Int, reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8:
- v := rv.Int()
- if v > math.MaxInt32 || v < math.MinInt32 {
- return nil, marshalErrorf("marshal int: value %d out of range", v)
- }
- return encInt(int32(v)), nil
- case reflect.Uint, reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8:
- v := rv.Uint()
- if v > math.MaxInt32 {
- return nil, marshalErrorf("marshal int: value %d out of range", v)
- }
- return encInt(int32(v)), nil
- case reflect.Ptr:
- return marshalInt(info, rv.Elem().Interface())
- }
- return nil, marshalErrorf("can not marshal %T into %s", value, info)
- }
- func encInt(x int32) []byte {
- 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 {
- if len(x) != 4 {
- return 0
- }
- return int32(x[0])<<24 | int32(x[1])<<16 | int32(x[2])<<8 | int32(x[3])
- }
- func marshalBigInt(info *TypeInfo, value interface{}) ([]byte, error) {
- switch v := value.(type) {
- case Marshaler:
- return v.MarshalCQL(info)
- case int:
- return encBigInt(int64(v)), nil
- case uint:
- if uint64(v) > math.MaxInt64 {
- return nil, marshalErrorf("marshal bigint: value %d out of range", v)
- }
- return encBigInt(int64(v)), nil
- case int64:
- return encBigInt(v), nil
- case uint64:
- if v > math.MaxInt64 {
- return nil, marshalErrorf("marshal bigint: value %d out of range", v)
- }
- return encBigInt(int64(v)), nil
- case int32:
- return encBigInt(int64(v)), nil
- case uint32:
- return encBigInt(int64(v)), nil
- case int16:
- return encBigInt(int64(v)), nil
- case uint16:
- return encBigInt(int64(v)), nil
- case int8:
- return encBigInt(int64(v)), nil
- case uint8:
- return encBigInt(int64(v)), nil
- }
- rv := reflect.ValueOf(value)
- switch rv.Type().Kind() {
- case reflect.Int, reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8:
- v := rv.Int()
- return encBigInt(v), nil
- case reflect.Uint, reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8:
- v := rv.Uint()
- if v > math.MaxInt64 {
- return nil, marshalErrorf("marshal bigint: value %d out of range", v)
- }
- return encBigInt(int64(v)), nil
- case reflect.Ptr:
- return marshalBigInt(info, rv.Elem().Interface())
- }
- return nil, marshalErrorf("can not marshal %T into %s", value, info)
- }
- func encBigInt(x int64) []byte {
- return []byte{byte(x >> 56), byte(x >> 48), byte(x >> 40), byte(x >> 32),
- byte(x >> 24), byte(x >> 16), byte(x >> 8), byte(x)}
- }
- func unmarshalBigInt(info *TypeInfo, data []byte, value interface{}) error {
- switch v := value.(type) {
- case Unmarshaler:
- return v.UnmarshalCQL(info, data)
- 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)
- }
- *v = int(x)
- return nil
- 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)
- }
- *v = uint(x)
- return nil
- case *int64:
- *v = decBigInt(data)
- return nil
- case *uint64:
- x := decBigInt(data)
- if x < 0 {
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
- }
- *v = uint64(x)
- return nil
- case *int32:
- x := decBigInt(data)
- if x < math.MinInt32 || x > math.MaxInt32 {
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
- }
- *v = int32(x)
- return nil
- case *uint32:
- x := decBigInt(data)
- if x < 0 || x > math.MaxUint32 {
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
- }
- *v = uint32(x)
- return nil
- case *int16:
- x := decBigInt(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 := decBigInt(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 := decBigInt(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 := decBigInt(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:
- x := decBigInt(data)
- if ^uint(0) == math.MaxUint32 && (x < math.MinInt32 || x > math.MaxInt32) {
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
- }
- rv.SetInt(x)
- return nil
- case reflect.Int64:
- rv.SetInt(decBigInt(data))
- return nil
- case reflect.Int32:
- x := decBigInt(data)
- if x < math.MinInt32 || x > math.MaxInt32 {
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
- }
- rv.SetInt(x)
- return nil
- case reflect.Int16:
- x := decBigInt(data)
- if x < math.MinInt16 || x > math.MaxInt16 {
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
- }
- rv.SetInt(x)
- return nil
- case reflect.Int8:
- x := decBigInt(data)
- if x < math.MinInt8 || x > math.MaxInt8 {
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
- }
- rv.SetInt(x)
- return nil
- 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)
- }
- rv.SetUint(uint64(x))
- return nil
- case reflect.Uint64:
- x := decBigInt(data)
- if x < 0 {
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
- }
- rv.SetUint(uint64(x))
- return nil
- case reflect.Uint32:
- x := decBigInt(data)
- if x < 0 || x > math.MaxUint32 {
- return unmarshalErrorf("unmarshal int: value %d out of range", x)
- }
- rv.SetUint(uint64(x))
- return nil
- case reflect.Uint16:
- x := decBigInt(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 := decBigInt(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 decBigInt(data []byte) int64 {
- if len(data) != 8 {
- return 0
- }
- return int64(data[0])<<56 | int64(data[1])<<48 |
- int64(data[2])<<40 | int64(data[3])<<32 |
- int64(data[4])<<24 | int64(data[5])<<16 |
- int64(data[6])<<8 | int64(data[7])
- }
- func marshalBool(info *TypeInfo, value interface{}) ([]byte, error) {
- switch v := value.(type) {
- case Marshaler:
- return v.MarshalCQL(info)
- case bool:
- return encBool(v), nil
- }
- rv := reflect.ValueOf(value)
- switch rv.Type().Kind() {
- case reflect.Bool:
- return encBool(rv.Bool()), nil
- case reflect.Ptr:
- return marshalBool(info, rv.Elem().Interface())
- }
- return nil, marshalErrorf("can not marshal %T into %s", value, info)
- }
- func encBool(v bool) []byte {
- if v {
- return []byte{1}
- }
- return []byte{0}
- }
- func unmarshalBool(info *TypeInfo, data []byte, value interface{}) error {
- switch v := value.(type) {
- case Unmarshaler:
- return v.UnmarshalCQL(info, data)
- case *bool:
- *v = decBool(data)
- 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.Bool:
- rv.SetBool(decBool(data))
- return nil
- }
- return unmarshalErrorf("can not unmarshal %s into %T", info, value)
- }
- func decBool(v []byte) bool {
- if len(v) == 0 {
- return false
- }
- return v[0] != 0
- }
- func marshalFloat(info *TypeInfo, value interface{}) ([]byte, error) {
- switch v := value.(type) {
- case Marshaler:
- return v.MarshalCQL(info)
- case float32:
- return encInt(int32(math.Float32bits(v))), nil
- }
- rv := reflect.ValueOf(value)
- switch rv.Type().Kind() {
- case reflect.Float32:
- return encInt(int32(math.Float32bits(float32(rv.Float())))), nil
- case reflect.Ptr:
- return marshalFloat(info, rv.Elem().Interface())
- }
- return nil, marshalErrorf("can not marshal %T into %s", value, info)
- }
- func unmarshalFloat(info *TypeInfo, data []byte, value interface{}) error {
- switch v := value.(type) {
- case Unmarshaler:
- return v.UnmarshalCQL(info, data)
- case *float32:
- *v = math.Float32frombits(uint32(decInt(data)))
- 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.Float32:
- rv.SetFloat(float64(math.Float32frombits(uint32(decInt(data)))))
- return nil
- }
- return unmarshalErrorf("can not unmarshal %s into %T", info, value)
- }
- func marshalDouble(info *TypeInfo, value interface{}) ([]byte, error) {
- switch v := value.(type) {
- case Marshaler:
- return v.MarshalCQL(info)
- case float64:
- return encBigInt(int64(math.Float64bits(v))), nil
- }
- rv := reflect.ValueOf(value)
- switch rv.Type().Kind() {
- case reflect.Float64:
- return encBigInt(int64(math.Float64bits(rv.Float()))), nil
- case reflect.Ptr:
- return marshalFloat(info, rv.Elem().Interface())
- }
- return nil, marshalErrorf("can not marshal %T into %s", value, info)
- }
- func unmarshalDouble(info *TypeInfo, data []byte, value interface{}) error {
- switch v := value.(type) {
- case Unmarshaler:
- return v.UnmarshalCQL(info, data)
- case *float64:
- *v = math.Float64frombits(uint64(decBigInt(data)))
- 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.Float64:
- rv.SetFloat(math.Float64frombits(uint64(decBigInt(data))))
- return nil
- }
- return unmarshalErrorf("can not unmarshal %s into %T", info, value)
- }
- func marshalTimestamp(info *TypeInfo, value interface{}) ([]byte, error) {
- switch v := value.(type) {
- case Marshaler:
- return v.MarshalCQL(info)
- case int64:
- return encBigInt(v), nil
- case time.Time:
- x := v.In(time.UTC).UnixNano() / int64(time.Millisecond)
- return encBigInt(x), nil
- }
- rv := reflect.ValueOf(value)
- switch rv.Type().Kind() {
- case reflect.Int64:
- return encBigInt(rv.Int()), nil
- case reflect.Ptr:
- return marshalTimestamp(info, rv.Elem().Interface())
- }
- return nil, marshalErrorf("can not marshal %T into %s", value, info)
- }
- func unmarshalTimestamp(info *TypeInfo, data []byte, value interface{}) error {
- switch v := value.(type) {
- case Unmarshaler:
- return v.UnmarshalCQL(info, data)
- case *int64:
- *v = decBigInt(data)
- return nil
- case *time.Time:
- x := decBigInt(data)
- sec := x / 1000
- nsec := (x - sec*1000) * 1000000
- *v = time.Unix(sec, nsec).In(time.UTC)
- 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.Int64:
- rv.SetInt(decBigInt(data))
- return nil
- }
- return unmarshalErrorf("can not unmarshal %s into %T", info, value)
- }
- func marshalList(info *TypeInfo, value interface{}) ([]byte, error) {
- rv := reflect.ValueOf(value)
- t := rv.Type()
- k := t.Kind()
- switch k {
- case reflect.Slice, reflect.Array:
- if k == reflect.Slice && rv.IsNil() {
- return nil, nil
- }
- buf := &bytes.Buffer{}
- n := rv.Len()
- if n > math.MaxUint16 {
- return nil, marshalErrorf("marshal: slice / array too large")
- }
- buf.WriteByte(byte(n >> 8))
- buf.WriteByte(byte(n))
- for i := 0; i < n; i++ {
- item, err := Marshal(info.Elem, rv.Index(i).Interface())
- if err != nil {
- return nil, err
- }
- if len(item) > math.MaxUint16 {
- return nil, marshalErrorf("marshal: slice / array item too large")
- }
- buf.WriteByte(byte(len(item) >> 8))
- buf.WriteByte(byte(len(item)))
- buf.Write(item)
- }
- return buf.Bytes(), nil
- }
- if k == reflect.Map {
- elem := t.Elem()
- if elem.Kind() == reflect.Struct && elem.NumField() == 0 {
- rkeys := rv.MapKeys()
- keys := make([]interface{}, len(rkeys))
- for i := 0; i < len(keys); i++ {
- keys[i] = rkeys[i].Interface()
- }
- return marshalList(info, keys)
- }
- }
- return nil, marshalErrorf("can not marshal %T into %s", value, info)
- }
- func unmarshalList(info *TypeInfo, data []byte, value interface{}) error {
- rv := reflect.ValueOf(value)
- if rv.Kind() != reflect.Ptr {
- return unmarshalErrorf("can not unmarshal into non-pointer %T", value)
- }
- rv = rv.Elem()
- t := rv.Type()
- k := t.Kind()
- switch k {
- case reflect.Slice, reflect.Array:
- if data == nil {
- if k == reflect.Array {
- return unmarshalErrorf("unmarshal list: can not store nil in array value")
- }
- rv.Set(reflect.Zero(t))
- return nil
- }
- if len(data) < 2 {
- return unmarshalErrorf("unmarshal list: unexpected eof")
- }
- n := int(data[0])<<8 | int(data[1])
- data = data[2:]
- if k == reflect.Array {
- if rv.Len() != n {
- return unmarshalErrorf("unmarshal list: array with wrong size")
- }
- } else if rv.Cap() < n {
- rv.Set(reflect.MakeSlice(t, n, n))
- } else {
- rv.SetLen(n)
- }
- for i := 0; i < n; i++ {
- if len(data) < 2 {
- return unmarshalErrorf("unmarshal list: unexpected eof")
- }
- m := int(data[0])<<8 | int(data[1])
- data = data[2:]
- if err := Unmarshal(info.Elem, data[:m], rv.Index(i).Addr().Interface()); err != nil {
- return err
- }
- data = data[m:]
- }
- return nil
- }
- return unmarshalErrorf("can not unmarshal %s into %T", info, value)
- }
- func marshalMap(info *TypeInfo, value interface{}) ([]byte, error) {
- rv := reflect.ValueOf(value)
- t := rv.Type()
- if t.Kind() != reflect.Map {
- return nil, marshalErrorf("can not marshal %T into %s", value, info)
- }
- if rv.IsNil() {
- return nil, nil
- }
- buf := &bytes.Buffer{}
- n := rv.Len()
- if n > math.MaxUint16 {
- return nil, marshalErrorf("marshal: map too large")
- }
- buf.WriteByte(byte(n >> 8))
- buf.WriteByte(byte(n))
- keys := rv.MapKeys()
- for _, key := range keys {
- item, err := Marshal(info.Key, key.Interface())
- if err != nil {
- return nil, err
- }
- if len(item) > math.MaxUint16 {
- return nil, marshalErrorf("marshal: slice / array item too large")
- }
- buf.WriteByte(byte(len(item) >> 8))
- buf.WriteByte(byte(len(item)))
- buf.Write(item)
- item, err = Marshal(info.Elem, rv.MapIndex(key).Interface())
- if err != nil {
- return nil, err
- }
- if len(item) > math.MaxUint16 {
- return nil, marshalErrorf("marshal: slice / array item too large")
- }
- buf.WriteByte(byte(len(item) >> 8))
- buf.WriteByte(byte(len(item)))
- buf.Write(item)
- }
- return buf.Bytes(), nil
- }
- func unmarshalMap(info *TypeInfo, data []byte, value interface{}) error {
- rv := reflect.ValueOf(value)
- if rv.Kind() != reflect.Ptr {
- return unmarshalErrorf("can not unmarshal into non-pointer %T", value)
- }
- rv = rv.Elem()
- t := rv.Type()
- if t.Kind() != reflect.Map {
- return unmarshalErrorf("can not unmarshal %s into %T", info, value)
- }
- if data == nil {
- rv.Set(reflect.Zero(t))
- return nil
- }
- rv.Set(reflect.MakeMap(t))
- if len(data) < 2 {
- return unmarshalErrorf("unmarshal map: unexpected eof")
- }
- n := int(data[1]) | int(data[0])<<8
- data = data[2:]
- for i := 0; i < n; i++ {
- if len(data) < 2 {
- return unmarshalErrorf("unmarshal list: unexpected eof")
- }
- m := int(data[1]) | int(data[0])<<8
- data = data[2:]
- key := reflect.New(t.Key())
- if err := Unmarshal(info.Key, data[:m], key.Interface()); err != nil {
- return err
- }
- data = data[m:]
- m = int(data[1]) | int(data[0])<<8
- data = data[2:]
- val := reflect.New(t.Elem())
- if err := Unmarshal(info.Elem, data[:m], val.Interface()); err != nil {
- return err
- }
- data = data[m:]
- rv.SetMapIndex(key.Elem(), val.Elem())
- }
- return nil
- }
- func marshalUUID(info *TypeInfo, value interface{}) ([]byte, error) {
- if val, ok := value.([]byte); ok && len(val) == 16 {
- return val, nil
- }
- if val, ok := value.(uuid.UUID); ok {
- return val.Bytes(), nil
- }
- return nil, marshalErrorf("can not marshal %T into %s", value, info)
- }
- func unmarshalUUID(info *TypeInfo, data []byte, value interface{}) error {
- switch v := value.(type) {
- case Unmarshaler:
- return v.UnmarshalCQL(info, data)
- case *uuid.UUID:
- *v = uuid.FromBytes(data)
- return nil
- }
- return unmarshalErrorf("can not unmarshal %s into %T", info, value)
- }
- func unmarshalTimeUUID(info *TypeInfo, data []byte, value interface{}) error {
- switch v := value.(type) {
- case *time.Time:
- id := uuid.FromBytes(data)
- if id.Version() != 1 {
- return unmarshalErrorf("invalid timeuuid")
- }
- *v = id.Time()
- return nil
- default:
- return unmarshalUUID(info, data, value)
- }
- }
- func unmarshalInet(info *TypeInfo, data []byte, value interface{}) error {
- switch v := value.(type) {
- case Unmarshaler:
- return v.UnmarshalCQL(info, data)
- case *string:
- if len(data) == 0 {
- *v = ""
- return nil
- }
- if len(data) == 4 {
- *v = fmt.Sprintf("%d.%d.%d.%d", data[0], data[1], data[2], data[3])
- return nil
- }
- // TODO: support IPv6
- }
- return unmarshalErrorf("can not unmarshal %s into %T", info, value)
- }
- // TypeInfo describes a Cassandra specific data type.
- type TypeInfo struct {
- Type Type
- Key *TypeInfo // only used for TypeMap
- Elem *TypeInfo // only used for TypeMap, TypeList and TypeSet
- Custom string // only used for TypeCostum
- }
- // String returns a human readable name for the Cassandra datatype
- // described by t.
- func (t TypeInfo) String() string {
- switch t.Type {
- case TypeMap:
- return fmt.Sprintf("%s(%s, %s)", t.Type, t.Key, t.Elem)
- case TypeList, TypeSet:
- return fmt.Sprintf("%s(%s)", t.Type, t.Elem)
- case TypeCustom:
- return fmt.Sprintf("%s(%s)", t.Type, t.Elem)
- }
- return t.Type.String()
- }
- // Type is the identifier of a Cassandra internal datatype.
- type Type int
- const (
- TypeCustom Type = 0x0000
- TypeAscii Type = 0x0001
- TypeBigInt Type = 0x0002
- TypeBlob Type = 0x0003
- TypeBoolean Type = 0x0004
- TypeCounter Type = 0x0005
- TypeDecimal Type = 0x0006
- TypeDouble Type = 0x0007
- TypeFloat Type = 0x0008
- TypeInt Type = 0x0009
- TypeTimestamp Type = 0x000B
- TypeUUID Type = 0x000C
- TypeVarchar Type = 0x000D
- TypeVarint Type = 0x000E
- TypeTimeUUID Type = 0x000F
- TypeInet Type = 0x0010
- TypeList Type = 0x0020
- TypeMap Type = 0x0021
- TypeSet Type = 0x0022
- )
- // String returns the name of the identifier.
- func (t Type) String() string {
- switch t {
- case TypeCustom:
- return "custom"
- case TypeAscii:
- return "ascii"
- case TypeBigInt:
- return "bigint"
- case TypeBlob:
- return "blob"
- case TypeBoolean:
- return "boolean"
- case TypeCounter:
- return "counter"
- case TypeDecimal:
- return "decimal"
- case TypeDouble:
- return "double"
- case TypeFloat:
- return "float"
- case TypeInt:
- return "int"
- case TypeTimestamp:
- return "timestamp"
- case TypeUUID:
- return "uuid"
- case TypeVarchar:
- return "varchar"
- case TypeTimeUUID:
- return "timeuuid"
- case TypeInet:
- return "inet"
- case TypeList:
- return "list"
- case TypeMap:
- return "map"
- case TypeSet:
- return "set"
- default:
- return "unknown"
- }
- }
- type MarshalError string
- func (m MarshalError) Error() string {
- return string(m)
- }
- func marshalErrorf(format string, args ...interface{}) MarshalError {
- return MarshalError(fmt.Sprintf(format, args...))
- }
- type UnmarshalError string
- func (m UnmarshalError) Error() string {
- return string(m)
- }
- func unmarshalErrorf(format string, args ...interface{}) UnmarshalError {
- return UnmarshalError(fmt.Sprintf(format, args...))
- }
|