github.com/3JoB/go-json@v0.10.4/internal/decoder/context.go (about) 1 package decoder 2 3 import ( 4 "sync" 5 "unsafe" 6 7 "github.com/3JoB/go-json/internal/errors" 8 ) 9 10 type RuntimeContext struct { 11 Buf []byte 12 Option *Option 13 } 14 15 var ( 16 runtimeContextPool = sync.Pool{ 17 New: func() any { 18 return &RuntimeContext{ 19 Option: &Option{}, 20 } 21 }, 22 } 23 ) 24 25 func TakeRuntimeContext() *RuntimeContext { 26 return runtimeContextPool.Get().(*RuntimeContext) 27 } 28 29 func ReleaseRuntimeContext(ctx *RuntimeContext) { 30 runtimeContextPool.Put(ctx) 31 } 32 33 var ( 34 isWhiteSpace = [256]bool{} 35 ) 36 37 func init() { 38 isWhiteSpace[' '] = true 39 isWhiteSpace['\n'] = true 40 isWhiteSpace['\t'] = true 41 isWhiteSpace['\r'] = true 42 } 43 44 func char(ptr unsafe.Pointer, offset int64) byte { 45 return *(*byte)(unsafe.Pointer(uintptr(ptr) + uintptr(offset))) 46 } 47 48 func ptrUint16(ptr unsafe.Pointer, offset int64) *uint16 { 49 return (*uint16)(unsafe.Pointer(uintptr(ptr) + uintptr(offset))) 50 } 51 52 func skipWhiteSpace(buf []byte, cursor int64) int64 { 53 for isWhiteSpace[buf[cursor]] { 54 cursor++ 55 } 56 return cursor 57 } 58 59 func skipObject(buf []byte, cursor, depth int64) (int64, error) { 60 braceCount := 1 61 for { 62 switch buf[cursor] { 63 case '{': 64 braceCount++ 65 depth++ 66 if depth > maxDecodeNestingDepth { 67 return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) 68 } 69 case '}': 70 depth-- 71 braceCount-- 72 if braceCount == 0 { 73 return cursor + 1, nil 74 } 75 case '[': 76 depth++ 77 if depth > maxDecodeNestingDepth { 78 return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) 79 } 80 case ']': 81 depth-- 82 case '"': 83 for { 84 cursor++ 85 switch buf[cursor] { 86 case '\\': 87 cursor++ 88 if buf[cursor] == nul { 89 return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) 90 } 91 case '"': 92 goto SWITCH_OUT 93 case nul: 94 return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) 95 } 96 } 97 case nul: 98 return 0, errors.ErrUnexpectedEndOfJSON("object of object", cursor) 99 } 100 SWITCH_OUT: 101 cursor++ 102 } 103 } 104 105 func skipArray(buf []byte, cursor, depth int64) (int64, error) { 106 bracketCount := 1 107 for { 108 switch buf[cursor] { 109 case '[': 110 bracketCount++ 111 depth++ 112 if depth > maxDecodeNestingDepth { 113 return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) 114 } 115 case ']': 116 bracketCount-- 117 depth-- 118 if bracketCount == 0 { 119 return cursor + 1, nil 120 } 121 case '{': 122 depth++ 123 if depth > maxDecodeNestingDepth { 124 return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) 125 } 126 case '}': 127 depth-- 128 case '"': 129 for { 130 cursor++ 131 switch buf[cursor] { 132 case '\\': 133 cursor++ 134 if buf[cursor] == nul { 135 return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) 136 } 137 case '"': 138 goto SWITCH_OUT 139 case nul: 140 return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) 141 } 142 } 143 case nul: 144 return 0, errors.ErrUnexpectedEndOfJSON("array of object", cursor) 145 } 146 SWITCH_OUT: 147 cursor++ 148 } 149 } 150 151 func skipValue(buf []byte, cursor, depth int64) (int64, error) { 152 for { 153 switch buf[cursor] { 154 case ' ', '\t', '\n', '\r': 155 cursor++ 156 continue 157 case '{': 158 return skipObject(buf, cursor+1, depth+1) 159 case '[': 160 return skipArray(buf, cursor+1, depth+1) 161 case '"': 162 for { 163 cursor++ 164 switch buf[cursor] { 165 case '\\': 166 cursor++ 167 if buf[cursor] == nul { 168 return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) 169 } 170 case '"': 171 return cursor + 1, nil 172 case nul: 173 return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) 174 } 175 } 176 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 177 for { 178 cursor++ 179 if floatTable[buf[cursor]] { 180 continue 181 } 182 break 183 } 184 return cursor, nil 185 case 't': 186 if err := validateTrue(buf, cursor); err != nil { 187 return 0, err 188 } 189 cursor += 4 190 return cursor, nil 191 case 'f': 192 if err := validateFalse(buf, cursor); err != nil { 193 return 0, err 194 } 195 cursor += 5 196 return cursor, nil 197 case 'n': 198 if err := validateNull(buf, cursor); err != nil { 199 return 0, err 200 } 201 cursor += 4 202 return cursor, nil 203 default: 204 return cursor, errors.ErrUnexpectedEndOfJSON("null", cursor) 205 } 206 } 207 } 208 209 func validateTrue(buf []byte, cursor int64) error { 210 if cursor+3 >= int64(len(buf)) { 211 return errors.ErrUnexpectedEndOfJSON("true", cursor) 212 } 213 if buf[cursor+1] != 'r' { 214 return errors.ErrInvalidCharacter(buf[cursor+1], "true", cursor) 215 } 216 if buf[cursor+2] != 'u' { 217 return errors.ErrInvalidCharacter(buf[cursor+2], "true", cursor) 218 } 219 if buf[cursor+3] != 'e' { 220 return errors.ErrInvalidCharacter(buf[cursor+3], "true", cursor) 221 } 222 return nil 223 } 224 225 func validateFalse(buf []byte, cursor int64) error { 226 if cursor+4 >= int64(len(buf)) { 227 return errors.ErrUnexpectedEndOfJSON("false", cursor) 228 } 229 if buf[cursor+1] != 'a' { 230 return errors.ErrInvalidCharacter(buf[cursor+1], "false", cursor) 231 } 232 if buf[cursor+2] != 'l' { 233 return errors.ErrInvalidCharacter(buf[cursor+2], "false", cursor) 234 } 235 if buf[cursor+3] != 's' { 236 return errors.ErrInvalidCharacter(buf[cursor+3], "false", cursor) 237 } 238 if buf[cursor+4] != 'e' { 239 return errors.ErrInvalidCharacter(buf[cursor+4], "false", cursor) 240 } 241 return nil 242 } 243 244 func validateNull(buf []byte, cursor int64) error { 245 if cursor+3 >= int64(len(buf)) { 246 return errors.ErrUnexpectedEndOfJSON("null", cursor) 247 } 248 if buf[cursor+1] != 'u' { 249 return errors.ErrInvalidCharacter(buf[cursor+1], "null", cursor) 250 } 251 if buf[cursor+2] != 'l' { 252 return errors.ErrInvalidCharacter(buf[cursor+2], "null", cursor) 253 } 254 if buf[cursor+3] != 'l' { 255 return errors.ErrInvalidCharacter(buf[cursor+3], "null", cursor) 256 } 257 return nil 258 }