123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514 |
- package yu_proto_old
- import (
- "encoding"
- "encoding/binary"
- "errors"
- "fmt"
- "math"
- "reflect"
- "time"
- )
- // Constructors represents a map defining how to instantiate any interface
- // types that Decode() might encounter while reading and decoding structured
- // data. The keys are reflect.Type values denoting interface types. The
- // corresponding values are functions expected to instantiate, and initialize
- // as necessary, an appropriate concrete object type supporting that
- // interface. A caller could use this capability to support
- // dynamic instantiation of objects of the concrete type
- // appropriate for a given abstract type.
- type Constructors map[reflect.Type]func() interface{}
- // String returns an easy way to visualize what you have in your constructors.
- func (c *Constructors) String() string {
- var s string
- for k := range *c {
- s += k.String() + "=>" + "(func() interface {})" + "\t"
- }
- return s
- }
- // Decoder is the main struct used to decode a protobuf blob.
- type decoder struct {
- nm Constructors
- }
- // Decode a protocol buffer into a Go struct.
- // The caller must pass a pointer to the struct to decode into.
- //
- // Decode() currently does not explicitly check that all 'required' fields
- // are actually present in the input buffer being decoded.
- // If required fields are missing, then the corresponding fields
- // will be left unmodified, meaning they will take on
- // their default Go zero values if Decode() is passed a fresh struct.
- func Decode(buf []byte, structPtr interface{}) error {
- return DecodeWithConstructors(buf, structPtr, nil)
- }
- // DecodeWithConstructors is like Decode, but you can pass a map of
- // constructors with which to instantiate interface types.
- func DecodeWithConstructors(buf []byte, structPtr interface{}, cons Constructors) (err error) {
- defer func() {
- if r := recover(); r != nil {
- switch e := r.(type) {
- case string:
- err = errors.New(e)
- case error:
- err = e
- default:
- err = errors.New("Failed to decode the field")
- }
- }
- }()
- if structPtr == nil {
- return nil
- }
- if bu, ok := structPtr.(encoding.BinaryUnmarshaler); ok {
- return bu.UnmarshalBinary(buf)
- }
- de := decoder{cons}
- val := reflect.ValueOf(structPtr)
- // if its NOT a pointer, it is bad return an error
- if val.Kind() != reflect.Ptr {
- return errors.New("Decode has been given a non pointer type")
- }
- return de.message(buf, val.Elem())
- }
- // Decode a Protocol Buffers message into a Go struct.
- // The Kind of the passed value v must be Struct.
- func (de *decoder) message(buf []byte, sval reflect.Value) error {
- if sval.Kind() != reflect.Struct {
- return errors.New("not a struct")
- }
- for i := 0; i < sval.NumField(); i++ {
- switch field := sval.Field(i); field.Kind() {
- case reflect.Interface:
- // Interface are not reset because the decoder won't
- // be able to instantiate it again in some scenarios.
- default:
- if field.CanSet() {
- field.Set(reflect.Zero(field.Type()))
- }
- }
- }
- // Decode all the fields
- fields := ProtoFields(sval.Type())
- fieldi := 0
- for len(buf) > 0 {
- // Parse the key
- key, n := binary.Uvarint(buf)
- if n <= 0 {
- return errors.New("bad protobuf field key")
- }
- buf = buf[n:]
- wiretype := int(key & 7)
- fieldnum := key >> 3
- // Lookup the corresponding struct field.
- // Leave field with a zero Value if fieldnum is out-of-range.
- // In this case, as well as for blank fields,
- // value() will just skip over and discard the field content.
- var field reflect.Value
- for fieldi < len(fields) && fields[fieldi].ID < int64(fieldnum) {
- fieldi++
- }
- if fieldi < len(fields) && fields[fieldi].ID == int64(fieldnum) {
- // For fields within embedded structs, ensure the embedded values aren't nil.
- index := fields[fieldi].Index
- path := make([]int, 0, len(index))
- for _, id := range index {
- path = append(path, id)
- field = sval.FieldByIndex(path)
- if field.Kind() == reflect.Ptr && field.IsNil() {
- field.Set(reflect.New(field.Type().Elem()))
- }
- }
- }
- // For more debugging output, uncomment the following three lines.
- // if fieldi < len(fields){
- // fmt.Printf("Decoding FieldName %+v\n", fields[fieldi].Field)
- // }
- // Decode the field's value
- rem, err := de.value(wiretype, buf, field)
- if err != nil {
- if fieldi < len(fields) && fields[fieldi] != nil {
- return fmt.Errorf("Error while decoding field %+v: %v", fields[fieldi].Field, err)
- }
- return err
- }
- buf = rem
- }
- return nil
- }
- // Pull a value from the buffer and put it into a reflective Value.
- func (de *decoder) value(wiretype int, buf []byte,
- val reflect.Value) ([]byte, error) {
- // Break out the value from the buffer based on the wire type
- var v uint64
- var n int
- var vb []byte
- switch wiretype {
- case 0: // varint
- v, n = binary.Uvarint(buf)
- if n <= 0 {
- return nil, errors.New("bad protobuf varint value")
- }
- buf = buf[n:]
- case 5: // 32-bit
- if len(buf) < 4 {
- return nil, errors.New("bad protobuf 32-bit value")
- }
- v = uint64(buf[0]) |
- uint64(buf[1])<<8 |
- uint64(buf[2])<<16 |
- uint64(buf[3])<<24
- buf = buf[4:]
- case 1: // 64-bit
- if len(buf) < 8 {
- return nil, errors.New("bad protobuf 64-bit value")
- }
- v = uint64(buf[0]) |
- uint64(buf[1])<<8 |
- uint64(buf[2])<<16 |
- uint64(buf[3])<<24 |
- uint64(buf[4])<<32 |
- uint64(buf[5])<<40 |
- uint64(buf[6])<<48 |
- uint64(buf[7])<<56
- buf = buf[8:]
- case 2: // length-delimited
- v, n = binary.Uvarint(buf)
- if n <= 0 || v > uint64(len(buf)-n) {
- return nil, errors.New(
- "bad protobuf length-delimited value")
- }
- vb = buf[n : n+int(v) : n+int(v)]
- buf = buf[n+int(v):]
- default:
- return nil, errors.New("unknown protobuf wire-type")
- }
- // We've gotten the value out of the buffer,
- // now put it into the appropriate reflective Value.
- if err := de.putvalue(wiretype, val, v, vb); err != nil {
- return nil, err
- }
- return buf, nil
- }
- func (de *decoder) decodeSignedInt(wiretype int, v uint64) (int64, error) {
- if wiretype == 0 { // encoded as varint
- sv := int64(v) >> 1
- if v&1 != 0 {
- sv = ^sv
- }
- return sv, nil
- } else if wiretype == 5 { // sfixed32
- return int64(int32(v)), nil
- } else if wiretype == 1 { // sfixed64
- return int64(v), nil
- } else {
- return -1, errors.New("bad wiretype for sint")
- }
- }
- func (de *decoder) putvalue(wiretype int, val reflect.Value,
- v uint64, vb []byte) error {
- // If val is not settable, it either represents an out-of-range field
- // or an in-range but blank (padding) field in the struct.
- // In this case, simply ignore and discard the field's content.
- if !val.CanSet() {
- return nil
- }
- switch val.Kind() {
- case reflect.Bool:
- if wiretype != 0 {
- return errors.New("bad wiretype for bool")
- }
- if v > 1 {
- return errors.New("invalid bool value")
- }
- val.SetBool(v != 0)
- case reflect.Int, reflect.Int32, reflect.Int64:
- // Signed integers may be encoded either zigzag-varint or fixed
- // Note that protobufs don't support 8- or 16-bit ints.
- if val.Kind() == reflect.Int && val.Type().Size() < 8 {
- return errors.New("detected a 32bit machine, please use either int64 or int32")
- }
- sv, err := de.decodeSignedInt(wiretype, v)
- if err != nil {
- fmt.Println("Error Reflect.Int for v=", v, "wiretype=", wiretype, "for Value=", val.Type().Name())
- return err
- }
- val.SetInt(sv)
- case reflect.Uint, reflect.Uint32, reflect.Uint64:
- // Varint-encoded 32-bit and 64-bit unsigned integers.
- if val.Kind() == reflect.Uint && val.Type().Size() < 8 {
- return errors.New("detected a 32bit machine, please use either uint64 or uint32")
- }
- if wiretype == 0 {
- val.SetUint(v)
- } else if wiretype == 5 { // ufixed32
- val.SetUint(uint64(uint32(v)))
- } else if wiretype == 1 { // ufixed64
- val.SetUint(uint64(v))
- } else {
- return errors.New("bad wiretype for uint")
- }
- case reflect.Float32:
- // Fixed-length 32-bit floats.
- if wiretype != 5 {
- return errors.New("bad wiretype for float32")
- }
- val.SetFloat(float64(math.Float32frombits(uint32(v))))
- case reflect.Float64:
- // Fixed-length 64-bit floats.
- if wiretype != 1 {
- return errors.New("bad wiretype for float64")
- }
- val.SetFloat(math.Float64frombits(v))
- case reflect.String:
- // Length-delimited string.
- if wiretype != 2 {
- return errors.New("bad wiretype for string")
- }
- val.SetString(string(vb))
- case reflect.Struct:
- // Embedded message
- if val.Type() == timeType {
- sv, err := de.decodeSignedInt(wiretype, v)
- if err != nil {
- return err
- }
- t := time.Unix(sv/int64(time.Second), sv%int64(time.Second))
- val.Set(reflect.ValueOf(t))
- return nil
- } else if enc, ok := val.Addr().Interface().(encoding.BinaryUnmarshaler); ok {
- return enc.UnmarshalBinary(vb[:])
- }
- if wiretype != 2 {
- return errors.New("bad wiretype for embedded message")
- }
- return de.message(vb, val)
- case reflect.Ptr:
- // Optional field
- // Instantiate pointer's element type.
- if val.IsNil() {
- val.Set(de.instantiate(val.Type().Elem()))
- }
- return de.putvalue(wiretype, val.Elem(), v, vb)
- case reflect.Slice, reflect.Array:
- // Repeated field or byte-slice
- if wiretype != 2 {
- return errors.New("bad wiretype for repeated field")
- }
- return de.slice(val, vb)
- case reflect.Map:
- if wiretype != 2 {
- return errors.New("bad wiretype for repeated field")
- }
- if val.IsNil() {
- // make(map[k]v):
- val.Set(reflect.MakeMap(val.Type()))
- }
- return de.mapEntry(val, vb)
- case reflect.Interface:
- data := vb[:]
- // Abstract field: instantiate via dynamic constructor.
- if val.IsNil() {
- id := GeneratorID{}
- var g InterfaceGeneratorFunc
- if len(id) < len(vb) {
- copy(id[:], vb[:len(id)])
- g = generators.get(id)
- }
- if g == nil {
- // Backwards compatible usage of the default constructors
- val.Set(de.instantiate(val.Type()))
- } else {
- // As pointers to interface are discouraged in Go, we use
- // the generator only for interface types
- data = vb[len(id):]
- val.Set(reflect.ValueOf(g()))
- }
- }
- // If the object support self-decoding, use that.
- if enc, ok := val.Interface().(encoding.BinaryUnmarshaler); ok {
- if wiretype != 2 {
- return errors.New("bad wiretype for bytes")
- }
- return enc.UnmarshalBinary(data)
- }
- // Decode into the object the interface points to.
- // XXX perhaps better ONLY to support self-decoding
- // for interface fields?
- return Decode(vb, val.Interface())
- default:
- panic("unsupported value kind " + val.Kind().String())
- }
- return nil
- }
- // Instantiate an arbitrary type, handling dynamic interface types.
- // Returns a Ptr value.
- func (de *decoder) instantiate(t reflect.Type) reflect.Value {
- // If it's an interface type, lookup a dynamic constructor for it.
- if t.Kind() == reflect.Interface {
- newfunc, ok := de.nm[t]
- if !ok {
- panic("no constructor for interface " + t.String())
- }
- return reflect.ValueOf(newfunc())
- }
- // Otherwise, for all concrete types, just instantiate directly.
- return reflect.New(t)
- }
- var sfixed32type = reflect.TypeOf(Sfixed32(0))
- var sfixed64type = reflect.TypeOf(Sfixed64(0))
- var ufixed32type = reflect.TypeOf(Ufixed32(0))
- var ufixed64type = reflect.TypeOf(Ufixed64(0))
- // Handle decoding of slices
- func (de *decoder) slice(slval reflect.Value, vb []byte) error {
- // Find the element type, and create a temporary instance of it.
- eltype := slval.Type().Elem()
- val := reflect.New(eltype).Elem()
- // Decide on the wiretype to use for decoding.
- var wiretype int
- switch eltype.Kind() {
- case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Int,
- reflect.Uint32, reflect.Uint64, reflect.Uint:
- if (eltype.Kind() == reflect.Int || eltype.Kind() == reflect.Uint) && eltype.Size() < 8 {
- return errors.New("detected a 32bit machine, please either use (u)int64 or (u)int32")
- }
- switch eltype {
- case sfixed32type:
- wiretype = 5 // Packed 32-bit representation
- case sfixed64type:
- wiretype = 1 // Packed 64-bit representation
- case ufixed32type:
- wiretype = 5 // Packed 32-bit representation
- case ufixed64type:
- wiretype = 1 // Packed 64-bit representation
- default:
- wiretype = 0 // Packed varint representation
- }
- case reflect.Float32:
- wiretype = 5 // Packed 32-bit representation
- case reflect.Float64:
- wiretype = 1 // Packed 64-bit representation
- case reflect.Uint8: // Unpacked byte-slice
- if slval.Kind() == reflect.Array {
- if slval.Len() != len(vb) {
- return errors.New("array length and buffer length differ")
- }
- for i := 0; i < slval.Len(); i++ {
- // no SetByte method in reflect so has to pass down by uint64
- slval.Index(i).SetUint(uint64(vb[i]))
- }
- } else {
- slval.SetBytes(vb)
- }
- return nil
- default: // Other unpacked repeated types
- // Just unpack and append one value from vb.
- if err := de.putvalue(2, val, 0, vb); err != nil {
- return err
- }
- if slval.Kind() != reflect.Slice {
- return errors.New("append to non-slice")
- }
- slval.Set(reflect.Append(slval, val))
- return nil
- }
- // Decode packed values from the buffer and append them to the slice.
- for len(vb) > 0 {
- rem, err := de.value(wiretype, vb, val)
- if err != nil {
- return err
- }
- slval.Set(reflect.Append(slval, val))
- vb = rem
- }
- return nil
- }
- // Handles the entry k,v of a map[K]V
- func (de *decoder) mapEntry(slval reflect.Value, vb []byte) error {
- mKey := reflect.New(slval.Type().Key())
- mVal := reflect.New(slval.Type().Elem())
- k := mKey.Elem()
- v := mVal.Elem()
- key, n := binary.Uvarint(vb)
- if n <= 0 {
- return errors.New("bad protobuf field key")
- }
- buf := vb[n:]
- wiretype := int(key & 7)
- var err error
- buf, err = de.value(wiretype, buf, k)
- if err != nil {
- return err
- }
- for len(buf) > 0 { // for repeated values (slices etc)
- key, n = binary.Uvarint(buf)
- if n <= 0 {
- return errors.New("bad protobuf field key")
- }
- buf = buf[n:]
- wiretype = int(key & 7)
- buf, err = de.value(wiretype, buf, v)
- if err != nil {
- return err
- }
- }
- if !k.IsValid() || !v.IsValid() {
- // We did not decode the key or the value in the map entry.
- // Either way, it's an invalid map entry.
- return errors.New("proto: bad map data: missing key/val")
- }
- slval.SetMapIndex(k, v)
- return nil
- }
|