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