func binaryEncoder(e *encodeState, k string, v reflect.Value) { //type(1) | klen(1) | vlen(4) | key(len(k)) | 0x00 | value e.resizeIfNeeded(1 + 1 + 4 + len(k) + 1 + v.Len()) e.data[e.off] = MCPACKV2_BINARY e.off++ if len(k) > 0 { // key len e.data[e.off] = byte(len(k) + 1) } else { e.data[e.off] = 0 } e.off++ vlenpos := e.off e.off += 4 // content length if len(k) > 0 { // key and 0x00 e.off += copy(e.data[e.off:], k) e.data[e.off] = 0 e.off++ } vpos := e.off e.off += copy(e.data[e.off:], v.Bytes()) //value PutInt32(e.data[vlenpos:], int32(e.off-vpos)) }
func (f *Field) Pack(buf []byte, val reflect.Value, length int) error { if f.Type == Pad { for i := 0; i < length; i++ { buf[i] = 0 } return nil } if f.Slice { // special case byte slices for performance if !f.Array && f.Type == Uint8 && f.defType == Uint8 { copy(buf, val.Bytes()) return nil } pos := 0 for i := 0; i < length; i++ { if err := f.packVal(buf[pos:], val.Index(i), 1); err != nil { return err } pos += f.Type.Size() } return nil } else { return f.packVal(buf, val, length) } }
func defaultReturnHandler() ReturnHandler { return func(ctx *Context, vals []reflect.Value) { rv := ctx.GetVal(inject.InterfaceOf((*http.ResponseWriter)(nil))) resp := rv.Interface().(http.ResponseWriter) var respVal reflect.Value if len(vals) > 1 && vals[0].Kind() == reflect.Int { resp.WriteHeader(int(vals[0].Int())) respVal = vals[1] } else if len(vals) > 0 { respVal = vals[0] if isError(respVal) { err := respVal.Interface().(error) if err != nil { ctx.internalServerError(ctx, err) } return } else if canDeref(respVal) { if respVal.IsNil() { return // Ignore nil error } } } if canDeref(respVal) { respVal = respVal.Elem() } if isByteSlice(respVal) { resp.Write(respVal.Bytes()) } else { resp.Write([]byte(respVal.String())) } } }
func (f *Field) Unpack(buf []byte, val reflect.Value, length int, options *Options) error { typ := f.Type.Resolve(options) if typ == Pad || f.kind == reflect.String { if typ == Pad { return nil } else { val.SetString(string(buf)) return nil } } else if f.Slice { if val.Cap() < length { val.Set(reflect.MakeSlice(val.Type(), length, length)) } else if val.Len() < length { val.Set(val.Slice(0, length)) } // special case byte slices for performance if !f.Array && typ == Uint8 && f.defType == Uint8 { copy(val.Bytes(), buf[:length]) return nil } pos := 0 size := typ.Size() for i := 0; i < length; i++ { if err := f.unpackVal(buf[pos:pos+size], val.Index(i), 1, options); err != nil { return err } pos += size } return nil } else { return f.unpackVal(buf, val, length, options) } }
func encodePacketValue(buf []byte, v reflect.Value) (int, error) { n := 0 switch v.Kind() { default: return n, ErrUnhandledFieldType case reflect.Struct: for i := 0; i < v.NumField(); i++ { field := v.Field(i) n2, err := encodePacketValue(buf[n:], field) n += n2 if err != nil { return n, err } } case reflect.Bool: if v.Bool() { buf[n] = 1 } else { buf[n] = 0 } n += 1 case reflect.Int32: binary.BigEndian.PutUint32(buf[n:n+4], uint32(v.Int())) n += 4 case reflect.Int64: binary.BigEndian.PutUint64(buf[n:n+8], uint64(v.Int())) n += 8 case reflect.String: str := v.String() binary.BigEndian.PutUint32(buf[n:n+4], uint32(len(str))) copy(buf[n+4:n+4+len(str)], []byte(str)) n += 4 + len(str) case reflect.Slice: switch v.Type().Elem().Kind() { default: count := v.Len() startN := n n += 4 for i := 0; i < count; i++ { n2, err := encodePacketValue(buf[n:], v.Index(i)) n += n2 if err != nil { return n, err } } binary.BigEndian.PutUint32(buf[startN:startN+4], uint32(count)) case reflect.Uint8: if v.IsNil() { binary.BigEndian.PutUint32(buf[n:n+4], uint32(0xffffffff)) n += 4 } else { bytes := v.Bytes() binary.BigEndian.PutUint32(buf[n:n+4], uint32(len(bytes))) copy(buf[n+4:n+4+len(bytes)], bytes) n += 4 + len(bytes) } } } return n, nil }
func (f *decFnInfo) kSlice(rv reflect.Value) { // A slice can be set from a map or array in stream. currEncodedType := f.dd.currentEncodedType() switch currEncodedType { case valueTypeBytes, valueTypeString: if f.ti.rtid == uint8SliceTypId || f.ti.rt.Elem().Kind() == reflect.Uint8 { if bs2, changed2 := f.dd.decodeBytes(rv.Bytes()); changed2 { rv.SetBytes(bs2) } return } } if shortCircuitReflectToFastPath && rv.CanAddr() { switch f.ti.rtid { case intfSliceTypId: f.d.decSliceIntf(rv.Addr().Interface().(*[]interface{}), currEncodedType, f.array) return case uint64SliceTypId: f.d.decSliceUint64(rv.Addr().Interface().(*[]uint64), currEncodedType, f.array) return case int64SliceTypId: f.d.decSliceInt64(rv.Addr().Interface().(*[]int64), currEncodedType, f.array) return case strSliceTypId: f.d.decSliceStr(rv.Addr().Interface().(*[]string), currEncodedType, f.array) return } } containerLen, containerLenS := decContLens(f.dd, currEncodedType) // an array can never return a nil slice. so no need to check f.array here. if rv.IsNil() { rv.Set(reflect.MakeSlice(f.ti.rt, containerLenS, containerLenS)) } if containerLen == 0 { return } if rvcap, rvlen := rv.Len(), rv.Cap(); containerLenS > rvcap { if f.array { // !rv.CanSet() decErr(msgDecCannotExpandArr, rvcap, containerLenS) } rvn := reflect.MakeSlice(f.ti.rt, containerLenS, containerLenS) if rvlen > 0 { reflect.Copy(rvn, rv) } rv.Set(rvn) } else if containerLenS > rvlen { rv.SetLen(containerLenS) } for j := 0; j < containerLenS; j++ { f.d.decodeValue(rv.Index(j)) } }
func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) error { switch val.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: p.WriteString(strconv.FormatInt(val.Int(), 10)) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: p.WriteString(strconv.FormatUint(val.Uint(), 10)) case reflect.Float32, reflect.Float64: p.WriteString(strconv.FormatFloat(val.Float(), 'g', -1, 64)) case reflect.String: // TODO: Add EscapeString. Escape(p, []byte(val.String())) case reflect.Bool: p.WriteString(strconv.FormatBool(val.Bool())) case reflect.Array: // will be [...]byte bytes := make([]byte, val.Len()) for i := range bytes { bytes[i] = val.Index(i).Interface().(byte) } Escape(p, bytes) case reflect.Slice: // will be []byte Escape(p, val.Bytes()) default: return &UnsupportedTypeError{typ} } return nil }
func indexBytes(typ reflect.Type, value reflect.Value) (b []byte, err error) { switch typ.Kind() { case reflect.String: b = []byte(value.String()) case reflect.Int: buf := new(bytes.Buffer) if err = binary.Write(buf, binary.BigEndian, value.Int()); err != nil { return } b = buf.Bytes() case reflect.Slice: switch typ.Elem().Kind() { case reflect.Uint8: b = value.Bytes() default: err = fmt.Errorf("%v is not an indexable type", typ) } case reflect.Bool: if value.Bool() { b = []byte{1} } else { b = []byte{0} } default: err = fmt.Errorf("%v is not an indexable type", typ) return } if len(b) == 0 { b = []byte{0} } return }
func encode(b []byte, rv reflect.Value) ([]byte, error) { switch rk := rv.Kind(); rk { case reflect.Bool: b = encodeBool(b, rv.Bool()) case reflect.Int, reflect.Int8, reflect.Int64, reflect.Int32, reflect.Int16: b = encodeInt(b, rv.Int()) case reflect.Uint8, reflect.Uint64, reflect.Uint, reflect.Uint32, reflect.Uint16: b = encodeInt(b, int64(rv.Uint())) case reflect.String: b = encodeString(b, rv.String()) case reflect.Array, reflect.Slice: if rv.Len() == 0 && rv.Type().Elem().Kind() == reflect.Uint8 { b = encodeBytes(b, rv.Bytes()) } else if rv.Index(0).Kind() == reflect.Uint8 { b = encodeBytes(b, rv.Bytes()) } else { b = encodeArray(b, rv) } case reflect.Map: b = encodeMap(b, rv) case reflect.Struct: b = encodeStruct(b, rv) default: panic("no support for type") } return b, nil }
func marshalBytesValue(value reflect.Value) *dynamodb.AttributeValue { if value.IsNil() { return makeNullAttrValue() } return &dynamodb.AttributeValue{B: value.Bytes()} }
/* Subscription will return a subscription with name, watching changes to objects with the same type and id as obj. It will watch for operations matching the ops, and send the events to the subscriber. */ func (self *DB) Subscription(name string, obj interface{}, ops Operation, subscriber Subscriber) (result *Subscription, err error) { var wantedValue reflect.Value var wantedId reflect.Value if wantedValue, wantedId, err = identify(obj); err != nil { return } wantedType := wantedValue.Type() wantedBytes := make([]byte, len(wantedId.Bytes())) copy(wantedBytes, wantedId.Bytes()) result = &Subscription{ name: name, db: self, matcher: func(tx *TX, typ reflect.Type, value reflect.Value) (result bool, err error) { if typ.Name() != wantedType.Name() { return } if bytes.Compare(value.FieldByName(idField).Bytes(), wantedBytes) != 0 { return } result = true return }, subscriber: subscriber, ops: ops, typ: wantedType, } return }
func rewrite(nodeVal reflect.Value, rewriter Rewriter) { if !nodeVal.IsValid() { return } nodeTyp := nodeVal.Type() switch nodeTyp.Kind() { case reflect.Slice: if nodeTyp == typeOfBytes && !nodeVal.IsNil() { val := rewriter(nodeVal.Bytes()) //use rewriter to rewrite the bytes nodeVal.SetBytes(val) } else if nodeTyp.Implements(typeOfSQLNode) { for i := 0; i < nodeVal.Len(); i++ { m := nodeVal.Index(i) rewrite(m, rewriter) } } case reflect.Struct: for i := 0; i < nodeVal.NumField(); i++ { f := nodeVal.Field(i) rewrite(f, rewriter) } case reflect.Ptr, reflect.Interface: rewrite(nodeVal.Elem(), rewriter) } }
func (e *Encoder) encodeScalar(by []byte, rv reflect.Value, isKeyOrClass bool, strTable map[string]int, ptrTable map[uintptr]int) []byte { for rv.Kind() == reflect.Interface { rv = rv.Elem() } switch rv.Kind() { case reflect.Array, reflect.Slice: if rv.Type().Elem().Kind() == reflect.Uint8 { by = e.encodeBytes(by, rv.Bytes(), isKeyOrClass, strTable) } else { by = append(by, typeREFN) by = e.encodeArray(by, rv, strTable, ptrTable) } case reflect.Map: by = append(by, typeREFN) by = e.encodeMap(by, rv, strTable, ptrTable) case reflect.String: by = e.encodeString(by, rv.String(), true, strTable) default: by, _ = e.encode(by, rv, isKeyOrClass, strTable, ptrTable) } return by }
func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) error { // Normally we don't see structs, but this can happen for an attribute. if val.Type() == timeType { p.WriteString(val.Interface().(time.Time).Format(time.RFC3339Nano)) return nil } switch val.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: p.WriteString(strconv.FormatInt(val.Int(), 10)) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: p.WriteString(strconv.FormatUint(val.Uint(), 10)) case reflect.Float32, reflect.Float64: p.WriteString(strconv.FormatFloat(val.Float(), 'g', -1, 64)) case reflect.String: // TODO: Add EscapeString. Escape(p, []byte(val.String())) case reflect.Bool: p.WriteString(strconv.FormatBool(val.Bool())) case reflect.Array: // will be [...]byte bytes := make([]byte, val.Len()) for i := range bytes { bytes[i] = val.Index(i).Interface().(byte) } Escape(p, bytes) case reflect.Slice: // will be []byte Escape(p, val.Bytes()) default: return &UnsupportedTypeError{typ} } return p.cachedWriteError() }
func defaultReturnHandler() ReturnHandler { return func(ctx Context, vals []reflect.Value) { rv := ctx.Get(inject.InterfaceOf((*http.ResponseWriter)(nil))) res := rv.Interface().(http.ResponseWriter) var responseVal reflect.Value if len(vals) > 1 && vals[0].Kind() == reflect.Int { res.WriteHeader(int(vals[0].Int())) responseVal = vals[1] } else if len(vals) > 0 { responseVal = vals[0] } if canDeref(responseVal) { responseVal = responseVal.Elem() } if isByteSlice(responseVal) { res.Write(responseVal.Bytes()) } else { jsonBody, err := json.Marshal(responseVal.Interface()) if err != nil { res.Write([]byte(responseVal.String())) } else { res.Write(jsonBody) } } } }
func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []byte, error) { switch val.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return strconv.FormatInt(val.Int(), 10), nil, nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return strconv.FormatUint(val.Uint(), 10), nil, nil case reflect.Float32, reflect.Float64: return strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits()), nil, nil case reflect.String: return val.String(), nil, nil case reflect.Bool: return strconv.FormatBool(val.Bool()), nil, nil case reflect.Array: if typ.Elem().Kind() != reflect.Uint8 { break } // [...]byte var bytes []byte if val.CanAddr() { bytes = val.Slice(0, val.Len()).Bytes() } else { bytes = make([]byte, val.Len()) reflect.Copy(reflect.ValueOf(bytes), val) } return "", bytes, nil case reflect.Slice: if typ.Elem().Kind() != reflect.Uint8 { break } // []byte return "", val.Bytes(), nil } return "", nil, &UnsupportedTypeError{typ} }
func (ep entityProtector) encrypt(field reflect.Value) { switch field.Interface().(type) { case []byte: field.SetBytes(ep.cipher.Encrypt(field.Bytes())) case string: field.SetString(string(ep.cipher.Encrypt([]byte(field.String())))) } }
// encUint8Array encodes the byte array referenced by v. // Byte arrays are encoded as an unsigned count followed by the raw bytes. func encUint8Array(i *encInstr, state *encoderState, v reflect.Value) { b := v.Bytes() if len(b) > 0 || state.sendZero { state.update(i) state.encodeUint(uint64(len(b))) state.b.Write(b) } }
func (e *Encoder) encode(rv reflect.Value) error { switch rk := rv.Kind(); rk { case reflect.Bool: e.encodeBool(rv.Bool()) case reflect.Int, reflect.Int8, reflect.Int64, reflect.Int32, reflect.Int16: e.encodeInt(reflect.Int, rv.Int()) case reflect.Uint8, reflect.Uint64, reflect.Uint, reflect.Uint32, reflect.Uint16: e.encodeInt(reflect.Uint, int64(rv.Uint())) case reflect.String: e.encodeString(rv.String()) case reflect.Array, reflect.Slice: if rv.Type().Elem().Kind() == reflect.Uint8 { e.encodeBytes(rv.Bytes()) } else { e.encodeArray(rv) } case reflect.Map: e.encodeMap(rv) case reflect.Struct: e.encodeStruct(rv) case reflect.Float32, reflect.Float64: e.encodeFloat(float64(rv.Float())) case reflect.Interface: // recurse until we get a concrete type // could be optmized into a tail call var err error err = e.encode(rv.Elem()) if err != nil { return err } case reflect.Ptr: if rv.Elem().Kind() == reflect.Struct { switch rv.Elem().Interface().(type) { case None: e.encodeStruct(rv.Elem()) return nil } } e.encode(rv.Elem()) case reflect.Invalid: e.w.Write([]byte{opNone}) default: panic(fmt.Sprintf("no support for type '%s'", rk.String())) } return nil }
func (e *encodeState) marshalArrayValue(path string, v reflect.Value, options tagOptions) string { if v.Type().Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 { e.marshalBytesValue(v.Bytes(), options) return "string" } sep := " " e.WriteByte('[') check := checkArrayElemType(path, "") for i, n := 0, v.Len(); i < n; i++ { e.WriteString(sep) ti, elem := indirectPtr(v.Index(i)) switch { case elem.Type() == datetimeType, elem.Type().ConvertibleTo(datetimeType) && options.Has("datetime"): check("datetime") e.marshalDatetimeValue(elem, options) continue case ti != nil: check("string") e.marshalTextValue(ti, options) continue } switch elem.Kind() { case reflect.Bool: check("boolean") e.marshalBoolValue(elem.Bool(), options) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: check("integer") e.marshalIntValue(elem.Int(), options) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: check("integer") e.marshalUintValue(elem.Uint(), options) case reflect.Float32, reflect.Float64: check("float") e.marshalFloatValue(elem.Float(), options) case reflect.String: check("string") e.marshalStringValue(elem.String(), options) case reflect.Array, reflect.Slice: check(e.marshalArrayValue(combineIndexPath(path, i), elem, options)) case reflect.Map: check("table") e.marshalMapValue(combineIndexPath(path, i), elem, options) case reflect.Struct: check("table") e.marshalStructValue(combineIndexPath(path, i), elem, options) case reflect.Ptr, reflect.Interface: panic(&MarshalNilValueError{Type: elem.Type(), As: "array element"}) default: panic(&MarshalTypeError{Type: elem.Type(), As: "array element"}) } sep = ", " } e.WriteString(" ]") return "array" }
func mergeAny(out, in reflect.Value) { if in.Type() == protoMessageType { if !in.IsNil() { if out.IsNil() { out.Set(reflect.ValueOf(Clone(in.Interface().(Message)))) } else { Merge(out.Interface().(Message), in.Interface().(Message)) } } return } switch in.Kind() { case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64: out.Set(in) case reflect.Ptr: if in.IsNil() { return } if out.IsNil() { out.Set(reflect.New(in.Elem().Type())) } mergeAny(out.Elem(), in.Elem()) case reflect.Slice: if in.IsNil() { return } if in.Type().Elem().Kind() == reflect.Uint8 { // []byte is a scalar bytes field, not a repeated field. // Make a deep copy. // Append to []byte{} instead of []byte(nil) so that we never end up // with a nil result. out.SetBytes(append([]byte{}, in.Bytes()...)) return } n := in.Len() if out.IsNil() { out.Set(reflect.MakeSlice(in.Type(), 0, n)) } switch in.Type().Elem().Kind() { case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64: out.Set(reflect.AppendSlice(out, in)) default: for i := 0; i < n; i++ { x := reflect.Indirect(reflect.New(in.Type().Elem())) mergeAny(x, in.Index(i)) out.Set(reflect.Append(out, x)) } } case reflect.Struct: mergeStruct(out, in) default: // unknown type, so not a protocol buffer log.Printf("proto: don't know how to copy %v", in) } }
func (e *Encoder) encodeSlice(av *dynamodb.AttributeValue, v reflect.Value, fieldTag tag) error { switch v.Type().Elem().Kind() { case reflect.Uint8: b := v.Bytes() if len(b) == 0 { encodeNull(av) return nil } av.B = append([]byte{}, b...) default: var elemFn func(dynamodb.AttributeValue) error if fieldTag.AsBinSet || v.Type() == byteSliceSlicetype { // Binary Set av.BS = make([][]byte, 0, v.Len()) elemFn = func(elem dynamodb.AttributeValue) error { if elem.B == nil { return &InvalidMarshalError{msg: "binary set must only contain non-nil byte slices"} } av.BS = append(av.BS, elem.B) return nil } } else if fieldTag.AsNumSet { // Number Set av.NS = make([]*string, 0, v.Len()) elemFn = func(elem dynamodb.AttributeValue) error { if elem.N == nil { return &InvalidMarshalError{msg: "number set must only contain non-nil string numbers"} } av.NS = append(av.NS, elem.N) return nil } } else if fieldTag.AsStrSet { // String Set av.SS = make([]*string, 0, v.Len()) elemFn = func(elem dynamodb.AttributeValue) error { if elem.S == nil { return &InvalidMarshalError{msg: "string set must only contain non-nil strings"} } av.SS = append(av.SS, elem.S) return nil } } else { // List av.L = make([]*dynamodb.AttributeValue, 0, v.Len()) elemFn = func(elem dynamodb.AttributeValue) error { av.L = append(av.L, &elem) return nil } } if n, err := e.encodeList(v, fieldTag, elemFn); err != nil { return err } else if n == 0 { encodeNull(av) } } return nil }
func encodeByteSlice(e *encodeState, name string, fs *fieldSpec, v reflect.Value) { b := v.Bytes() if b == nil { return } e.writeKindName(kindBinary, name) e.WriteUint32(uint32(len(b))) e.WriteByte(0) e.Write(b) }
func NewEncoder(opts ...Options) martini.Handler { return func(c martini.Context, w http.ResponseWriter) { wrappedWriter := newWrappedResponseWriter(w) c.MapTo(wrappedWriter, (*http.ResponseWriter)(nil)) c.MapTo(encoder.JsonEncoder{PrettyPrint: true}, (*encoder.Encoder)(nil)) var rtnHandler martini.ReturnHandler rtnHandler = func(ctx martini.Context, vals []reflect.Value) { rv := ctx.Get(inject.InterfaceOf((*http.ResponseWriter)(nil))) res := rv.Interface().(http.ResponseWriter) var responseVal reflect.Value if len(vals) > 1 && vals[0].Kind() == reflect.Int { res.WriteHeader(int(vals[0].Int())) responseVal = vals[1] } else if len(vals) > 0 { responseVal = vals[0] } if isNil(responseVal) { wrappedRes := res.(*wrappedResponseWriter) code := wrappedRes.statusCode if code == 0 { panic(errors.New("No return code set for error")) } responseVal = reflect.ValueOf(errorResponse{Error: code, Message: http.StatusText(code)}) } if canDeref(responseVal) { responseVal = responseVal.Elem() } if isByteSlice(responseVal) { res.Write(responseVal.Bytes()) } else if isStruct(responseVal) || isStructSlice(responseVal) { encv := ctx.Get(inject.InterfaceOf((*encoder.Encoder)(nil))) enc := encv.Interface().(encoder.Encoder) res.Header().Set("Content-Type", "application/json; charset=utf-8") buf := bytes.NewBuffer(encoder.Must(enc.Encode(responseVal.Interface()))) if len(opts) > 0 { if opts[0].Html { val := buf.Bytes() buf.Reset() json.HTMLEscape(buf, val) } if opts[0].Indent { val := buf.Bytes() buf.Reset() json.Indent(buf, val, "", "\t") } } res.Write(buf.Bytes()) } else { res.Write([]byte(responseVal.String())) } } c.Map(rtnHandler) } }
func saveStructProperty(props *[]datastore.Property, name string, noIndex, multiple bool, v reflect.Value) error { p := datastore.Property{ Name: name, NoIndex: noIndex, Multiple: multiple, } switch x := v.Interface().(type) { case json.Number: s := v.Interface().(json.Number).String() i, err := strconv.ParseInt(s, 10, 64) if err != nil { f, err := strconv.ParseFloat(s, 64) if err != nil { p.Value = s } else { p.Value = f } } else { p.Value = i } case *datastore.Key: p.Value = x case time.Time: p.Value = x case appengine.BlobKey: p.Value = x case appengine.GeoPoint: p.Value = x case datastore.ByteString: p.Value = x default: switch v.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: p.Value = v.Int() case reflect.Bool: p.Value = v.Bool() case reflect.String: p.Value = v.String() case reflect.Float32, reflect.Float64: p.Value = v.Float() case reflect.Slice: if v.Type().Elem().Kind() == reflect.Uint8 { p.NoIndex = true p.Value = v.Bytes() } case reflect.Struct: return fmt.Errorf("datastore: struct field is unsupported") } } if p.Value == nil { return fmt.Errorf("datastore: unsupported struct field type: %v", v.Type()) } *props = append(*props, p) return nil }
// decodeArrayInterface decodes the source value into []interface{} func decodeArrayInterface(sv reflect.Value) interface{} { if sv.Type() == byteSliceType { return sv.Bytes() } arr := []interface{}{} for i := 0; i < sv.Len(); i++ { arr = append(arr, decodeInterface(sv.Index(i))) } return arr }
func encodeByteSlice(b []byte, v reflect.Value) []byte { x := string(v.Bytes()) if n := len(x); n < (0xec - 0xe0) { b = append(b, byte(0xe0+n)) } else { b = encodeK4(b, 0xec, uint64(n)) } return append(b, x...) }
func encodeSlice(v reflect.Value) interface{} { t := v.Type() if t.Elem().Kind() == reflect.Uint8 { return string(v.Bytes()) // Encode byte slices as a single string by default. } n := node{} for i := 0; i < v.Len(); i++ { n[strconv.Itoa(i)] = encodeValue(v.Index(i)) } return n }
func encodeByteSlice(e *encodeState, v reflect.Value, _ bool) { if v.IsNil() { e.WriteString("Z") return } s := v.Bytes() // Represented as an array of uint8. e.WriteString("[$U#") intEncoder(e, reflect.ValueOf(len(s)), false) e.Write(s) // No closing ']' as we're using optimized format here. }
func (e *Encoder) encode(rv reflect.Value) error { switch rk := rv.Kind(); rk { case reflect.Bool: return e.encodeBool(rv.Bool()) case reflect.Int, reflect.Int8, reflect.Int64, reflect.Int32, reflect.Int16: return e.encodeInt(reflect.Int, rv.Int()) case reflect.Uint8, reflect.Uint64, reflect.Uint, reflect.Uint32, reflect.Uint16: return e.encodeInt(reflect.Uint, int64(rv.Uint())) case reflect.String: return e.encodeString(rv.String()) case reflect.Array, reflect.Slice: if rv.Type().Elem().Kind() == reflect.Uint8 { return e.encodeBytes(rv.Bytes()) } else { return e.encodeArray(rv) } case reflect.Map: return e.encodeMap(rv) case reflect.Struct: return e.encodeStruct(rv) case reflect.Float32, reflect.Float64: return e.encodeFloat(float64(rv.Float())) case reflect.Interface: // recurse until we get a concrete type // could be optmized into a tail call return e.encode(rv.Elem()) case reflect.Ptr: if rv.Elem().Kind() == reflect.Struct { switch rv.Elem().Interface().(type) { case None: return e.encodeStruct(rv.Elem()) } } return e.encode(rv.Elem()) case reflect.Invalid: _, err := e.w.Write([]byte{opNone}) return err default: return &TypeError{typ: rk.String()} } return nil }