Skip to content

Instantly share code, notes, and snippets.

@vancexu
Created June 19, 2018 19:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vancexu/815ec74bfaa79ab483ad96cc6a6eb697 to your computer and use it in GitHub Desktop.
Save vancexu/815ec74bfaa79ab483ad96cc6a6eb697 to your computer and use it in GitHub Desktop.
thriftEncoding
// thriftEncoding encapsulates thrift serializer/de-serializer.
type thriftEncoding struct{}
func toStructPtr(obj interface{}) interface{} {
val := reflect.ValueOf(obj)
vp := reflect.New(val.Type())
vp.Elem().Set(val)
return vp.Interface()
}
// Marshal encodes an array of thrift into bytes
func (g thriftEncoding) Marshal(objs []interface{}) ([]byte, error) {
var b bytes.Buffer
for i := 0; i < len(objs); i++ {
if !isThriftType(objs[i]) {
return nil, fmt.Errorf("thrift type is required for %v argument", i+1)
}
var x wire.Value
var err error
if reflect.ValueOf(objs[i]).Kind() != reflect.Ptr {
x, err = toStructPtr(objs[i]).(thriftType).ToWire()
} else {
x, err = reflect.ValueOf(objs[i]).Interface().(thriftType).ToWire()
}
if err != nil {
return nil, err
}
err = protocol.Binary.Encode(x, &b)
if err != nil {
return nil, err
}
}
return b.Bytes(), nil
}
// thriftDecodeHelper is used when bytes in reader contains multiple encoded objects.
// It starts reading from the given offset,
// and return the Value, the new offset, and an error if there was a decode error.
func thriftDecodeHelper(r io.ReaderAt, offset int64, t wire.Type) (wire.Value, int64, error) {
reader := binary.NewReader(r)
return reader.ReadValue(t, offset)
}
// Unmarshal decodes an array of thrift into bytes
func (g thriftEncoding) Unmarshal(data []byte, objs []interface{}) error {
fmt.Println("vancexu in unmarshal")
reader := bytes.NewReader(data)
var offset int64 = 0
for i := 0; i < len(objs); i++ {
rVal := reflect.ValueOf(objs[i])
fmt.Println("rval: ", rVal)
fmt.Println(reflect.TypeOf(objs[i]))
if rVal.Kind() != reflect.Ptr || !isThriftType(reflect.Indirect(rVal).Interface()) {
return fmt.Errorf("pointer to thrift type is required for %v argument", i+1)
}
var x wire.Value
var err error
x, offset, err = thriftDecodeHelper(reader, offset, wire.TStruct)
if err != nil {
return err
}
t, ok := rVal.Interface().(thriftType)
if ok {
err = t.FromWire(x)
} else {
err = reflect.Indirect(rVal).Interface().(thriftType).FromWire(x)
}
//err = rVal.Interface().(thriftType).FromWire(x)
if err != nil {
return err
}
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment