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

     1  package jzon
     2  
     3  import (
     4  	"encoding"
     5  	"reflect"
     6  	"unsafe"
     7  )
     8  
     9  type mapEncoderBuilder struct {
    10  	encoder   *directMapEncoder
    11  	elemRType rtype
    12  }
    13  
    14  func newMapEncoder(mapType reflect.Type) *mapEncoderBuilder {
    15  	keyType := mapType.Key()
    16  	var (
    17  		keyEncoder keyEncoder
    18  	)
    19  	keyRType := rtypeOfType(keyType)
    20  	keyKind := keyType.Kind()
    21  	switch {
    22  	case keyKind == reflect.String:
    23  		keyEncoder = keyEncoders[keyKind]
    24  	case keyType.Implements(textMarshalerType):
    25  		if ifaceIndir(keyRType) {
    26  			keyEncoder = textMarshalerKeyEncoder(keyRType)
    27  		} else {
    28  			keyEncoder = directTextMarshalerKeyEncoder(keyRType)
    29  		}
    30  	default:
    31  		if keyEncoder = keyEncoders[keyKind]; keyEncoder == nil {
    32  			return nil
    33  		}
    34  	}
    35  	return &mapEncoderBuilder{
    36  		encoder: &directMapEncoder{
    37  			mapRType: rtypeOfType(mapType),
    38  			// keyRType:   keyRType,
    39  			keyEncoder: keyEncoder,
    40  		},
    41  		elemRType: rtypeOfType(mapType.Elem()),
    42  	}
    43  }
    44  
    45  type directMapEncoder struct {
    46  	mapRType rtype
    47  
    48  	// keyRType   rtype
    49  	keyEncoder keyEncoder
    50  
    51  	elemEncoder ValEncoder
    52  }
    53  
    54  func (enc *directMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
    55  	ptr = *(*unsafe.Pointer)(ptr)
    56  	return maplen(ptr) == 0
    57  }
    58  
    59  // text marshaler
    60  type textMarshalerKeyEncoder rtype
    61  
    62  func (enc textMarshalerKeyEncoder) Encode(ptr unsafe.Pointer, s *Streamer) {
    63  	if s.Error != nil {
    64  		return
    65  	}
    66  	rtype := rtype(enc)
    67  	obj := packEFace(rtype, ptr)
    68  	marshaler := obj.(encoding.TextMarshaler)
    69  	b, err := marshaler.MarshalText()
    70  	if err != nil {
    71  		s.Error = err
    72  		return
    73  	}
    74  	s.String(localByteToString(b))
    75  	s.buffer = append(s.buffer, ':')
    76  	s.poped = false
    77  }
    78  
    79  type directTextMarshalerKeyEncoder rtype
    80  
    81  func (enc directTextMarshalerKeyEncoder) Encode(ptr unsafe.Pointer, s *Streamer) {
    82  	if s.Error != nil {
    83  		return
    84  	}
    85  	rtype := rtype(enc)
    86  	// go1.14 ignore the error silently
    87  	// check `func (w *reflectWithString) resolve()` in encoding/json
    88  	ptr = *(*unsafe.Pointer)(ptr)
    89  	if ptr == nil {
    90  		s.String("")
    91  	} else {
    92  		obj := packEFace(rtype, ptr)
    93  		marshaler := obj.(encoding.TextMarshaler)
    94  		b, err := marshaler.MarshalText()
    95  		if err != nil {
    96  			s.Error = err
    97  			return
    98  		}
    99  		s.String(localByteToString(b))
   100  	}
   101  	s.buffer = append(s.buffer, ':')
   102  	s.poped = false
   103  }
   104  
   105  // key encoders
   106  type stringKeyEncoder struct{}
   107  
   108  func (*stringKeyEncoder) Encode(ptr unsafe.Pointer, s *Streamer) {
   109  	s.Field(*(*string)(ptr))
   110  }
   111  
   112  // int encoders
   113  type int8KeyEncoder struct{}
   114  
   115  func (*int8KeyEncoder) Encode(ptr unsafe.Pointer, s *Streamer) {
   116  	if s.Error != nil {
   117  		return
   118  	}
   119  	var b [6]byte // `"-128"` max length is 6
   120  	b[0] = '"'
   121  	buf := appendInt8(b[:1], *(*int8)(ptr))
   122  	buf = append(buf, '"')
   123  	s.RawField(buf)
   124  }
   125  
   126  type int16KeyEncoder struct{}
   127  
   128  func (*int16KeyEncoder) Encode(ptr unsafe.Pointer, s *Streamer) {
   129  	if s.Error != nil {
   130  		return
   131  	}
   132  	var b [8]byte // `"-32768"` max length is 8
   133  	b[0] = '"'
   134  	buf := appendInt16(b[:1], *(*int16)(ptr))
   135  	buf = append(buf, '"')
   136  	s.RawField(buf)
   137  }
   138  
   139  type int32KeyEncoder struct{}
   140  
   141  func (*int32KeyEncoder) Encode(ptr unsafe.Pointer, s *Streamer) {
   142  	if s.Error != nil {
   143  		return
   144  	}
   145  	var b [13]byte // `"-2147483648"` max length is 13
   146  	b[0] = '"'
   147  	buf := appendInt32(b[:1], *(*int32)(ptr))
   148  	buf = append(buf, '"')
   149  	s.RawField(buf)
   150  }
   151  
   152  type int64KeyEncoder struct{}
   153  
   154  func (*int64KeyEncoder) Encode(ptr unsafe.Pointer, s *Streamer) {
   155  	if s.Error != nil {
   156  		return
   157  	}
   158  	var b [22]byte // `"-9223372036854775808"` max length is 22
   159  	b[0] = '"'
   160  	buf := appendInt64(b[:1], *(*int64)(ptr))
   161  	buf = append(buf, '"')
   162  	s.RawField(buf)
   163  }
   164  
   165  // uint encoders
   166  type uint8KeyEncoder struct{}
   167  
   168  func (*uint8KeyEncoder) Encode(ptr unsafe.Pointer, s *Streamer) {
   169  	if s.Error != nil {
   170  		return
   171  	}
   172  	var b [6]byte // `"-128"` max length is 6
   173  	b[0] = '"'
   174  	buf := appendUint8(b[:1], *(*uint8)(ptr))
   175  	buf = append(buf, '"')
   176  	s.RawField(buf)
   177  }
   178  
   179  type uint16KeyEncoder struct{}
   180  
   181  func (*uint16KeyEncoder) Encode(ptr unsafe.Pointer, s *Streamer) {
   182  	if s.Error != nil {
   183  		return
   184  	}
   185  	var b [8]byte // `"-32768"` max length is 8
   186  	b[0] = '"'
   187  	buf := appendUint16(b[:1], *(*uint16)(ptr))
   188  	buf = append(buf, '"')
   189  	s.RawField(buf)
   190  }
   191  
   192  type uint32KeyEncoder struct{}
   193  
   194  func (*uint32KeyEncoder) Encode(ptr unsafe.Pointer, s *Streamer) {
   195  	if s.Error != nil {
   196  		return
   197  	}
   198  	var b [13]byte // `"-2147483648"` max length is 13
   199  	b[0] = '"'
   200  	buf := appendUint32(b[:1], *(*uint32)(ptr))
   201  	buf = append(buf, '"')
   202  	s.RawField(buf)
   203  }
   204  
   205  type uint64KeyEncoder struct{}
   206  
   207  func (*uint64KeyEncoder) Encode(ptr unsafe.Pointer, s *Streamer) {
   208  	if s.Error != nil {
   209  		return
   210  	}
   211  	var b [22]byte // `"-9223372036854775808"` max length is 22
   212  	b[0] = '"'
   213  	buf := appendUint64(b[:1], *(*uint64)(ptr))
   214  	buf = append(buf, '"')
   215  	s.RawField(buf)
   216  }