feature_any.go 5.2 KB

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