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