예제 #1
0
파일: encode.go 프로젝트: qiangmzsx/golang
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))
}
예제 #2
0
파일: field.go 프로젝트: bjyoungblood/struc
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)
	}
}
예제 #3
0
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()))
		}
	}
}
예제 #4
0
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)
	}
}
예제 #5
0
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
}
예제 #6
0
파일: decode.go 프로젝트: MG-RAST/Shock
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))
	}
}
예제 #7
0
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
}
예제 #8
0
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
}
예제 #9
0
파일: pack.go 프로젝트: bchangizi/Sereal
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
}
예제 #10
0
func marshalBytesValue(value reflect.Value) *dynamodb.AttributeValue {
	if value.IsNil() {
		return makeNullAttrValue()
	}

	return &dynamodb.AttributeValue{B: value.Bytes()}
}
예제 #11
0
파일: db.go 프로젝트: jmptrader/unbolted
/*
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
}
예제 #12
0
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)
	}
}
예제 #13
0
파일: encode.go 프로젝트: dams/Sereal
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

}
예제 #14
0
파일: marshal.go 프로젝트: timnau/golang
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()
}
예제 #15
0
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)
			}
		}
	}
}
예제 #16
0
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}
}
예제 #17
0
파일: entity.go 프로젝트: Mehokm/golem
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()))))
	}
}
예제 #18
0
파일: encode.go 프로젝트: sreis/go
// 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)
	}
}
예제 #19
0
파일: encode.go 프로젝트: JonPulfer/og-rek
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
}
예제 #20
0
파일: encode.go 프로젝트: kezhuw/toml
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"
}
예제 #21
0
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)
	}
}
예제 #22
0
파일: encode.go 프로젝트: Xercoy/aws-sdk-go
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
}
예제 #23
0
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)
}
예제 #24
0
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)
	}
}
예제 #25
0
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
}
예제 #26
0
// 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
}
예제 #27
0
파일: encoder.go 프로젝트: erkl/binn
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...)
}
예제 #28
0
파일: encode.go 프로젝트: henryren/form
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
}
예제 #29
0
파일: encode.go 프로젝트: cesanta/ubjson
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.
}
예제 #30
0
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
}