iter_skip_sloppy.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. //+build jsoniter_sloppy
  2. package jsoniter
  3. // sloppy but faster implementation, do not validate the input json
  4. func (iter *Iterator) skipNumber() {
  5. for {
  6. for i := iter.head; i < iter.tail; i++ {
  7. c := iter.buf[i]
  8. switch c {
  9. case ' ', '\n', '\r', '\t', ',', '}', ']':
  10. iter.head = i
  11. return
  12. }
  13. }
  14. if !iter.loadMore() {
  15. return
  16. }
  17. }
  18. }
  19. func (iter *Iterator) skipArray() {
  20. level := 1
  21. for {
  22. for i := iter.head; i < iter.tail; i++ {
  23. switch iter.buf[i] {
  24. case '"': // If inside string, skip it
  25. iter.head = i + 1
  26. iter.skipString()
  27. i = iter.head - 1 // it will be i++ soon
  28. case '[': // If open symbol, increase level
  29. level++
  30. case ']': // If close symbol, increase level
  31. level--
  32. // If we have returned to the original level, we're done
  33. if level == 0 {
  34. iter.head = i + 1
  35. return
  36. }
  37. }
  38. }
  39. if !iter.loadMore() {
  40. iter.ReportError("skipObject", "incomplete array")
  41. return
  42. }
  43. }
  44. }
  45. func (iter *Iterator) skipObject() {
  46. level := 1
  47. for {
  48. for i := iter.head; i < iter.tail; i++ {
  49. switch iter.buf[i] {
  50. case '"': // If inside string, skip it
  51. iter.head = i + 1
  52. iter.skipString()
  53. i = iter.head - 1 // it will be i++ soon
  54. case '{': // If open symbol, increase level
  55. level++
  56. case '}': // If close symbol, increase level
  57. level--
  58. // If we have returned to the original level, we're done
  59. if level == 0 {
  60. iter.head = i + 1
  61. return
  62. }
  63. }
  64. }
  65. if !iter.loadMore() {
  66. iter.ReportError("skipObject", "incomplete object")
  67. return
  68. }
  69. }
  70. }
  71. func (iter *Iterator) skipString() {
  72. for {
  73. end, escaped := iter.findStringEnd()
  74. if end == -1 {
  75. if !iter.loadMore() {
  76. iter.ReportError("skipString", "incomplete string")
  77. return
  78. }
  79. if escaped {
  80. iter.head = 1 // skip the first char as last char read is \
  81. }
  82. } else {
  83. iter.head = end
  84. return
  85. }
  86. }
  87. }
  88. // adapted from: https://github.com/buger/jsonparser/blob/master/parser.go
  89. // Tries to find the end of string
  90. // Support if string contains escaped quote symbols.
  91. func (iter *Iterator) findStringEnd() (int, bool) {
  92. escaped := false
  93. for i := iter.head; i < iter.tail; i++ {
  94. c := iter.buf[i]
  95. if c == '"' {
  96. if !escaped {
  97. return i + 1, false
  98. }
  99. j := i - 1
  100. for {
  101. if j < iter.head || iter.buf[j] != '\\' {
  102. // even number of backslashes
  103. // either end of buffer, or " found
  104. return i + 1, true
  105. }
  106. j--
  107. if j < iter.head || iter.buf[j] != '\\' {
  108. // odd number of backslashes
  109. // it is \" or \\\"
  110. break
  111. }
  112. j--
  113. }
  114. } else if c == '\\' {
  115. escaped = true
  116. }
  117. }
  118. j := iter.tail - 1
  119. for {
  120. if j < iter.head || iter.buf[j] != '\\' {
  121. // even number of backslashes
  122. // either end of buffer, or " found
  123. return -1, false // do not end with \
  124. }
  125. j--
  126. if j < iter.head || iter.buf[j] != '\\' {
  127. // odd number of backslashes
  128. // it is \" or \\\"
  129. break
  130. }
  131. j--
  132. }
  133. return -1, true // end with \
  134. }