interface.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. package optdec
  2. import (
  3. "encoding"
  4. "encoding/json"
  5. "unsafe"
  6. "reflect"
  7. "github.com/bytedance/sonic/internal/rt"
  8. )
  9. type efaceDecoder struct {
  10. }
  11. func (d *efaceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  12. /* check the defined pointer type for issue 379 */
  13. eface := (*rt.GoEface)(vp)
  14. /*
  15. not pointer type, or nil pointer, or self-pointed interface{}, such as
  16. ```go
  17. var v interface{}
  18. v = &v
  19. return v
  20. ``` see `issue758_test.go`.
  21. */
  22. if eface.Value == nil || eface.Type.Kind() != reflect.Ptr || eface.Value == vp {
  23. ret, err := node.AsEface(ctx)
  24. if err != nil {
  25. return err
  26. }
  27. *(*interface{})(vp) = ret
  28. return nil
  29. }
  30. if node.IsNull() {
  31. if eface.Type.Indirect() || (!eface.Type.Indirect() && eface.Type.Pack().Elem().Kind() != reflect.Ptr) {
  32. *(*interface{})(vp) = nil
  33. return nil
  34. }
  35. }
  36. etp := rt.PtrElem(eface.Type)
  37. vp = eface.Value
  38. if eface.Type.IsNamed() {
  39. // check named pointer type, avoid call its `Unmarshaler`
  40. newp := vp
  41. etp = eface.Type
  42. vp = unsafe.Pointer(&newp)
  43. } else if !eface.Type.Indirect() {
  44. // check direct value
  45. etp = rt.UnpackType(eface.Type.Pack().Elem())
  46. }
  47. dec, err := findOrCompile(etp)
  48. if err != nil {
  49. return err
  50. }
  51. return dec.FromDom(vp, node, ctx)
  52. }
  53. type ifaceDecoder struct {
  54. typ *rt.GoType
  55. }
  56. func (d *ifaceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  57. if node.IsNull() {
  58. *(*unsafe.Pointer)(vp) = nil
  59. return nil
  60. }
  61. iface := *(*rt.GoIface)(vp)
  62. if iface.Itab == nil {
  63. return error_type(d.typ)
  64. }
  65. vt := iface.Itab.Vt
  66. if vt.Kind() != reflect.Ptr || iface.Value == nil {
  67. return error_type(d.typ)
  68. }
  69. etp := rt.PtrElem(vt)
  70. vp = iface.Value
  71. /* check the defined pointer type for issue 379 */
  72. if vt.IsNamed() {
  73. newp := vp
  74. etp = vt
  75. vp = unsafe.Pointer(&newp)
  76. }
  77. dec, err := findOrCompile(etp)
  78. if err != nil {
  79. return err
  80. }
  81. return dec.FromDom(vp, node, ctx)
  82. }
  83. type unmarshalTextDecoder struct {
  84. typ *rt.GoType
  85. }
  86. func (d *unmarshalTextDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  87. if node.IsNull() {
  88. *(*unsafe.Pointer)(vp) = nil
  89. return nil
  90. }
  91. txt, ok := node.AsStringText(ctx)
  92. if !ok {
  93. return error_mismatch(node, ctx, d.typ.Pack())
  94. }
  95. v := *(*interface{})(unsafe.Pointer(&rt.GoEface{
  96. Type: d.typ,
  97. Value: vp,
  98. }))
  99. // fast path
  100. if u, ok := v.(encoding.TextUnmarshaler); ok {
  101. return u.UnmarshalText(txt)
  102. }
  103. // slow path
  104. rv := reflect.ValueOf(v)
  105. if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
  106. return u.UnmarshalText(txt)
  107. }
  108. return error_type(d.typ)
  109. }
  110. type unmarshalJSONDecoder struct {
  111. typ *rt.GoType
  112. strOpt bool
  113. }
  114. func (d *unmarshalJSONDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  115. v := *(*interface{})(unsafe.Pointer(&rt.GoEface{
  116. Type: d.typ,
  117. Value: vp,
  118. }))
  119. var input []byte
  120. if d.strOpt && node.IsNull() {
  121. input = []byte("null")
  122. } else if d.strOpt {
  123. s, ok := node.AsStringText(ctx)
  124. if !ok {
  125. return error_mismatch(node, ctx, d.typ.Pack())
  126. }
  127. input = s
  128. } else {
  129. input = []byte(node.AsRaw(ctx))
  130. }
  131. // fast path
  132. if u, ok := v.(json.Unmarshaler); ok {
  133. return u.UnmarshalJSON((input))
  134. }
  135. // slow path
  136. rv := reflect.ValueOf(v)
  137. if u, ok := rv.Interface().(json.Unmarshaler); ok {
  138. return u.UnmarshalJSON(input)
  139. }
  140. return error_type(d.typ)
  141. }