2020-04-19 13:51:22 +03:00
package json
import (
"fmt"
2020-04-21 08:19:50 +03:00
"io"
2020-04-19 13:51:22 +03:00
"reflect"
"strconv"
2020-04-19 14:28:13 +03:00
"strings"
2020-04-19 13:51:22 +03:00
"sync"
"unsafe"
"golang.org/x/xerrors"
)
2020-04-21 08:19:50 +03:00
// An Encoder writes JSON values to an output stream.
2020-04-19 13:51:22 +03:00
type Encoder struct {
2020-04-21 08:19:50 +03:00
w io . Writer
2020-04-19 13:51:22 +03:00
buf [ ] byte
pool sync . Pool
}
type EncodeOp func ( * Encoder , uintptr )
const (
bufSize = 1024
)
var (
encPool sync . Pool
cachedEncodeOp map [ string ] EncodeOp
)
func init ( ) {
encPool = sync . Pool {
New : func ( ) interface { } {
return & Encoder {
buf : make ( [ ] byte , 0 , bufSize ) ,
pool : encPool ,
}
} ,
}
cachedEncodeOp = map [ string ] EncodeOp { }
}
2020-04-21 08:19:50 +03:00
// NewEncoder returns a new encoder that writes to w.
func NewEncoder ( w io . Writer ) * Encoder {
2020-04-19 13:51:22 +03:00
enc := encPool . Get ( ) . ( * Encoder )
2020-04-21 08:19:50 +03:00
enc . w = w
enc . reset ( )
2020-04-19 13:51:22 +03:00
return enc
}
2020-04-21 08:19:50 +03:00
// Encode writes the JSON encoding of v to the stream, followed by a newline character.
//
// See the documentation for Marshal for details about the conversion of Go values to JSON.
func ( e * Encoder ) Encode ( v interface { } ) error {
2020-04-24 14:23:26 +03:00
if err := e . encode ( v ) ; err != nil {
2020-04-21 08:19:50 +03:00
return err
}
if _ , err := e . w . Write ( e . buf ) ; err != nil {
return err
}
return nil
}
func ( e * Encoder ) encodeForMarshal ( v interface { } ) ( [ ] byte , error ) {
2020-04-24 14:23:26 +03:00
if err := e . encode ( v ) ; err != nil {
2020-04-21 08:19:50 +03:00
return nil , err
}
copied := make ( [ ] byte , len ( e . buf ) )
copy ( copied , e . buf )
return copied , nil
}
// SetEscapeHTML specifies whether problematic HTML characters should be escaped inside JSON quoted strings.
// The default behavior is to escape &, <, and > to \u0026, \u003c, and \u003e to avoid certain safety problems that can arise when embedding JSON in HTML.
//
// In non-HTML settings where the escaping interferes with the readability of the output, SetEscapeHTML(false) disables this behavior.
func ( e * Encoder ) SetEscapeHTML ( on bool ) {
}
// SetIndent instructs the encoder to format each subsequent encoded value as if indented by the package-level function Indent(dst, src, prefix, indent).
// Calling SetIndent("", "") disables indentation.
func ( e * Encoder ) SetIndent ( prefix , indent string ) {
}
func ( e * Encoder ) release ( ) {
e . w = nil
2020-04-22 07:06:52 +03:00
e . pool . Put ( e )
2020-04-19 13:51:22 +03:00
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) reset ( ) {
2020-04-19 13:51:22 +03:00
e . buf = e . buf [ : 0 ]
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeInt ( v int ) {
e . encodeInt64 ( int64 ( v ) )
2020-04-19 13:51:22 +03:00
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeInt8 ( v int8 ) {
e . encodeInt64 ( int64 ( v ) )
2020-04-19 13:51:22 +03:00
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeInt16 ( v int16 ) {
e . encodeInt64 ( int64 ( v ) )
2020-04-19 13:51:22 +03:00
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeInt32 ( v int32 ) {
e . encodeInt64 ( int64 ( v ) )
2020-04-19 13:51:22 +03:00
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeInt64 ( v int64 ) {
2020-04-19 13:51:22 +03:00
e . buf = strconv . AppendInt ( e . buf , v , 10 )
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeUint ( v uint ) {
e . encodeUint64 ( uint64 ( v ) )
2020-04-19 13:51:22 +03:00
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeUint8 ( v uint8 ) {
e . encodeUint64 ( uint64 ( v ) )
2020-04-19 13:51:22 +03:00
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeUint16 ( v uint16 ) {
e . encodeUint64 ( uint64 ( v ) )
2020-04-19 13:51:22 +03:00
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeUint32 ( v uint32 ) {
e . encodeUint64 ( uint64 ( v ) )
2020-04-19 13:51:22 +03:00
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeUint64 ( v uint64 ) {
2020-04-19 13:51:22 +03:00
e . buf = strconv . AppendUint ( e . buf , v , 10 )
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeFloat32 ( v float32 ) {
2020-04-19 13:51:22 +03:00
e . buf = strconv . AppendFloat ( e . buf , float64 ( v ) , 'f' , - 1 , 32 )
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeFloat64 ( v float64 ) {
2020-04-19 13:51:22 +03:00
e . buf = strconv . AppendFloat ( e . buf , v , 'f' , - 1 , 64 )
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeBool ( v bool ) {
2020-04-19 13:51:22 +03:00
e . buf = strconv . AppendBool ( e . buf , v )
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeString ( s string ) {
2020-04-19 13:51:22 +03:00
b := * ( * [ ] byte ) ( unsafe . Pointer ( & s ) )
e . buf = append ( e . buf , b ... )
}
2020-04-21 08:19:50 +03:00
func ( e * Encoder ) encodeByte ( b byte ) {
2020-04-19 13:51:22 +03:00
e . buf = append ( e . buf , b )
}
2020-04-24 14:23:26 +03:00
func ( e * Encoder ) encode ( v interface { } ) error {
header := ( * interfaceHeader ) ( unsafe . Pointer ( & v ) )
typ := header . typ
2020-04-20 11:13:03 +03:00
name := typ . String ( )
2020-04-19 13:51:22 +03:00
if op , exists := cachedEncodeOp [ name ] ; exists {
2020-04-24 14:23:26 +03:00
op ( e , uintptr ( header . ptr ) )
2020-04-21 08:19:50 +03:00
return nil
2020-04-19 13:51:22 +03:00
}
2020-04-20 11:13:03 +03:00
if typ . Kind ( ) == reflect . Ptr {
2020-04-22 09:29:54 +03:00
typ = typ . Elem ( )
2020-04-20 11:13:03 +03:00
}
2020-04-22 09:29:54 +03:00
op , err := e . compile ( typ )
2020-04-19 13:51:22 +03:00
if err != nil {
2020-04-21 08:19:50 +03:00
return err
2020-04-19 13:51:22 +03:00
}
2020-04-19 17:13:24 +03:00
if name != "" {
cachedEncodeOp [ name ] = op
}
2020-04-24 14:23:26 +03:00
op ( e , uintptr ( header . ptr ) )
2020-04-21 08:19:50 +03:00
return nil
2020-04-19 13:51:22 +03:00
}
2020-04-24 14:23:26 +03:00
func ( e * Encoder ) compile ( typ * rtype ) ( EncodeOp , error ) {
2020-04-22 09:29:54 +03:00
switch typ . Kind ( ) {
2020-04-19 13:51:22 +03:00
case reflect . Ptr :
2020-04-22 09:29:54 +03:00
return e . compilePtr ( typ )
2020-04-19 17:13:24 +03:00
case reflect . Slice :
2020-04-22 09:29:54 +03:00
return e . compileSlice ( typ )
2020-04-19 13:51:22 +03:00
case reflect . Struct :
2020-04-22 09:29:54 +03:00
return e . compileStruct ( typ )
2020-04-20 18:06:27 +03:00
case reflect . Map :
2020-04-22 09:29:54 +03:00
return e . compileMap ( typ )
2020-04-21 07:19:53 +03:00
case reflect . Array :
2020-04-22 09:29:54 +03:00
return e . compileArray ( typ )
2020-04-19 13:51:22 +03:00
case reflect . Int :
return e . compileInt ( )
case reflect . Int8 :
return e . compileInt8 ( )
case reflect . Int16 :
return e . compileInt16 ( )
case reflect . Int32 :
return e . compileInt32 ( )
case reflect . Int64 :
return e . compileInt64 ( )
2020-04-19 17:13:24 +03:00
case reflect . Uint :
return e . compileUint ( )
case reflect . Uint8 :
return e . compileUint8 ( )
case reflect . Uint16 :
return e . compileUint16 ( )
case reflect . Uint32 :
return e . compileUint32 ( )
case reflect . Uint64 :
return e . compileUint64 ( )
2020-04-21 07:38:48 +03:00
case reflect . Uintptr :
return e . compileUint ( )
2020-04-19 13:51:22 +03:00
case reflect . Float32 :
return e . compileFloat32 ( )
case reflect . Float64 :
return e . compileFloat64 ( )
case reflect . String :
return e . compileString ( )
case reflect . Bool :
return e . compileBool ( )
2020-04-21 07:19:53 +03:00
case reflect . Interface :
return nil , ErrCompileSlowPath
2020-04-19 13:51:22 +03:00
}
2020-04-24 14:23:26 +03:00
return nil , xerrors . Errorf ( "failed to encode type %s: %w" , typ . String ( ) , ErrUnsupportedType )
2020-04-19 13:51:22 +03:00
}
2020-04-24 14:23:26 +03:00
func ( e * Encoder ) compilePtr ( typ * rtype ) ( EncodeOp , error ) {
2020-04-22 09:29:54 +03:00
op , err := e . compile ( typ . Elem ( ) )
2020-04-19 21:25:26 +03:00
if err != nil {
return nil , err
}
return func ( enc * Encoder , p uintptr ) {
op ( enc , e . ptrToPtr ( p ) )
} , nil
}
2020-04-19 13:51:22 +03:00
func ( e * Encoder ) compileInt ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeInt ( e . ptrToInt ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
func ( e * Encoder ) compileInt8 ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeInt8 ( e . ptrToInt8 ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
func ( e * Encoder ) compileInt16 ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeInt16 ( e . ptrToInt16 ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
func ( e * Encoder ) compileInt32 ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeInt32 ( e . ptrToInt32 ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
func ( e * Encoder ) compileInt64 ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeInt64 ( e . ptrToInt64 ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
func ( e * Encoder ) compileUint ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeUint ( e . ptrToUint ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
func ( e * Encoder ) compileUint8 ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeUint8 ( e . ptrToUint8 ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
func ( e * Encoder ) compileUint16 ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeUint16 ( e . ptrToUint16 ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
func ( e * Encoder ) compileUint32 ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeUint32 ( e . ptrToUint32 ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
func ( e * Encoder ) compileUint64 ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeUint64 ( e . ptrToUint64 ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
func ( e * Encoder ) compileFloat32 ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeFloat32 ( e . ptrToFloat32 ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
func ( e * Encoder ) compileFloat64 ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeFloat64 ( e . ptrToFloat64 ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
func ( e * Encoder ) compileString ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeEscapedString ( e . ptrToString ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
func ( e * Encoder ) compileBool ( ) ( EncodeOp , error ) {
2020-04-21 08:19:50 +03:00
return func ( enc * Encoder , p uintptr ) { enc . encodeBool ( e . ptrToBool ( p ) ) } , nil
2020-04-19 13:51:22 +03:00
}
2020-04-24 14:23:26 +03:00
func ( e * Encoder ) compileSlice ( typ * rtype ) ( EncodeOp , error ) {
2020-04-19 17:13:24 +03:00
size := typ . Elem ( ) . Size ( )
2020-04-22 09:29:54 +03:00
op , err := e . compile ( typ . Elem ( ) )
2020-04-19 17:13:24 +03:00
if err != nil {
return nil , err
}
return func ( enc * Encoder , base uintptr ) {
2020-04-19 21:25:26 +03:00
if base == 0 {
2020-04-21 08:19:50 +03:00
enc . encodeString ( "null" )
2020-04-19 21:25:26 +03:00
return
}
2020-04-21 08:19:50 +03:00
enc . encodeByte ( '[' )
2020-04-19 17:13:24 +03:00
slice := ( * reflect . SliceHeader ) ( unsafe . Pointer ( base ) )
num := slice . Len
for i := 0 ; i < num ; i ++ {
op ( enc , slice . Data + uintptr ( i ) * size )
if i != num - 1 {
2020-04-21 08:19:50 +03:00
enc . encodeByte ( ',' )
2020-04-19 17:13:24 +03:00
}
}
2020-04-21 08:19:50 +03:00
enc . encodeByte ( ']' )
2020-04-19 17:13:24 +03:00
} , nil
2020-04-21 07:19:53 +03:00
}
2020-04-19 17:13:24 +03:00
2020-04-24 14:23:26 +03:00
func ( e * Encoder ) compileArray ( typ * rtype ) ( EncodeOp , error ) {
2020-04-21 07:19:53 +03:00
alen := typ . Len ( )
size := typ . Elem ( ) . Size ( )
2020-04-22 09:29:54 +03:00
op , err := e . compile ( typ . Elem ( ) )
2020-04-21 07:19:53 +03:00
if err != nil {
return nil , err
}
return func ( enc * Encoder , base uintptr ) {
if base == 0 {
2020-04-21 08:19:50 +03:00
enc . encodeString ( "null" )
2020-04-21 07:19:53 +03:00
return
}
2020-04-21 08:19:50 +03:00
enc . encodeByte ( '[' )
2020-04-21 07:19:53 +03:00
for i := 0 ; i < alen ; i ++ {
if i != 0 {
2020-04-21 08:19:50 +03:00
enc . encodeByte ( ',' )
2020-04-21 07:19:53 +03:00
}
op ( enc , base + uintptr ( i ) * size )
}
2020-04-21 08:19:50 +03:00
enc . encodeByte ( ']' )
2020-04-21 07:19:53 +03:00
} , nil
2020-04-19 17:13:24 +03:00
}
2020-04-21 07:38:48 +03:00
func ( e * Encoder ) getTag ( field reflect . StructField ) string {
return field . Tag . Get ( "json" )
}
func ( e * Encoder ) isIgnoredStructField ( field reflect . StructField ) bool {
if field . PkgPath != "" && ! field . Anonymous {
// private field
return true
}
tag := e . getTag ( field )
if tag == "-" {
return true
}
return false
}
2020-04-24 14:23:26 +03:00
func ( e * Encoder ) compileStruct ( typ * rtype ) ( EncodeOp , error ) {
2020-04-19 17:13:24 +03:00
fieldNum := typ . NumField ( )
2020-04-19 13:51:22 +03:00
opQueue := make ( [ ] EncodeOp , 0 , fieldNum )
for i := 0 ; i < fieldNum ; i ++ {
field := typ . Field ( i )
2020-04-21 07:38:48 +03:00
if e . isIgnoredStructField ( field ) {
continue
}
2020-04-19 14:28:13 +03:00
keyName := field . Name
2020-04-21 07:38:48 +03:00
tag := e . getTag ( field )
2020-04-19 14:28:13 +03:00
opts := strings . Split ( tag , "," )
if len ( opts ) > 0 {
if opts [ 0 ] != "" {
keyName = opts [ 0 ]
}
}
2020-04-24 14:23:26 +03:00
fieldType := type2rtype ( field . Type )
op , err := e . compile ( fieldType )
2020-04-19 13:51:22 +03:00
if err != nil {
return nil , err
}
2020-04-19 14:28:13 +03:00
key := fmt . Sprintf ( ` "%s": ` , keyName )
2020-04-19 13:51:22 +03:00
opQueue = append ( opQueue , func ( enc * Encoder , base uintptr ) {
2020-04-21 08:19:50 +03:00
enc . encodeString ( key )
2020-04-19 13:51:22 +03:00
op ( enc , base + field . Offset )
} )
}
queueNum := len ( opQueue )
return func ( enc * Encoder , base uintptr ) {
2020-04-19 21:25:26 +03:00
if base == 0 {
2020-04-21 08:19:50 +03:00
enc . encodeString ( "null" )
2020-04-19 21:25:26 +03:00
return
}
2020-04-21 08:19:50 +03:00
enc . encodeByte ( '{' )
2020-04-19 13:51:22 +03:00
for i := 0 ; i < queueNum ; i ++ {
opQueue [ i ] ( enc , base )
if i != queueNum - 1 {
2020-04-21 08:19:50 +03:00
enc . encodeByte ( ',' )
2020-04-19 13:51:22 +03:00
}
}
2020-04-21 08:19:50 +03:00
enc . encodeByte ( '}' )
2020-04-19 13:51:22 +03:00
} , nil
}
2020-04-20 18:06:27 +03:00
//go:linkname mapiterinit reflect.mapiterinit
func mapiterinit ( mapType unsafe . Pointer , m unsafe . Pointer ) unsafe . Pointer
//go:linkname mapiterkey reflect.mapiterkey
func mapiterkey ( it unsafe . Pointer ) unsafe . Pointer
//go:linkname mapitervalue reflect.mapitervalue
func mapitervalue ( it unsafe . Pointer ) unsafe . Pointer
//go:linkname mapiternext reflect.mapiternext
func mapiternext ( it unsafe . Pointer )
//go:linkname maplen reflect.maplen
func maplen ( m unsafe . Pointer ) int
type valueType struct {
typ unsafe . Pointer
ptr unsafe . Pointer
}
2020-04-24 14:23:26 +03:00
func ( e * Encoder ) compileMap ( typ * rtype ) ( EncodeOp , error ) {
mapType := unsafe . Pointer ( typ )
2020-04-22 09:29:54 +03:00
keyOp , err := e . compile ( typ . Key ( ) )
2020-04-20 18:06:27 +03:00
if err != nil {
return nil , err
}
2020-04-22 09:29:54 +03:00
valueOp , err := e . compile ( typ . Elem ( ) )
2020-04-20 18:06:27 +03:00
if err != nil {
return nil , err
}
return func ( enc * Encoder , base uintptr ) {
if base == 0 {
2020-04-21 08:19:50 +03:00
enc . encodeString ( "null" )
2020-04-20 18:06:27 +03:00
return
}
2020-04-21 08:19:50 +03:00
enc . encodeByte ( '{' )
2020-04-20 18:06:27 +03:00
mlen := maplen ( unsafe . Pointer ( base ) )
iter := mapiterinit ( mapType , unsafe . Pointer ( base ) )
for i := 0 ; i < mlen ; i ++ {
key := mapiterkey ( iter )
if i != 0 {
2020-04-21 08:19:50 +03:00
enc . encodeByte ( ',' )
2020-04-20 18:06:27 +03:00
}
value := mapitervalue ( iter )
keyOp ( enc , uintptr ( key ) )
2020-04-21 08:19:50 +03:00
enc . encodeByte ( ':' )
2020-04-20 18:06:27 +03:00
valueOp ( enc , uintptr ( value ) )
mapiternext ( iter )
}
2020-04-21 08:19:50 +03:00
enc . encodeByte ( '}' )
2020-04-20 18:06:27 +03:00
} , nil
}
2020-04-19 21:25:26 +03:00
func ( e * Encoder ) ptrToPtr ( p uintptr ) uintptr { return * ( * uintptr ) ( unsafe . Pointer ( p ) ) }
2020-04-19 13:51:22 +03:00
func ( e * Encoder ) ptrToInt ( p uintptr ) int { return * ( * int ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToInt8 ( p uintptr ) int8 { return * ( * int8 ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToInt16 ( p uintptr ) int16 { return * ( * int16 ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToInt32 ( p uintptr ) int32 { return * ( * int32 ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToInt64 ( p uintptr ) int64 { return * ( * int64 ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToUint ( p uintptr ) uint { return * ( * uint ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToUint8 ( p uintptr ) uint8 { return * ( * uint8 ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToUint16 ( p uintptr ) uint16 { return * ( * uint16 ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToUint32 ( p uintptr ) uint32 { return * ( * uint32 ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToUint64 ( p uintptr ) uint64 { return * ( * uint64 ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToFloat32 ( p uintptr ) float32 { return * ( * float32 ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToFloat64 ( p uintptr ) float64 { return * ( * float64 ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToBool ( p uintptr ) bool { return * ( * bool ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToByte ( p uintptr ) byte { return * ( * byte ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToBytes ( p uintptr ) [ ] byte { return * ( * [ ] byte ) ( unsafe . Pointer ( p ) ) }
func ( e * Encoder ) ptrToString ( p uintptr ) string { return * ( * string ) ( unsafe . Pointer ( p ) ) }