slice.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. package optdec
  2. import (
  3. "reflect"
  4. "unsafe"
  5. "github.com/bytedance/sonic/internal/rt"
  6. )
  7. type sliceDecoder struct {
  8. elemType *rt.GoType
  9. elemDec decFunc
  10. typ reflect.Type
  11. }
  12. var (
  13. emptyPtr = &struct{}{}
  14. )
  15. func (d *sliceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  16. if node.IsNull() {
  17. *(*rt.GoSlice)(vp) = rt.GoSlice{}
  18. return nil
  19. }
  20. arr, ok := node.AsArr()
  21. if !ok {
  22. return error_mismatch(node, ctx, d.typ)
  23. }
  24. slice := rt.MakeSlice(vp, d.elemType, arr.Len())
  25. elems := slice.Ptr
  26. next := arr.Children()
  27. var gerr error
  28. for i := 0; i < arr.Len(); i++ {
  29. val := NewNode(next)
  30. elem := unsafe.Pointer(uintptr(elems) + uintptr(i)*d.elemType.Size)
  31. err := d.elemDec.FromDom(elem, val, ctx)
  32. if gerr == nil && err != nil {
  33. gerr = err
  34. }
  35. next = val.Next()
  36. }
  37. *(*rt.GoSlice)(vp) = *slice
  38. return gerr
  39. }
  40. type arrayDecoder struct {
  41. len int
  42. elemType *rt.GoType
  43. elemDec decFunc
  44. typ reflect.Type
  45. }
  46. //go:nocheckptr
  47. func (d *arrayDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  48. if node.IsNull() {
  49. return nil
  50. }
  51. arr, ok := node.AsArr()
  52. if !ok {
  53. return error_mismatch(node, ctx, d.typ)
  54. }
  55. next := arr.Children()
  56. i := 0
  57. var gerr error
  58. for ; i < d.len && i < arr.Len(); i++ {
  59. elem := unsafe.Pointer(uintptr(vp) + uintptr(i)*d.elemType.Size)
  60. val := NewNode(next)
  61. err := d.elemDec.FromDom(elem, val, ctx)
  62. if gerr == nil && err != nil {
  63. gerr = err
  64. }
  65. next = val.Next()
  66. }
  67. /* zero rest of array */
  68. addr := uintptr(vp) + uintptr(i)*d.elemType.Size
  69. n := uintptr(d.len-i) * d.elemType.Size
  70. /* the boundary pointer may points to another unknown object, so we need to avoid using it */
  71. if n != 0 {
  72. rt.ClearMemory(d.elemType, unsafe.Pointer(addr), n)
  73. }
  74. return gerr
  75. }
  76. type sliceEfaceDecoder struct {
  77. }
  78. func (d *sliceEfaceDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  79. if node.IsNull() {
  80. *(*rt.GoSlice)(vp) = rt.GoSlice{}
  81. return nil
  82. }
  83. /* if slice is empty, just call `AsSliceEface` */
  84. if ((*rt.GoSlice)(vp)).Len == 0 {
  85. return node.AsSliceEface(ctx, vp)
  86. }
  87. decoder := sliceDecoder{
  88. elemType: rt.AnyType,
  89. elemDec: &efaceDecoder{},
  90. typ: rt.SliceEfaceType.Pack(),
  91. }
  92. return decoder.FromDom(vp, node, ctx)
  93. }
  94. type sliceI32Decoder struct {
  95. }
  96. func (d *sliceI32Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  97. if node.IsNull() {
  98. *(*rt.GoSlice)(vp) = rt.GoSlice{}
  99. return nil
  100. }
  101. return node.AsSliceI32(ctx, vp)
  102. }
  103. type sliceI64Decoder struct {
  104. }
  105. func (d *sliceI64Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  106. if node.IsNull() {
  107. *(*rt.GoSlice)(vp) = rt.GoSlice{}
  108. return nil
  109. }
  110. return node.AsSliceI64(ctx, vp)
  111. }
  112. type sliceU32Decoder struct {
  113. }
  114. func (d *sliceU32Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  115. if node.IsNull() {
  116. *(*rt.GoSlice)(vp) = rt.GoSlice{}
  117. return nil
  118. }
  119. return node.AsSliceU32(ctx, vp)
  120. }
  121. type sliceU64Decoder struct {
  122. }
  123. func (d *sliceU64Decoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  124. if node.IsNull() {
  125. *(*rt.GoSlice)(vp) = rt.GoSlice{}
  126. return nil
  127. }
  128. return node.AsSliceU64(ctx, vp)
  129. }
  130. type sliceStringDecoder struct {
  131. }
  132. func (d *sliceStringDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  133. if node.IsNull() {
  134. *(*rt.GoSlice)(vp) = rt.GoSlice{}
  135. return nil
  136. }
  137. return node.AsSliceString(ctx, vp)
  138. }
  139. type sliceBytesDecoder struct {
  140. }
  141. func (d *sliceBytesDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  142. if node.IsNull() {
  143. *(*rt.GoSlice)(vp) = rt.GoSlice{}
  144. return nil
  145. }
  146. s, err := node.AsSliceBytes(ctx)
  147. *(*[]byte)(vp) = s
  148. return err
  149. }
  150. type sliceBytesUnmarshalerDecoder struct {
  151. elemType *rt.GoType
  152. elemDec decFunc
  153. typ reflect.Type
  154. }
  155. func (d *sliceBytesUnmarshalerDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  156. if node.IsNull() {
  157. *(*rt.GoSlice)(vp) = rt.GoSlice{}
  158. return nil
  159. }
  160. /* parse JSON string into `[]byte` */
  161. if node.IsStr() {
  162. slice, err := node.AsSliceBytes(ctx)
  163. if err != nil {
  164. return err
  165. }
  166. *(*[]byte)(vp) = slice
  167. return nil
  168. }
  169. /* parse JSON array into `[]byte` */
  170. arr, ok := node.AsArr()
  171. if !ok {
  172. return error_mismatch(node, ctx, d.typ)
  173. }
  174. slice := rt.MakeSlice(vp, d.elemType, arr.Len())
  175. elems := slice.Ptr
  176. var gerr error
  177. next := arr.Children()
  178. for i := 0; i < arr.Len(); i++ {
  179. child := NewNode(next)
  180. elem := unsafe.Pointer(uintptr(elems) + uintptr(i)*d.elemType.Size)
  181. err := d.elemDec.FromDom(elem, child, ctx)
  182. if gerr == nil && err != nil {
  183. gerr = err
  184. }
  185. next = child.Next()
  186. }
  187. *(*rt.GoSlice)(vp) = *slice
  188. return gerr
  189. }