feature_any.go 4.3 KB

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