func _reflect(b []byte, v reflect.Value) int { switch v.Kind() { case reflect.String: s := ScanString(b) v.SetString(s) return len(s) + 1 case reflect.Bool: v.SetBool(Bool(b)) return 1 case reflect.Int: v.SetInt(int64(Int(b))) return 8 case reflect.Uint: v.SetUint(uint64(Uint(b))) return 8 case reflect.Int8: v.SetInt(int64(Int8(b))) case reflect.Uint8: v.SetUint(uint64(Uint8(b))) case reflect.Int16: v.SetInt(int64(Int16(b))) case reflect.Uint16: v.SetUint(uint64(Uint16(b))) case reflect.Int32: v.SetInt(int64(Int32(b))) case reflect.Uint32: v.SetUint(uint64(Uint32(b))) case reflect.Int64: v.SetInt(Int64(b)) case reflect.Uint64: v.SetUint(Uint64(b)) case reflect.Float32: v.SetFloat(float64(Float32(b))) case reflect.Float64: v.SetFloat(Float64(b)) case reflect.Complex64: v.SetComplex(complex128(Complex64(b))) case reflect.Complex128: v.SetComplex(Complex128(b)) case reflect.Struct: sum := 0 for i, n := 0, v.NumField(); i < n; i++ { if f := v.Field(i); f.CanSet() { s := _reflect(b[sum:], f) if s < 0 { return -1 } sum += s } } if sum == 0 { return -1 } return sum default: return -1 } return int(v.Type().Size()) }
func (d *decoder) value(v reflect.Value) { switch v.Kind() { case reflect.Array: l := v.Len() for i := 0; i < l; i++ { d.value(v.Index(i)) } case reflect.Struct: l := v.NumField() for i := 0; i < l; i++ { d.value(v.Field(i)) } case reflect.Slice: l := v.Len() for i := 0; i < l; i++ { d.value(v.Index(i)) } case reflect.Int8: v.SetInt(int64(d.int8())) case reflect.Int16: v.SetInt(int64(d.int16())) case reflect.Int32: v.SetInt(int64(d.int32())) case reflect.Int64: v.SetInt(d.int64()) case reflect.Uint8: v.SetUint(uint64(d.uint8())) case reflect.Uint16: v.SetUint(uint64(d.uint16())) case reflect.Uint32: v.SetUint(uint64(d.uint32())) case reflect.Uint64: v.SetUint(d.uint64()) case reflect.Float32: v.SetFloat(float64(math.Float32frombits(d.uint32()))) case reflect.Float64: v.SetFloat(math.Float64frombits(d.uint64())) case reflect.Complex64: v.SetComplex(complex( float64(math.Float32frombits(d.uint32())), float64(math.Float32frombits(d.uint32())), )) case reflect.Complex128: v.SetComplex(complex( math.Float64frombits(d.uint64()), math.Float64frombits(d.uint64()), )) } }
func readList(lex *lexer, v reflect.Value) { switch v.Kind() { case reflect.Complex128: // (real imag) r, _ := strconv.ParseFloat(lex.text(), 64) lex.next() i, _ := strconv.ParseFloat(lex.text(), 64) lex.next() v.SetComplex(complex(r, i)) case reflect.Interface: // ("type" value) s, _ := strconv.Unquote(lex.text()) // NOTE: ignoring errors item := reflect.New(typeRegistry[s]).Elem() lex.next() read(lex, item) v.Set(item) case reflect.Array: // (item ...) for i := 0; !endList(lex); i++ { read(lex, v.Index(i)) } case reflect.Slice: // (item ...) for !endList(lex) { item := reflect.New(v.Type().Elem()).Elem() read(lex, item) v.Set(reflect.Append(v, item)) } case reflect.Struct: // ((name value) ...) for !endList(lex) { lex.consume('(') if lex.token != scanner.Ident { panic(fmt.Sprintf("got token %q, want field name", lex.text())) } name := lex.text() lex.next() read(lex, v.FieldByName(name)) lex.consume(')') } case reflect.Map: // ((key value) ...) v.Set(reflect.MakeMap(v.Type())) for !endList(lex) { lex.consume('(') key := reflect.New(v.Type().Key()).Elem() read(lex, key) value := reflect.New(v.Type().Elem()).Elem() read(lex, value) v.SetMapIndex(key, value) lex.consume(')') } default: panic(fmt.Sprintf("cannot decode list into %v", v.Type())) } }
func complex64Decoder(dec *decoder, v reflect.Value) error { bs := dec.buf[:8] if err := readAtLeast(dec, bs, 8); err != nil { return err } v.SetComplex(complex( float64(math.Float32frombits(dec.order.Uint32(bs))), float64(math.Float32frombits(dec.order.Uint32(bs[4:]))), )) return nil }
func complex128Decoder(dec *decoder, v reflect.Value) error { bs := dec.buf[:8] if err := readAtLeast(dec, bs, 8); err != nil { return err } f1 := math.Float64frombits(dec.order.Uint64(bs)) if err := readAtLeast(dec, bs, 8); err != nil { return err } v.SetComplex(complex(f1, math.Float64frombits(dec.order.Uint64(bs)))) return nil }
func decodeBasic(v reflect.Value, x interface{}) { t := v.Type() switch k, s := t.Kind(), getString(x); k { case reflect.Bool: if b, e := strconv.ParseBool(s); e == nil { v.SetBool(b) } else { panic("could not parse bool from " + strconv.Quote(s)) } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: if i, e := strconv.ParseInt(s, 10, 64); e == nil { v.SetInt(i) } else { panic("could not parse int from " + strconv.Quote(s)) } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: if u, e := strconv.ParseUint(s, 10, 64); e == nil { v.SetUint(u) } else { panic("could not parse uint from " + strconv.Quote(s)) } case reflect.Float32, reflect.Float64: if f, e := strconv.ParseFloat(s, 64); e == nil { v.SetFloat(f) } else { panic("could not parse float from " + strconv.Quote(s)) } case reflect.Complex64, reflect.Complex128: var c complex128 if n, err := fmt.Sscanf(s, "%g", &c); n == 1 && err == nil { v.SetComplex(c) } else { panic("could not parse complex from " + strconv.Quote(s)) } case reflect.String: v.SetString(s) default: panic(t.String() + " has unsupported kind " + k.String()) } }
// complexSetter sets value with the complex returned from valueMaker, if it implements ComplexMaker. Otherwise it returns an error. func complexSetter(bitSize int, valueMaker interface{}, value reflect.Value, tagValue string) (bool, error) { complexValueMaker, ok := valueMaker.(ComplexMaker) if !ok { var kind reflect.Kind if bitSize == 64 { kind = reflect.Complex64 } else { kind = reflect.Complex128 } return false, &UnsupportedKindError{kind} } set, c128, err := complexValueMaker.MakeComplex(tagValue, bitSize) if err != nil { return false, err } else if set { value.SetComplex(c128) } return set, nil }
func (d *decoder) value(v reflect.Value) { switch v.Kind() { case reflect.Array: l := v.Len() for i := 0; i < l; i++ { d.value(v.Index(i)) } case reflect.Struct: t := v.Type() l := v.NumField() for i := 0; i < l; i++ { // Note: Calling v.CanSet() below is an optimization. // It would be sufficient to check the field name, // but creating the StructField info for each field is // costly (run "go test -bench=ReadStruct" and compare // results when making changes to this code). if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" { d.value(v) } else { d.skip(v) } } case reflect.Slice: l := v.Len() for i := 0; i < l; i++ { d.value(v.Index(i)) } case reflect.Int8: v.SetInt(int64(d.int8())) case reflect.Int16: v.SetInt(int64(d.int16())) case reflect.Int32: v.SetInt(int64(d.int32())) case reflect.Int64: v.SetInt(d.int64()) case reflect.Uint8: v.SetUint(uint64(d.uint8())) case reflect.Uint16: v.SetUint(uint64(d.uint16())) case reflect.Uint32: v.SetUint(uint64(d.uint32())) case reflect.Uint64: v.SetUint(d.uint64()) case reflect.Float32: v.SetFloat(float64(math.Float32frombits(d.uint32()))) case reflect.Float64: v.SetFloat(math.Float64frombits(d.uint64())) case reflect.Complex64: v.SetComplex(complex( float64(math.Float32frombits(d.uint32())), float64(math.Float32frombits(d.uint32())), )) case reflect.Complex128: v.SetComplex(complex( math.Float64frombits(d.uint64()), math.Float64frombits(d.uint64()), )) } }
// decComplex128 decodes a pair of unsigned integers, treats them as a // pair of floating point numbers, and stores them as a complex128 in value. // The real part comes first. func decComplex128(i *decInstr, state *decoderState, value reflect.Value) { real := float64FromBits(state.decodeUint()) imag := float64FromBits(state.decodeUint()) value.SetComplex(complex(real, imag)) }
// decComplex64 decodes a pair of unsigned integers, treats them as a // pair of floating point numbers, and stores them as a complex64 in value. // The real part comes first. func decComplex64(i *decInstr, state *decoderState, value reflect.Value) { real := float32FromBits(state.decodeUint(), i.ovfl) imag := float32FromBits(state.decodeUint(), i.ovfl) value.SetComplex(complex(real, imag)) }
func (t *Transport) decodeValue(r reader, val reflect.Value) error { // TODO(kevlar): Break out "decodeUvarint" and "decodeString" so that we // don't need the decodeValue(r, reflect.ValueOf(...).Elem()) construct. // Delegate out basic types switch val.Kind() { case reflect.Interface: if val.IsNil() { return fmt.Errorf("cannot decode into nil interface") } case reflect.Ptr: ptype, err := r.ReadByte() if err != nil { return err } if ptype == '0' { return nil } if val.IsNil() { pzero := reflect.New(val.Type().Elem()) val.Set(pzero) } return t.decodeValue(r, val.Elem()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: varint, err := binary.ReadVarint(r) if err != nil { return err } val.SetInt(varint) case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: varint, err := binary.ReadUvarint(r) if err != nil { return err } val.SetUint(varint) case reflect.Uintptr: var raw [8]byte if _, err := io.ReadFull(r, raw[:]); err != nil { return err } val.SetUint(endian.Uint64(raw[:])) case reflect.Uint8: b, err := r.ReadByte() if err != nil { return err } val.SetUint(uint64(b)) case reflect.Bool: c, err := r.ReadByte() if err != nil { return err } val.SetBool(c == 'T') case reflect.Float32, reflect.Float64: var raw [8]byte if _, err := io.ReadFull(r, raw[:]); err != nil { return err } val.SetFloat(math.Float64frombits(endian.Uint64(raw[:]))) case reflect.Complex64, reflect.Complex128: var raw [8]byte if _, err := io.ReadFull(r, raw[:]); err != nil { return err } rpart := math.Float64frombits(endian.Uint64(raw[:])) if _, err := io.ReadFull(r, raw[:]); err != nil { return err } ipart := math.Float64frombits(endian.Uint64(raw[:])) val.SetComplex(complex(rpart, ipart)) case reflect.Array, reflect.Slice, reflect.String: return t.decodeArrayish(r, val) case reflect.Map: var count uint if err := t.decodeValue(r, reflect.ValueOf(&count).Elem()); err != nil { return err } mtyp := val.Type() ktyp := mtyp.Key() etyp := mtyp.Elem() val.Set(reflect.MakeMap(val.Type())) for i := 0; i < int(count); i++ { key := reflect.New(ktyp).Elem() elem := reflect.New(etyp).Elem() if err := t.decodeValue(r, key); err != nil { return err } if err := t.decodeValue(r, elem); err != nil { return err } val.SetMapIndex(key, elem) } case reflect.Struct: styp := val.Type() var name string var fields uint if err := t.decodeValue(r, reflect.ValueOf(&name).Elem()); err != nil { return err } if err := t.decodeValue(r, reflect.ValueOf(&fields).Elem()); err != nil { return err } if got, want := name, styp.Name(); got != want { return fmt.Errorf("attempted to decode %q into %q: struct name mismatch", got, want) } if got, want := fields, uint(styp.NumField()); got != want { return fmt.Errorf("attempted to decode %d fields into %d fields: struct field count mismatch", got, want) } for i := 0; i < styp.NumField(); i++ { if f := styp.Field(i); f.Type.Kind() == reflect.Chan { if err := t.decodeChan(r, val.Field(i), f.Tag.Get("fatchan")); err != nil { return err } continue } if err := t.decodeValue(r, val.Field(i)); err != nil { return err } } case reflect.Chan: if err := t.decodeChan(r, val, ""); err != nil { return err } default: return fmt.Errorf("unrecognized type %s in value %s", val.Type(), val) } return nil }
func read(d *decoder, v reflect.Value, noset bool) { if d.err != nil { return } v = reflect.Indirect(v) k := v.Kind() // println(k.String()) switch k { case reflect.Bool: x := true if d.uint8() == 0 { x = false } if !noset { v.SetBool(x) } case reflect.Int: x := d.int() if !noset { v.SetInt(int64(x)) } case reflect.Int8: x := d.int8() if !noset { v.SetInt(int64(x)) } case reflect.Int16: x := d.int16() if !noset { v.SetInt(int64(x)) } case reflect.Int32: x := d.int32() if !noset { v.SetInt(int64(x)) } case reflect.Int64: x := d.int64() if !noset { v.SetInt(x) } case reflect.Uint: x := d.uint() if !noset { v.SetUint(uint64(x)) } case reflect.Uint8: x := d.uint8() if !noset { v.SetUint(uint64(x)) } case reflect.Uint16: x := d.uint16() if !noset { v.SetUint(uint64(x)) } case reflect.Uint32: x := d.uint32() if !noset { v.SetUint(uint64(x)) } case reflect.Uint64: x := d.uint64() if !noset { v.SetUint(x) } case reflect.Float32: x := math.Float32frombits(d.uint32()) if !noset { v.SetFloat(float64(x)) } case reflect.Float64: x := math.Float64frombits(d.uint64()) if !noset { v.SetFloat(x) } case reflect.Complex64: r, i := math.Float32frombits(d.uint32()), math.Float32frombits(d.uint32()) x := complex(float64(r), float64(i)) if !noset { v.SetComplex(x) } case reflect.Complex128: r, i := math.Float64frombits(d.uint64()), math.Float64frombits(d.uint64()) x := complex(r, i) if !noset { v.SetComplex(x) } case reflect.Struct: n := v.NumField() for i := 0; i < n && d.err == nil; i++ { read(d, v.Field(i), noset || !v.CanSet()) } case reflect.Array: n := v.Len() for i := 0; i < n && d.err == nil; i++ { read(d, v.Index(i), noset) } case reflect.String: n := d.int() x := string(d.bytes(n)) if d.err == nil && !noset { v.SetString(x) } case reflect.Slice: n := d.int() x := reflect.MakeSlice(v.Type(), n, n) for i := 0; i < n && d.err == nil; i++ { read(d, x.Index(i), noset) } if !noset { v.Set(x) } default: d.setError(errors.New("bintuil.decode: invalid type " + k.String())) } }
func (d *decoder) read(f field, v reflect.Value) { if f.Name != "_" { if s, ok := d.unpacker(v); ok { var err error d.buf, err = s.Unpack(d.buf, d.order) if err != nil { panic(err) } return } } else { d.skipn(f.SizeOf(v)) return } struc := d.struc sfields := d.sfields order := d.order if f.Order != nil { d.order = f.Order defer func() { d.order = order }() } if f.Skip != 0 { d.skipn(f.Skip) } switch f.Type.Kind() { case reflect.Array: l := f.Type.Len() // If the underlying value is a slice, initialize it. if f.DefType.Kind() == reflect.Slice { v.Set(reflect.MakeSlice(reflect.SliceOf(f.Type.Elem()), l, l)) } switch f.DefType.Kind() { case reflect.String: v.SetString(string(d.readn(f.SizeOf(v)))) case reflect.Slice, reflect.Array: ef := f.Elem() for i := 0; i < l; i++ { d.read(ef, v.Index(i)) } default: panic(fmt.Errorf("invalid array cast type: %s", f.DefType.String())) } case reflect.Struct: d.struc = v d.sfields = cachedFieldsFromStruct(f.Type) l := len(d.sfields) for i := 0; i < l; i++ { f := d.sfields[i] v := v.Field(f.Index) if v.CanSet() { d.read(f, v) } else { d.skip(f, v) } } d.sfields = sfields d.struc = struc case reflect.Slice, reflect.String: switch f.DefType.Kind() { case reflect.String: l := v.Len() v.SetString(string(d.readn(l))) case reflect.Slice, reflect.Array: switch f.DefType.Elem().Kind() { case reflect.Uint8: v.SetBytes(d.readn(f.SizeOf(v))) default: l := v.Len() ef := f.Elem() for i := 0; i < l; i++ { d.read(ef, v.Index(i)) } } default: panic(fmt.Errorf("invalid array cast type: %s", f.DefType.String())) } case reflect.Int8: v.SetInt(int64(d.readS8())) case reflect.Int16: v.SetInt(int64(d.readS16())) case reflect.Int32: v.SetInt(int64(d.readS32())) case reflect.Int64: v.SetInt(d.readS64()) case reflect.Uint8: v.SetUint(uint64(d.read8())) case reflect.Uint16: v.SetUint(uint64(d.read16())) case reflect.Uint32: v.SetUint(uint64(d.read32())) case reflect.Uint64: v.SetUint(d.read64()) case reflect.Float32: v.SetFloat(float64(math.Float32frombits(d.read32()))) case reflect.Float64: v.SetFloat(math.Float64frombits(d.read64())) case reflect.Complex64: v.SetComplex(complex( float64(math.Float32frombits(d.read32())), float64(math.Float32frombits(d.read32())), )) case reflect.Complex128: v.SetComplex(complex( math.Float64frombits(d.read64()), math.Float64frombits(d.read64()), )) } if f.SIndex != -1 { sv := struc.Field(f.SIndex) l := len(sfields) for i := 0; i < l; i++ { if sfields[i].Index != f.SIndex { continue } sf := sfields[i] sl := 0 // Must use different codepath for signed/unsigned. switch f.DefType.Kind() { case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: sl = int(v.Int()) case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: sl = int(v.Uint()) default: panic(fmt.Errorf("unsupported sizeof type %s", f.DefType.String())) } // Strings are immutable, but we make a blank one so that we can // figure out the size later. It might be better to do something // more hackish, like writing the length into the string... switch sf.DefType.Kind() { case reflect.Slice: sv.Set(reflect.MakeSlice(sf.Type, sl, sl)) case reflect.String: sv.SetString(string(make([]byte, sl))) default: panic(fmt.Errorf("unsupported sizeof target %s", sf.DefType.String())) } } } }