5 "github.com/modern-go/reflect2"
12 func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder {
13 mapType := typ.(*reflect2.UnsafeMapType)
14 keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), mapType.Key())
15 elemDecoder := decoderOfType(ctx.append("[mapElem]"), mapType.Elem())
18 keyType: mapType.Key(),
19 elemType: mapType.Elem(),
20 keyDecoder: keyDecoder,
21 elemDecoder: elemDecoder,
25 func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder {
26 mapType := typ.(*reflect2.UnsafeMapType)
28 return &sortKeysMapEncoder{
30 keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
31 elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
36 keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
37 elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
41 func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder {
42 decoder := ctx.decoderExtension.CreateMapKeyDecoder(typ)
46 for _, extension := range ctx.extraExtensions {
47 decoder := extension.CreateMapKeyDecoder(typ)
54 return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
56 reflect.Uint8, reflect.Int8,
57 reflect.Uint16, reflect.Int16,
58 reflect.Uint32, reflect.Int32,
59 reflect.Uint64, reflect.Int64,
60 reflect.Uint, reflect.Int,
61 reflect.Float32, reflect.Float64,
63 typ = reflect2.DefaultTypeOfKind(typ.Kind())
64 return &numericMapKeyDecoder{decoderOfType(ctx, typ)}
66 ptrType := reflect2.PtrTo(typ)
67 if ptrType.Implements(unmarshalerType) {
68 return &referenceDecoder{
74 if typ.Implements(unmarshalerType) {
75 return &unmarshalerDecoder{
79 if ptrType.Implements(textUnmarshalerType) {
80 return &referenceDecoder{
81 &textUnmarshalerDecoder{
86 if typ.Implements(textUnmarshalerType) {
87 return &textUnmarshalerDecoder{
91 return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
95 func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder {
96 encoder := ctx.encoderExtension.CreateMapKeyEncoder(typ)
100 for _, extension := range ctx.extraExtensions {
101 encoder := extension.CreateMapKeyEncoder(typ)
108 return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
110 reflect.Uint8, reflect.Int8,
111 reflect.Uint16, reflect.Int16,
112 reflect.Uint32, reflect.Int32,
113 reflect.Uint64, reflect.Int64,
114 reflect.Uint, reflect.Int,
115 reflect.Float32, reflect.Float64,
117 typ = reflect2.DefaultTypeOfKind(typ.Kind())
118 return &numericMapKeyEncoder{encoderOfType(ctx, typ)}
120 if typ == textMarshalerType {
121 return &directTextMarshalerEncoder{
122 stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
125 if typ.Implements(textMarshalerType) {
126 return &textMarshalerEncoder{
128 stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
131 if typ.Kind() == reflect.Interface {
132 return &dynamicMapKeyEncoder{ctx, typ}
134 return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
138 type mapDecoder struct {
139 mapType *reflect2.UnsafeMapType
140 keyType reflect2.Type
141 elemType reflect2.Type
142 keyDecoder ValDecoder
143 elemDecoder ValDecoder
146 func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
147 mapType := decoder.mapType
148 c := iter.nextToken()
150 iter.skipThreeBytes('u', 'l', 'l')
151 *(*unsafe.Pointer)(ptr) = nil
152 mapType.UnsafeSet(ptr, mapType.UnsafeNew())
155 if mapType.UnsafeIsNil(ptr) {
156 mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0))
159 iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
167 iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
171 key := decoder.keyType.UnsafeNew()
172 decoder.keyDecoder.Decode(key, iter)
175 iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
178 elem := decoder.elemType.UnsafeNew()
179 decoder.elemDecoder.Decode(elem, iter)
180 decoder.mapType.UnsafeSetIndex(ptr, key, elem)
181 for c = iter.nextToken(); c == ','; c = iter.nextToken() {
182 key := decoder.keyType.UnsafeNew()
183 decoder.keyDecoder.Decode(key, iter)
186 iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
189 elem := decoder.elemType.UnsafeNew()
190 decoder.elemDecoder.Decode(elem, iter)
191 decoder.mapType.UnsafeSetIndex(ptr, key, elem)
194 iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c}))
198 type numericMapKeyDecoder struct {
202 func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
203 c := iter.nextToken()
205 iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
208 decoder.decoder.Decode(ptr, iter)
211 iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
216 type numericMapKeyEncoder struct {
220 func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
221 stream.writeByte('"')
222 encoder.encoder.Encode(ptr, stream)
223 stream.writeByte('"')
226 func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
230 type dynamicMapKeyEncoder struct {
232 valType reflect2.Type
235 func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
236 obj := encoder.valType.UnsafeIndirect(ptr)
237 encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream)
240 func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
241 obj := encoder.valType.UnsafeIndirect(ptr)
242 return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj))
245 type mapEncoder struct {
246 mapType *reflect2.UnsafeMapType
247 keyEncoder ValEncoder
248 elemEncoder ValEncoder
251 func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
252 stream.WriteObjectStart()
253 iter := encoder.mapType.UnsafeIterate(ptr)
254 for i := 0; iter.HasNext(); i++ {
258 key, elem := iter.UnsafeNext()
259 encoder.keyEncoder.Encode(key, stream)
260 if stream.indention > 0 {
261 stream.writeTwoBytes(byte(':'), byte(' '))
263 stream.writeByte(':')
265 encoder.elemEncoder.Encode(elem, stream)
267 stream.WriteObjectEnd()
270 func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
271 iter := encoder.mapType.UnsafeIterate(ptr)
272 return !iter.HasNext()
275 type sortKeysMapEncoder struct {
276 mapType *reflect2.UnsafeMapType
277 keyEncoder ValEncoder
278 elemEncoder ValEncoder
281 func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
282 if *(*unsafe.Pointer)(ptr) == nil {
286 stream.WriteObjectStart()
287 mapIter := encoder.mapType.UnsafeIterate(ptr)
288 subStream := stream.cfg.BorrowStream(nil)
289 subIter := stream.cfg.BorrowIterator(nil)
290 keyValues := encodedKeyValues{}
291 for mapIter.HasNext() {
292 subStream.buf = make([]byte, 0, 64)
293 key, elem := mapIter.UnsafeNext()
294 encoder.keyEncoder.Encode(key, subStream)
295 if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil {
296 stream.Error = subStream.Error
298 encodedKey := subStream.Buffer()
299 subIter.ResetBytes(encodedKey)
300 decodedKey := subIter.ReadString()
301 if stream.indention > 0 {
302 subStream.writeTwoBytes(byte(':'), byte(' '))
304 subStream.writeByte(':')
306 encoder.elemEncoder.Encode(elem, subStream)
307 keyValues = append(keyValues, encodedKV{
309 keyValue: subStream.Buffer(),
313 for i, keyValue := range keyValues {
317 stream.Write(keyValue.keyValue)
319 stream.WriteObjectEnd()
320 stream.cfg.ReturnStream(subStream)
321 stream.cfg.ReturnIterator(subIter)
324 func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
325 iter := encoder.mapType.UnsafeIterate(ptr)
326 return !iter.HasNext()
329 type encodedKeyValues []encodedKV
331 type encodedKV struct {
336 func (sv encodedKeyValues) Len() int { return len(sv) }
337 func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
338 func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key }