forked from mirror/go-json
Get pointer from interface{} (FYI: https://golang.org/src/reflect/value.go )
This commit is contained in:
parent
c515899c6d
commit
f1ad87fd71
31
encode.go
31
encode.go
|
@ -114,32 +114,37 @@ func (e *Encoder) EncodeByte(b byte) {
|
||||||
e.buf = append(e.buf, b)
|
e.buf = append(e.buf, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) Encode(v interface{}) ([]byte, error) {
|
type rtype struct{}
|
||||||
rv := reflect.ValueOf(v)
|
|
||||||
if rv.Kind() != reflect.Ptr {
|
type interfaceHeader struct {
|
||||||
newV := reflect.New(rv.Type())
|
typ *rtype
|
||||||
newV.Elem().Set(rv)
|
ptr unsafe.Pointer
|
||||||
rv = newV
|
|
||||||
}
|
|
||||||
return e.encode(rv)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) encode(v reflect.Value) ([]byte, error) {
|
func (e *Encoder) Encode(v interface{}) ([]byte, error) {
|
||||||
name := v.Type().String()
|
header := (*interfaceHeader)(unsafe.Pointer(&v))
|
||||||
|
return e.encode(reflect.TypeOf(v), header.ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) encode(typ reflect.Type, ptr unsafe.Pointer) ([]byte, error) {
|
||||||
|
name := typ.String()
|
||||||
if op, exists := cachedEncodeOp[name]; exists {
|
if op, exists := cachedEncodeOp[name]; exists {
|
||||||
op(e, v.Pointer())
|
op(e, uintptr(ptr))
|
||||||
copied := make([]byte, len(e.buf))
|
copied := make([]byte, len(e.buf))
|
||||||
copy(copied, e.buf)
|
copy(copied, e.buf)
|
||||||
return copied, nil
|
return copied, nil
|
||||||
}
|
}
|
||||||
op, err := e.compile(v.Elem().Type())
|
if typ.Kind() == reflect.Ptr {
|
||||||
|
typ = typ.Elem()
|
||||||
|
}
|
||||||
|
op, err := e.compile(typ)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if name != "" {
|
if name != "" {
|
||||||
cachedEncodeOp[name] = op
|
cachedEncodeOp[name] = op
|
||||||
}
|
}
|
||||||
op(e, v.Pointer())
|
op(e, uintptr(ptr))
|
||||||
copied := make([]byte, len(e.buf))
|
copied := make([]byte, len(e.buf))
|
||||||
copy(copied, e.buf)
|
copy(copied, e.buf)
|
||||||
return copied, nil
|
return copied, nil
|
||||||
|
|
Loading…
Reference in New Issue