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 }