feature_iter_object.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. package jsoniter
  2. import (
  3. "fmt"
  4. "unicode"
  5. "unsafe"
  6. )
  7. // ReadObject read one field from object.
  8. // If object ended, returns empty string.
  9. // Otherwise, returns the field name.
  10. func (iter *Iterator) ReadObject() (ret string) {
  11. c := iter.nextToken()
  12. switch c {
  13. case 'n':
  14. iter.skipThreeBytes('u', 'l', 'l')
  15. return "" // null
  16. case '{':
  17. c = iter.nextToken()
  18. if c == '"' {
  19. iter.unreadByte()
  20. if iter.cfg.objectFieldMustBeSimpleString {
  21. return string(iter.readObjectFieldAsBytes())
  22. } else {
  23. field := iter.ReadString()
  24. c = iter.nextToken()
  25. if c != ':' {
  26. iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
  27. }
  28. return field
  29. }
  30. }
  31. if c == '}' {
  32. return "" // end of object
  33. }
  34. iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c}))
  35. return
  36. case ',':
  37. if iter.cfg.objectFieldMustBeSimpleString {
  38. return string(iter.readObjectFieldAsBytes())
  39. } else {
  40. field := iter.ReadString()
  41. c = iter.nextToken()
  42. if c != ':' {
  43. iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
  44. }
  45. return field
  46. }
  47. case '}':
  48. return "" // end of object
  49. default:
  50. iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c})))
  51. return
  52. }
  53. }
  54. func (iter *Iterator) readFieldHash() int32 {
  55. hash := int64(0x811c9dc5)
  56. c := iter.nextToken()
  57. if c == '"' {
  58. for {
  59. for i := iter.head; i < iter.tail; i++ {
  60. // require ascii string and no escape
  61. b := iter.buf[i]
  62. if !iter.cfg.objectFieldMustBeSimpleString && b == '\\' {
  63. iter.head = i
  64. for _, b := range iter.readStringSlowPath() {
  65. if 'A' <= b && b <= 'Z' {
  66. b += 'a' - 'A'
  67. }
  68. hash ^= int64(b)
  69. hash *= 0x1000193
  70. }
  71. c = iter.nextToken()
  72. if c != ':' {
  73. iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
  74. return 0
  75. }
  76. return int32(hash)
  77. }
  78. if b == '"' {
  79. iter.head = i + 1
  80. c = iter.nextToken()
  81. if c != ':' {
  82. iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
  83. return 0
  84. }
  85. return int32(hash)
  86. }
  87. if 'A' <= b && b <= 'Z' {
  88. b += 'a' - 'A'
  89. }
  90. hash ^= int64(b)
  91. hash *= 0x1000193
  92. }
  93. if !iter.loadMore() {
  94. iter.ReportError("readFieldHash", `incomplete field name`)
  95. return 0
  96. }
  97. }
  98. }
  99. iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c}))
  100. return 0
  101. }
  102. func calcHash(str string) int32 {
  103. hash := int64(0x811c9dc5)
  104. for _, b := range str {
  105. hash ^= int64(unicode.ToLower(b))
  106. hash *= 0x1000193
  107. }
  108. return int32(hash)
  109. }
  110. // ReadObjectCB read object with callback, the key is ascii only and field name not copied
  111. func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
  112. c := iter.nextToken()
  113. var fieldBytes []byte
  114. var field string
  115. if c == '{' {
  116. c = iter.nextToken()
  117. if c == '"' {
  118. iter.unreadByte()
  119. if iter.cfg.objectFieldMustBeSimpleString {
  120. fieldBytes = iter.readObjectFieldAsBytes()
  121. field = *(*string)(unsafe.Pointer(&fieldBytes))
  122. } else {
  123. field = iter.ReadString()
  124. c = iter.nextToken()
  125. if c != ':' {
  126. iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
  127. }
  128. }
  129. if !callback(iter, field) {
  130. return false
  131. }
  132. c = iter.nextToken()
  133. for c == ',' {
  134. if iter.cfg.objectFieldMustBeSimpleString {
  135. fieldBytes = iter.readObjectFieldAsBytes()
  136. field = *(*string)(unsafe.Pointer(&fieldBytes))
  137. } else {
  138. field = iter.ReadString()
  139. c = iter.nextToken()
  140. if c != ':' {
  141. iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
  142. }
  143. }
  144. if !callback(iter, field) {
  145. return false
  146. }
  147. c = iter.nextToken()
  148. }
  149. if c != '}' {
  150. iter.ReportError("ReadObjectCB", `object not ended with }`)
  151. return false
  152. }
  153. return true
  154. }
  155. if c == '}' {
  156. return true
  157. }
  158. iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c}))
  159. return false
  160. }
  161. if c == 'n' {
  162. iter.skipThreeBytes('u', 'l', 'l')
  163. return true // null
  164. }
  165. iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c}))
  166. return false
  167. }
  168. // ReadMapCB read map with callback, the key can be any string
  169. func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
  170. c := iter.nextToken()
  171. if c == '{' {
  172. c = iter.nextToken()
  173. if c == '"' {
  174. iter.unreadByte()
  175. field := iter.ReadString()
  176. if iter.nextToken() != ':' {
  177. iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
  178. return false
  179. }
  180. if !callback(iter, field) {
  181. return false
  182. }
  183. c = iter.nextToken()
  184. for c == ',' {
  185. field = iter.ReadString()
  186. if iter.nextToken() != ':' {
  187. iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
  188. return false
  189. }
  190. if !callback(iter, field) {
  191. return false
  192. }
  193. c = iter.nextToken()
  194. }
  195. if c != '}' {
  196. iter.ReportError("ReadMapCB", `object not ended with }`)
  197. return false
  198. }
  199. return true
  200. }
  201. if c == '}' {
  202. return true
  203. }
  204. iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
  205. return false
  206. }
  207. if c == 'n' {
  208. iter.skipThreeBytes('u', 'l', 'l')
  209. return true // null
  210. }
  211. iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
  212. return false
  213. }
  214. func (iter *Iterator) readObjectStart() bool {
  215. c := iter.nextToken()
  216. if c == '{' {
  217. c = iter.nextToken()
  218. if c == '}' {
  219. return false
  220. }
  221. iter.unreadByte()
  222. return true
  223. } else if c == 'n' {
  224. iter.skipThreeBytes('u', 'l', 'l')
  225. return false
  226. }
  227. iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c}))
  228. return false
  229. }
  230. func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) {
  231. str := iter.ReadStringAsSlice()
  232. if iter.skipWhitespacesWithoutLoadMore() {
  233. if ret == nil {
  234. ret = make([]byte, len(str))
  235. copy(ret, str)
  236. }
  237. if !iter.loadMore() {
  238. return
  239. }
  240. }
  241. if iter.buf[iter.head] != ':' {
  242. iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]}))
  243. return
  244. }
  245. iter.head++
  246. if iter.skipWhitespacesWithoutLoadMore() {
  247. if ret == nil {
  248. ret = make([]byte, len(str))
  249. copy(ret, str)
  250. }
  251. if !iter.loadMore() {
  252. return
  253. }
  254. }
  255. if ret == nil {
  256. return str
  257. }
  258. return ret
  259. }