feature_reflect_array.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package jsoniter
  2. import (
  3. "unsafe"
  4. "reflect"
  5. "io"
  6. "fmt"
  7. )
  8. type sliceDecoder struct {
  9. sliceType reflect.Type
  10. elemType reflect.Type
  11. elemDecoder Decoder
  12. }
  13. // sliceHeader is a safe version of SliceHeader used within this package.
  14. type sliceHeader struct {
  15. Data unsafe.Pointer
  16. Len int
  17. Cap int
  18. }
  19. func (decoder *sliceDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
  20. decoder.doDecode(ptr, iter)
  21. if iter.Error != nil && iter.Error != io.EOF {
  22. iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error())
  23. }
  24. }
  25. func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
  26. slice := (*sliceHeader)(ptr)
  27. reuseSlice(slice, decoder.sliceType, 4)
  28. if !iter.ReadArray() {
  29. return
  30. }
  31. offset := uintptr(0)
  32. decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter)
  33. if !iter.ReadArray() {
  34. slice.Len = 1
  35. return
  36. }
  37. offset += decoder.elemType.Size()
  38. decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter)
  39. if !iter.ReadArray() {
  40. slice.Len = 2
  41. return
  42. }
  43. offset += decoder.elemType.Size()
  44. decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter)
  45. if !iter.ReadArray() {
  46. slice.Len = 3
  47. return
  48. }
  49. offset += decoder.elemType.Size()
  50. decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter)
  51. slice.Len = 4
  52. for iter.ReadArray() {
  53. growOne(slice, decoder.sliceType, decoder.elemType)
  54. offset += decoder.elemType.Size()
  55. decoder.elemDecoder.decode(unsafe.Pointer(uintptr(slice.Data) + offset), iter)
  56. }
  57. }
  58. // grow grows the slice s so that it can hold extra more values, allocating
  59. // more capacity if needed. It also returns the old and new slice lengths.
  60. func growOne(slice *sliceHeader, sliceType reflect.Type, elementType reflect.Type) {
  61. newLen := slice.Len + 1
  62. if newLen <= slice.Cap {
  63. slice.Len = newLen
  64. return
  65. }
  66. newCap := slice.Cap
  67. if newCap == 0 {
  68. newCap = 1
  69. } else {
  70. for newCap < newLen {
  71. if slice.Len < 1024 {
  72. newCap += newCap
  73. } else {
  74. newCap += newCap / 4
  75. }
  76. }
  77. }
  78. dst := unsafe.Pointer(reflect.MakeSlice(sliceType, newLen, newCap).Pointer())
  79. // copy old array into new array
  80. originalBytesCount := uintptr(slice.Len) * elementType.Size()
  81. srcPtr := (*[1 << 30]byte)(slice.Data)
  82. dstPtr := (*[1 << 30]byte)(dst)
  83. for i := uintptr(0); i < originalBytesCount; i++ {
  84. dstPtr[i] = srcPtr[i]
  85. }
  86. slice.Len = newLen
  87. slice.Cap = newCap
  88. slice.Data = dst
  89. }
  90. func reuseSlice(slice *sliceHeader, sliceType reflect.Type, expectedCap int) {
  91. if expectedCap <= slice.Cap {
  92. return
  93. }
  94. dst := unsafe.Pointer(reflect.MakeSlice(sliceType, 0, expectedCap).Pointer())
  95. slice.Cap = expectedCap
  96. slice.Data = dst
  97. }