feature_any.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package jsoniter
  2. type Any interface {
  3. LastError() error
  4. ToBool() bool
  5. ToInt() int
  6. ToInt32() int32
  7. ToInt64() int64
  8. ToFloat32() float32
  9. ToFloat64() float64
  10. ToString() string
  11. Get(path ...interface{}) Any
  12. Size() int
  13. Keys() []string
  14. IterateObject() (func() (string, Any, bool), bool)
  15. IterateArray() (func() (Any, bool), bool)
  16. }
  17. type baseAny struct {}
  18. func (any *baseAny) Size() int {
  19. return 0
  20. }
  21. func (any *baseAny) Keys() []string {
  22. return []string{}
  23. }
  24. func (any *baseAny) IterateObject() (func() (string, Any, bool), bool) {
  25. return nil, false
  26. }
  27. func (any *baseAny) IterateArray() (func() (Any, bool), bool) {
  28. return nil, false
  29. }
  30. func (iter *Iterator) ReadAny() Any {
  31. return iter.readAny(nil)
  32. }
  33. func (iter *Iterator) readAny(reusableIter *Iterator) Any {
  34. c := iter.nextToken()
  35. switch c {
  36. case '"':
  37. return iter.readStringAny(reusableIter)
  38. case 'n':
  39. iter.skipFixedBytes(3) // null
  40. return &nilAny{}
  41. case 't':
  42. iter.skipFixedBytes(3) // true
  43. return &trueAny{}
  44. case 'f':
  45. iter.skipFixedBytes(4) // false
  46. return &falseAny{}
  47. case '{':
  48. return iter.readObjectAny(reusableIter)
  49. case '[':
  50. return iter.readArrayAny(reusableIter)
  51. default:
  52. iter.unreadByte()
  53. return iter.readNumberAny(reusableIter)
  54. }
  55. }
  56. func (iter *Iterator) readNumberAny(reusableIter *Iterator) Any {
  57. dotFound := false
  58. var lazyBuf []byte
  59. for {
  60. for i := iter.head; i < iter.tail; i++ {
  61. c := iter.buf[i]
  62. if c == '.' {
  63. dotFound = true
  64. continue
  65. }
  66. switch c {
  67. case ' ', '\n', '\r', '\t', ',', '}', ']':
  68. lazyBuf = append(lazyBuf, iter.buf[iter.head:i]...)
  69. iter.head = i
  70. if dotFound {
  71. return &floatLazyAny{baseAny{},lazyBuf, reusableIter, nil, 0}
  72. } else {
  73. return &intLazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0}
  74. }
  75. }
  76. }
  77. lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
  78. if !iter.loadMore() {
  79. iter.head = iter.tail
  80. if dotFound {
  81. return &floatLazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0}
  82. } else {
  83. return &intLazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0}
  84. }
  85. }
  86. }
  87. }
  88. func (iter *Iterator) readStringAny(reusableIter *Iterator) Any {
  89. lazyBuf := make([]byte, 1, 8)
  90. lazyBuf[0] = '"'
  91. for {
  92. end, escaped := iter.findStringEnd()
  93. if end == -1 {
  94. lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
  95. if !iter.loadMore() {
  96. iter.reportError("readStringAny", "incomplete string")
  97. return &invalidAny{}
  98. }
  99. if escaped {
  100. iter.head = 1 // skip the first char as last char read is \
  101. }
  102. } else {
  103. lazyBuf = append(lazyBuf, iter.buf[iter.head:end]...)
  104. iter.head = end
  105. return &stringLazyAny{baseAny{}, lazyBuf, reusableIter, nil, ""}
  106. }
  107. }
  108. }
  109. func (iter *Iterator) readObjectAny(reusableIter *Iterator) Any {
  110. level := 1
  111. lazyBuf := make([]byte, 1, 32)
  112. lazyBuf[0] = '{'
  113. for {
  114. start := iter.head
  115. for i := iter.head; i < iter.tail; i++ {
  116. switch iter.buf[i] {
  117. case '"': // If inside string, skip it
  118. iter.head = i + 1
  119. iter.skipString()
  120. i = iter.head - 1 // it will be i++ soon
  121. case '{': // If open symbol, increase level
  122. level++
  123. case '}': // If close symbol, increase level
  124. level--
  125. // If we have returned to the original level, we're done
  126. if level == 0 {
  127. iter.head = i + 1
  128. lazyBuf = append(lazyBuf, iter.buf[start:iter.head]...)
  129. return &objectLazyAny{baseAny{}, lazyBuf, reusableIter, nil, nil, lazyBuf}
  130. }
  131. }
  132. }
  133. lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
  134. if !iter.loadMore() {
  135. iter.reportError("skipObject", "incomplete object")
  136. return &invalidAny{}
  137. }
  138. }
  139. }
  140. func (iter *Iterator) readArrayAny(reusableIter *Iterator) Any {
  141. level := 1
  142. lazyBuf := make([]byte, 1, 32)
  143. lazyBuf[0] = '{'
  144. for {
  145. start := iter.head
  146. for i := iter.head; i < iter.tail; i++ {
  147. switch iter.buf[i] {
  148. case '"': // If inside string, skip it
  149. iter.head = i + 1
  150. iter.skipString()
  151. i = iter.head - 1 // it will be i++ soon
  152. case '[': // If open symbol, increase level
  153. level++
  154. case ']': // If close symbol, increase level
  155. level--
  156. // If we have returned to the original level, we're done
  157. if level == 0 {
  158. iter.head = i + 1
  159. lazyBuf = append(lazyBuf, iter.buf[start:iter.head]...)
  160. return &arrayLazyAny{baseAny{},lazyBuf, reusableIter, nil, nil, lazyBuf}
  161. }
  162. }
  163. }
  164. lazyBuf = append(lazyBuf, iter.buf[iter.head:iter.tail]...)
  165. if !iter.loadMore() {
  166. iter.reportError("skipArray", "incomplete array")
  167. return &invalidAny{}
  168. }
  169. }
  170. }