github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/jsoni/reflect_struct_decoder.go (about) 1 package jsoni 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "strings" 8 "unsafe" 9 10 "github.com/modern-go/reflect2" 11 ) 12 13 func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder { 14 bindings := map[string]*Binding{} 15 structDescriptor := describeStruct(ctx, typ) 16 for _, binding := range structDescriptor.Fields { 17 for _, fromName := range binding.FromNames { 18 old := bindings[fromName] 19 if old == nil { 20 bindings[fromName] = binding 21 continue 22 } 23 ignoreOld, ignoreNew := resolveConflictBinding(ctx.frozenConfig, old, binding) 24 if ignoreOld { 25 delete(bindings, fromName) 26 } 27 if !ignoreNew { 28 bindings[fromName] = binding 29 } 30 } 31 } 32 fields := map[string]*structFieldDecoder{} 33 for k, binding := range bindings { 34 fields[k] = binding.Decoder.(*structFieldDecoder) 35 } 36 37 if !ctx.caseSensitive() { 38 for k, b := range bindings { 39 if _, found := fields[strings.ToLower(k)]; !found { 40 fields[strings.ToLower(k)] = b.Decoder.(*structFieldDecoder) 41 } 42 } 43 } 44 45 return createStructDecoder(ctx, typ, fields) 46 } 47 48 func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder { 49 if ctx.disallowUnknownFields { 50 return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true} 51 } 52 53 if l := len(fields); l == 0 { 54 return &skipObjectDecoder{} 55 } else if l <= 10 { 56 return createDecoder(ctx, typ, fields) 57 } else { 58 return &generalStructDecoder{typ: typ, fields: fields} 59 } 60 } 61 62 func createDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder { 63 knownHash := map[int64]struct{}{0: {}} 64 hashDecoders := make(map[int64]*structFieldDecoder) 65 for fieldName, fieldDecoder := range fields { 66 fieldHash := calcHash(fieldName, ctx.caseSensitive()) 67 if _, known := knownHash[fieldHash]; known { 68 return &generalStructDecoder{typ: typ, fields: fields} 69 } 70 knownHash[fieldHash] = struct{}{} 71 hashDecoders[fieldHash] = fieldDecoder 72 } 73 return &fieldsStructDecoder{typ: typ, HashDecoders: hashDecoders} 74 } 75 76 type generalStructDecoder struct { 77 typ reflect2.Type 78 fields map[string]*structFieldDecoder 79 disallowUnknownFields bool 80 } 81 82 func (d *generalStructDecoder) Decode(ctx context.Context, ptr unsafe.Pointer, iter *Iterator) { 83 if !iter.readObjectStart() || !iter.incrementDepth() { 84 return 85 } 86 var c byte 87 for c = ','; c == ','; c = iter.nextToken() { 88 d.decodeOneField(ctx, ptr, iter) 89 } 90 if iter.Error != nil && iter.Error != io.EOF && len(d.typ.Type1().Name()) != 0 { 91 iter.Error = fmt.Errorf("%v.%s", d.typ, iter.Error.Error()) 92 } 93 if c != '}' { 94 iter.ReportError("struct Decode", `expect }, but found `+string([]byte{c})) 95 } 96 iter.decrementDepth() 97 } 98 99 func (d *generalStructDecoder) decodeOneField(ctx context.Context, ptr unsafe.Pointer, iter *Iterator) { 100 var field string 101 var fieldDecoder *structFieldDecoder 102 if iter.cfg.objectFieldMustBeSimpleString { 103 fieldBytes := iter.ReadStringAsSlice() 104 field = *(*string)(unsafe.Pointer(&fieldBytes)) 105 fieldDecoder = d.fields[field] 106 if fieldDecoder == nil && !iter.cfg.caseSensitive { 107 fieldDecoder = d.fields[strings.ToLower(field)] 108 } 109 } else { 110 field = iter.ReadString() 111 fieldDecoder = d.fields[field] 112 if fieldDecoder == nil && !iter.cfg.caseSensitive { 113 fieldDecoder = d.fields[strings.ToLower(field)] 114 } 115 } 116 if fieldDecoder == nil { 117 if d.disallowUnknownFields { 118 msg := "found unknown field: " + field 119 iter.ReportError("ReadObject", msg) 120 } 121 if c := iter.nextToken(); c != ':' { 122 iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) 123 } 124 iter.Skip() 125 return 126 } 127 if c := iter.nextToken(); c != ':' { 128 iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) 129 } 130 fieldDecoder.Decode(ctx, ptr, iter) 131 } 132 133 type skipObjectDecoder struct{} 134 135 func (d *skipObjectDecoder) Decode(_ context.Context, _ unsafe.Pointer, iter *Iterator) { 136 valueType := iter.WhatIsNext() 137 if valueType != ObjectValue && valueType != NilValue { 138 iter.ReportError("skipObjectDecoder", "expect object or null") 139 return 140 } 141 iter.Skip() 142 } 143 144 type fieldsStructDecoder struct { 145 typ reflect2.Type 146 HashDecoders map[int64]*structFieldDecoder 147 } 148 149 func (d *fieldsStructDecoder) Decode(ctx context.Context, ptr unsafe.Pointer, iter *Iterator) { 150 if !iter.readObjectStart() || !iter.incrementDepth() { 151 return 152 } 153 for { 154 fieldHash := iter.readFieldHash() 155 if decoder, ok := d.HashDecoders[fieldHash]; ok { 156 decoder.Decode(ctx, ptr, iter) 157 } else { 158 iter.Skip() 159 } 160 161 if iter.isObjectEnd() { 162 break 163 } 164 } 165 if iter.Error != nil && iter.Error != io.EOF && len(d.typ.Type1().Name()) != 0 { 166 iter.Error = fmt.Errorf("%v.%s", d.typ, iter.Error.Error()) 167 } 168 iter.decrementDepth() 169 } 170 171 type structFieldDecoder struct { 172 field reflect2.StructField 173 fieldDecoder ValDecoder 174 } 175 176 func (d *structFieldDecoder) Decode(ctx context.Context, ptr unsafe.Pointer, iter *Iterator) { 177 fieldPtr := d.field.UnsafeGet(ptr) 178 d.fieldDecoder.Decode(ctx, fieldPtr, iter) 179 if iter.Error != nil && iter.Error != io.EOF { 180 iter.Error = fmt.Errorf("%s: %s", d.field.Name(), iter.Error.Error()) 181 } 182 } 183 184 type stringModeStringDecoder struct { 185 elemDecoder ValDecoder 186 cfg *frozenConfig 187 } 188 189 func (d *stringModeStringDecoder) Decode(ctx context.Context, ptr unsafe.Pointer, iter *Iterator) { 190 d.elemDecoder.Decode(ctx, ptr, iter) 191 str := *((*string)(ptr)) 192 tempIter := d.cfg.BorrowIterator([]byte(str)) 193 defer d.cfg.ReturnIterator(tempIter) 194 *((*string)(ptr)) = tempIter.ReadString() 195 } 196 197 type stringModeNumberDecoder struct { 198 decoder ValDecoder 199 } 200 201 func (d *stringModeNumberDecoder) Decode(ctx context.Context, ptr unsafe.Pointer, iter *Iterator) { 202 if iter.WhatIsNext() == NilValue { 203 d.decoder.Decode(ctx, ptr, iter) 204 return 205 } 206 207 if c := iter.nextToken(); c != '"' { 208 iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) 209 return 210 } 211 d.decoder.Decode(ctx, ptr, iter) 212 if iter.Error != nil { 213 return 214 } 215 if c := iter.readByte(); c != '"' { 216 iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) 217 return 218 } 219 } 220 221 type stringModeNumberCompatibleDecoder struct { 222 decoder ValDecoder 223 } 224 225 func (d *stringModeNumberCompatibleDecoder) Decode(ctx context.Context, ptr unsafe.Pointer, iter *Iterator) { 226 if iter.WhatIsNext() == NilValue { 227 d.decoder.Decode(ctx, ptr, iter) 228 return 229 } 230 231 isString := iter.nextToken() == '"' 232 if !isString { 233 iter.unreadByte() 234 } 235 d.decoder.Decode(ctx, ptr, iter) 236 if iter.Error != nil { 237 return 238 } 239 240 if isString { 241 if c := iter.readByte(); c != '"' { 242 iter.ReportError("stringModeNumberCompatibleDecoder", `expect ", but found `+string([]byte{c})) 243 return 244 } 245 } 246 }