github.com/goccy/go-json@v0.10.3-0.20240509105655-5e2ae3f23c1d/internal/decoder/wrapped_string.go (about) 1 package decoder 2 3 import ( 4 "fmt" 5 "reflect" 6 "unsafe" 7 8 "github.com/goccy/go-json/internal/runtime" 9 ) 10 11 type wrappedStringDecoder struct { 12 typ *runtime.Type 13 dec Decoder 14 stringDecoder *stringDecoder 15 structName string 16 fieldName string 17 isPtrType bool 18 } 19 20 func newWrappedStringDecoder(typ *runtime.Type, dec Decoder, structName, fieldName string) *wrappedStringDecoder { 21 return &wrappedStringDecoder{ 22 typ: typ, 23 dec: dec, 24 stringDecoder: newStringDecoder(structName, fieldName), 25 structName: structName, 26 fieldName: fieldName, 27 isPtrType: typ.Kind() == reflect.Ptr, 28 } 29 } 30 31 func (d *wrappedStringDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { 32 bytes, err := d.stringDecoder.decodeStreamByte(s) 33 if err != nil { 34 return err 35 } 36 if bytes == nil { 37 if d.isPtrType { 38 *(*unsafe.Pointer)(p) = nil 39 } 40 return nil 41 } 42 b := make([]byte, len(bytes)+1) 43 copy(b, bytes) 44 if _, err := d.dec.Decode(&RuntimeContext{Buf: b}, 0, depth, p); err != nil { 45 return err 46 } 47 return nil 48 } 49 50 func (d *wrappedStringDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { 51 bytes, c, err := d.stringDecoder.decodeByte(ctx.Buf, cursor) 52 if err != nil { 53 return 0, err 54 } 55 if bytes == nil { 56 if d.isPtrType { 57 *(*unsafe.Pointer)(p) = nil 58 } 59 return c, nil 60 } 61 bytes = append(bytes, nul) 62 oldBuf := ctx.Buf 63 ctx.Buf = bytes 64 if _, err := d.dec.Decode(ctx, 0, depth, p); err != nil { 65 return 0, err 66 } 67 ctx.Buf = oldBuf 68 return c, nil 69 } 70 71 func (d *wrappedStringDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) { 72 return nil, 0, fmt.Errorf("json: wrapped string decoder does not support decode path") 73 }