github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/val_encoder.go (about)

     1  package jzon
     2  
     3  import (
     4  	"encoding"
     5  	"encoding/json"
     6  	"reflect"
     7  	"strconv"
     8  	"unsafe"
     9  )
    10  
    11  var (
    12  	globalValEncoders = map[rtype]ValEncoder{}
    13  	encoderKindMap    = [numKinds]rtype{}
    14  	kindEncoders      = [numKinds]ValEncoder{}
    15  	keyEncoders       = [numKinds]keyEncoder{}
    16  )
    17  
    18  func createGlobalValEncoder(ptr interface{}, enc ValEncoder) {
    19  	typ := reflect.TypeOf(ptr).Elem()
    20  	rType := rtypeOfType(typ)
    21  	if !ifaceIndir(rType) {
    22  		panic("not supported")
    23  	}
    24  	globalValEncoders[rType] = enc
    25  }
    26  
    27  func mapEncoderKind(ptr interface{}, enc ValEncoder) {
    28  	elem := reflect.TypeOf(ptr).Elem()
    29  	kind := elem.Kind()
    30  	elemRType := rtypeOfType(elem)
    31  	if !ifaceIndir(elemRType) {
    32  		panic("not supported")
    33  	}
    34  	encoderKindMap[kind] = elemRType
    35  	kindEncoders[kind] = enc
    36  }
    37  
    38  func mapKeyEncoder(ptr interface{}, enc keyEncoder) {
    39  	ptrType := reflect.TypeOf(ptr)
    40  	kind := ptrType.Elem().Kind()
    41  	keyEncoders[kind] = enc
    42  }
    43  
    44  func init() {
    45  	// standard json library types
    46  	createGlobalValEncoder((*json.Number)(nil), (*jsonNumberEncoder)(nil))
    47  	createGlobalValEncoder((*json.RawMessage)(nil), (*jsonRawMessageEncoder)(nil))
    48  	createGlobalValEncoder((*json.Marshaler)(nil), (*dynamicJSONMarshalerEncoder)(nil))
    49  	createGlobalValEncoder((*encoding.TextMarshaler)(nil), (*dynamicTextMarshalerEncoder)(nil))
    50  
    51  	// kind mapping
    52  	mapEncoderKind((*bool)(nil), (*boolEncoder)(nil))
    53  	mapEncoderKind((*string)(nil), (*stringEncoder)(nil))
    54  	if strconv.IntSize == 32 {
    55  		mapEncoderKind((*int)(nil), (*int32Encoder)(nil))
    56  		mapEncoderKind((*uint)(nil), (*uint32Encoder)(nil))
    57  	} else {
    58  		mapEncoderKind((*int)(nil), (*int64Encoder)(nil))
    59  		mapEncoderKind((*uint)(nil), (*uint64Encoder)(nil))
    60  	}
    61  	if unsafe.Sizeof(uintptr(0)) == 4 {
    62  		mapEncoderKind((*uintptr)(nil), (*uint32Encoder)(nil))
    63  	} else {
    64  		mapEncoderKind((*uintptr)(nil), (*uint64Encoder)(nil))
    65  	}
    66  	mapEncoderKind((*int8)(nil), (*int8Encoder)(nil))
    67  	mapEncoderKind((*int16)(nil), (*int16Encoder)(nil))
    68  	mapEncoderKind((*int32)(nil), (*int32Encoder)(nil))
    69  	mapEncoderKind((*int64)(nil), (*int64Encoder)(nil))
    70  	mapEncoderKind((*uint8)(nil), (*uint8Encoder)(nil))
    71  	mapEncoderKind((*uint16)(nil), (*uint16Encoder)(nil))
    72  	mapEncoderKind((*uint32)(nil), (*uint32Encoder)(nil))
    73  	mapEncoderKind((*uint64)(nil), (*uint64Encoder)(nil))
    74  	mapEncoderKind((*float32)(nil), (*float32Encoder)(nil))
    75  	mapEncoderKind((*float64)(nil), (*float64Encoder)(nil))
    76  
    77  	// object key encoders
    78  	mapKeyEncoder((*string)(nil), (*stringKeyEncoder)(nil))
    79  	if strconv.IntSize == 32 {
    80  		mapKeyEncoder((*int)(nil), (*int32KeyEncoder)(nil))
    81  		mapKeyEncoder((*uint)(nil), (*uint32KeyEncoder)(nil))
    82  	} else {
    83  		mapKeyEncoder((*int)(nil), (*int64KeyEncoder)(nil))
    84  		mapKeyEncoder((*uint)(nil), (*uint64KeyEncoder)(nil))
    85  	}
    86  	mapKeyEncoder((*int8)(nil), (*int8KeyEncoder)(nil))
    87  	mapKeyEncoder((*int16)(nil), (*int16KeyEncoder)(nil))
    88  	mapKeyEncoder((*int32)(nil), (*int32KeyEncoder)(nil))
    89  	mapKeyEncoder((*int64)(nil), (*int64KeyEncoder)(nil))
    90  	mapKeyEncoder((*uint8)(nil), (*uint8KeyEncoder)(nil))
    91  	mapKeyEncoder((*uint16)(nil), (*uint16KeyEncoder)(nil))
    92  	mapKeyEncoder((*uint32)(nil), (*uint32KeyEncoder)(nil))
    93  	mapKeyEncoder((*uint64)(nil), (*uint64KeyEncoder)(nil))
    94  	if unsafe.Sizeof(uintptr(0)) == 4 {
    95  		mapKeyEncoder((*uintptr)(nil), (*uint32KeyEncoder)(nil))
    96  	} else {
    97  		mapKeyEncoder((*uintptr)(nil), (*uint64KeyEncoder)(nil))
    98  	}
    99  }
   100  
   101  // EncOpts is the context related encoding option of the object
   102  type EncOpts struct {
   103  	Quoted bool
   104  }
   105  
   106  func (opts *EncOpts) noescape() *EncOpts {
   107  	return (*EncOpts)(noescape(unsafe.Pointer(opts)))
   108  }
   109  
   110  type keyEncoder interface {
   111  	Encode(ptr unsafe.Pointer, s *Streamer)
   112  }
   113  
   114  // ValEncoder is the interface to be implemented for custom encoder
   115  type ValEncoder interface {
   116  	IsEmpty(ptr unsafe.Pointer) bool
   117  
   118  	Encode(ptr unsafe.Pointer, s *Streamer, opts *EncOpts)
   119  }
   120  
   121  type notSupportedEncoder string
   122  
   123  func (enc notSupportedEncoder) IsEmpty(ptr unsafe.Pointer) bool {
   124  	return false
   125  }
   126  
   127  func (enc notSupportedEncoder) Encode(ptr unsafe.Pointer, s *Streamer, opts *EncOpts) {
   128  	if s.Error != nil {
   129  		return
   130  	}
   131  	s.Error = TypeNotSupportedError(enc)
   132  }