github.com/night-codes/go-json@v0.9.15/internal/decoder/stream.go (about) 1 package decoder 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "io" 7 "strconv" 8 "unsafe" 9 10 "github.com/night-codes/go-json/internal/errors" 11 ) 12 13 const ( 14 initBufSize = 512 15 ) 16 17 type Stream struct { 18 buf []byte 19 bufSize int64 20 length int64 21 r io.Reader 22 offset int64 23 cursor int64 24 filledBuffer bool 25 allRead bool 26 UseNumber bool 27 DisallowUnknownFields bool 28 Option *Option 29 } 30 31 func NewStream(r io.Reader) *Stream { 32 return &Stream{ 33 r: r, 34 bufSize: initBufSize, 35 buf: make([]byte, initBufSize), 36 Option: &Option{}, 37 } 38 } 39 40 func (s *Stream) TotalOffset() int64 { 41 return s.totalOffset() 42 } 43 44 func (s *Stream) Buffered() io.Reader { 45 buflen := int64(len(s.buf)) 46 for i := s.cursor; i < buflen; i++ { 47 if s.buf[i] == nul { 48 return bytes.NewReader(s.buf[s.cursor:i]) 49 } 50 } 51 return bytes.NewReader(s.buf[s.cursor:]) 52 } 53 54 func (s *Stream) PrepareForDecode() error { 55 for { 56 switch s.char() { 57 case ' ', '\t', '\r', '\n': 58 s.cursor++ 59 continue 60 case ',', ':': 61 s.cursor++ 62 return nil 63 case nul: 64 if s.read() { 65 continue 66 } 67 return io.EOF 68 } 69 break 70 } 71 return nil 72 } 73 74 func (s *Stream) totalOffset() int64 { 75 return s.offset + s.cursor 76 } 77 78 func (s *Stream) char() byte { 79 return s.buf[s.cursor] 80 } 81 82 func (s *Stream) equalChar(c byte) bool { 83 cur := s.buf[s.cursor] 84 if cur == nul { 85 s.read() 86 cur = s.buf[s.cursor] 87 } 88 return cur == c 89 } 90 91 func (s *Stream) stat() ([]byte, int64, unsafe.Pointer) { 92 return s.buf, s.cursor, (*sliceHeader)(unsafe.Pointer(&s.buf)).data 93 } 94 95 func (s *Stream) bufptr() unsafe.Pointer { 96 return (*sliceHeader)(unsafe.Pointer(&s.buf)).data 97 } 98 99 func (s *Stream) statForRetry() ([]byte, int64, unsafe.Pointer) { 100 s.cursor-- // for retry ( because caller progress cursor position in each loop ) 101 return s.buf, s.cursor, (*sliceHeader)(unsafe.Pointer(&s.buf)).data 102 } 103 104 func (s *Stream) Reset() { 105 s.reset() 106 s.bufSize = int64(len(s.buf)) 107 } 108 109 func (s *Stream) More() bool { 110 for { 111 switch s.char() { 112 case ' ', '\n', '\r', '\t': 113 s.cursor++ 114 continue 115 case '}', ']': 116 return false 117 case nul: 118 if s.read() { 119 continue 120 } 121 return false 122 } 123 break 124 } 125 return true 126 } 127 128 func (s *Stream) Token() (interface{}, error) { 129 for { 130 c := s.char() 131 switch c { 132 case ' ', '\n', '\r', '\t': 133 s.cursor++ 134 case '{', '[', ']', '}': 135 s.cursor++ 136 return json.Delim(c), nil 137 case ',', ':': 138 s.cursor++ 139 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 140 bytes := floatBytes(s) 141 if len(bytes) == 0 { 142 bytes = []byte("0") 143 } 144 str := *(*string)(unsafe.Pointer(&bytes)) 145 if s.UseNumber { 146 return json.Number(str), nil 147 } 148 f64, err := strconv.ParseFloat(str, 64) 149 if err != nil { 150 return nil, err 151 } 152 return f64, nil 153 case '"': 154 bytes, err := stringBytes(s) 155 if err != nil { 156 return nil, err 157 } 158 return string(bytes), nil 159 case 't': 160 if err := trueBytes(s); err != nil { 161 return nil, err 162 } 163 return true, nil 164 case 'f': 165 if err := falseBytes(s); err != nil { 166 return nil, err 167 } 168 return false, nil 169 case 'n': 170 if err := nullBytes(s); err != nil { 171 return nil, err 172 } 173 return nil, nil 174 case nul: 175 if s.read() { 176 continue 177 } 178 goto END 179 default: 180 return nil, errors.ErrInvalidCharacter(s.char(), "token", s.totalOffset()) 181 } 182 } 183 END: 184 return nil, io.EOF 185 } 186 187 func (s *Stream) reset() { 188 s.offset += s.cursor 189 s.buf = s.buf[s.cursor:] 190 s.length -= s.cursor 191 s.cursor = 0 192 } 193 194 func (s *Stream) readBuf() []byte { 195 if s.filledBuffer { 196 s.bufSize *= 2 197 remainBuf := s.buf 198 s.buf = make([]byte, s.bufSize) 199 copy(s.buf, remainBuf) 200 } 201 remainLen := s.length - s.cursor 202 remainNotNulCharNum := int64(0) 203 for i := int64(0); i < remainLen; i++ { 204 if s.buf[s.cursor+i] == nul { 205 break 206 } 207 remainNotNulCharNum++ 208 } 209 s.length = s.cursor + remainNotNulCharNum 210 return s.buf[s.cursor+remainNotNulCharNum:] 211 } 212 213 func (s *Stream) read() bool { 214 if s.allRead { 215 return false 216 } 217 buf := s.readBuf() 218 last := len(buf) - 1 219 buf[last] = nul 220 n, err := s.r.Read(buf[:last]) 221 s.length += int64(n) 222 if n == last { 223 s.filledBuffer = true 224 } else { 225 s.filledBuffer = false 226 } 227 if err == io.EOF { 228 s.allRead = true 229 } else if err != nil { 230 return false 231 } 232 return true 233 } 234 235 func (s *Stream) skipWhiteSpace() byte { 236 p := s.bufptr() 237 LOOP: 238 c := char(p, s.cursor) 239 switch c { 240 case ' ', '\n', '\t', '\r': 241 s.cursor++ 242 goto LOOP 243 case nul: 244 if s.read() { 245 p = s.bufptr() 246 goto LOOP 247 } 248 } 249 return c 250 } 251 252 func (s *Stream) skipObject(depth int64) error { 253 braceCount := 1 254 _, cursor, p := s.stat() 255 for { 256 switch char(p, cursor) { 257 case '{': 258 braceCount++ 259 depth++ 260 if depth > maxDecodeNestingDepth { 261 return errors.ErrExceededMaxDepth(s.char(), s.cursor) 262 } 263 case '}': 264 braceCount-- 265 depth-- 266 if braceCount == 0 { 267 s.cursor = cursor + 1 268 return nil 269 } 270 case '[': 271 depth++ 272 if depth > maxDecodeNestingDepth { 273 return errors.ErrExceededMaxDepth(s.char(), s.cursor) 274 } 275 case ']': 276 depth-- 277 case '"': 278 for { 279 cursor++ 280 switch char(p, cursor) { 281 case '\\': 282 cursor++ 283 if char(p, cursor) == nul { 284 s.cursor = cursor 285 if s.read() { 286 _, cursor, p = s.stat() 287 continue 288 } 289 return errors.ErrUnexpectedEndOfJSON("string of object", cursor) 290 } 291 case '"': 292 goto SWITCH_OUT 293 case nul: 294 s.cursor = cursor 295 if s.read() { 296 _, cursor, p = s.statForRetry() 297 continue 298 } 299 return errors.ErrUnexpectedEndOfJSON("string of object", cursor) 300 } 301 } 302 case nul: 303 s.cursor = cursor 304 if s.read() { 305 _, cursor, p = s.stat() 306 continue 307 } 308 return errors.ErrUnexpectedEndOfJSON("object of object", cursor) 309 } 310 SWITCH_OUT: 311 cursor++ 312 } 313 } 314 315 func (s *Stream) skipArray(depth int64) error { 316 bracketCount := 1 317 _, cursor, p := s.stat() 318 for { 319 switch char(p, cursor) { 320 case '[': 321 bracketCount++ 322 depth++ 323 if depth > maxDecodeNestingDepth { 324 return errors.ErrExceededMaxDepth(s.char(), s.cursor) 325 } 326 case ']': 327 bracketCount-- 328 depth-- 329 if bracketCount == 0 { 330 s.cursor = cursor + 1 331 return nil 332 } 333 case '{': 334 depth++ 335 if depth > maxDecodeNestingDepth { 336 return errors.ErrExceededMaxDepth(s.char(), s.cursor) 337 } 338 case '}': 339 depth-- 340 case '"': 341 for { 342 cursor++ 343 switch char(p, cursor) { 344 case '\\': 345 cursor++ 346 if char(p, cursor) == nul { 347 s.cursor = cursor 348 if s.read() { 349 _, cursor, p = s.stat() 350 continue 351 } 352 return errors.ErrUnexpectedEndOfJSON("string of object", cursor) 353 } 354 case '"': 355 goto SWITCH_OUT 356 case nul: 357 s.cursor = cursor 358 if s.read() { 359 _, cursor, p = s.statForRetry() 360 continue 361 } 362 return errors.ErrUnexpectedEndOfJSON("string of object", cursor) 363 } 364 } 365 case nul: 366 s.cursor = cursor 367 if s.read() { 368 _, cursor, p = s.stat() 369 continue 370 } 371 return errors.ErrUnexpectedEndOfJSON("array of object", cursor) 372 } 373 SWITCH_OUT: 374 cursor++ 375 } 376 } 377 378 func (s *Stream) skipValue(depth int64) error { 379 _, cursor, p := s.stat() 380 for { 381 switch char(p, cursor) { 382 case ' ', '\n', '\t', '\r': 383 cursor++ 384 continue 385 case nul: 386 s.cursor = cursor 387 if s.read() { 388 _, cursor, p = s.stat() 389 continue 390 } 391 return errors.ErrUnexpectedEndOfJSON("value of object", s.totalOffset()) 392 case '{': 393 s.cursor = cursor + 1 394 return s.skipObject(depth + 1) 395 case '[': 396 s.cursor = cursor + 1 397 return s.skipArray(depth + 1) 398 case '"': 399 for { 400 cursor++ 401 switch char(p, cursor) { 402 case '\\': 403 cursor++ 404 if char(p, cursor) == nul { 405 s.cursor = cursor 406 if s.read() { 407 _, cursor, p = s.stat() 408 continue 409 } 410 return errors.ErrUnexpectedEndOfJSON("value of string", s.totalOffset()) 411 } 412 case '"': 413 s.cursor = cursor + 1 414 return nil 415 case nul: 416 s.cursor = cursor 417 if s.read() { 418 _, cursor, p = s.statForRetry() 419 continue 420 } 421 return errors.ErrUnexpectedEndOfJSON("value of string", s.totalOffset()) 422 } 423 } 424 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 425 for { 426 cursor++ 427 c := char(p, cursor) 428 if floatTable[c] { 429 continue 430 } else if c == nul { 431 if s.read() { 432 _, cursor, p = s.stat() 433 continue 434 } 435 } 436 s.cursor = cursor 437 return nil 438 } 439 case 't': 440 s.cursor = cursor 441 if err := trueBytes(s); err != nil { 442 return err 443 } 444 return nil 445 case 'f': 446 s.cursor = cursor 447 if err := falseBytes(s); err != nil { 448 return err 449 } 450 return nil 451 case 'n': 452 s.cursor = cursor 453 if err := nullBytes(s); err != nil { 454 return err 455 } 456 return nil 457 } 458 cursor++ 459 } 460 } 461 462 func nullBytes(s *Stream) error { 463 // current cursor's character is 'n' 464 s.cursor++ 465 if s.char() != 'u' { 466 if err := retryReadNull(s); err != nil { 467 return err 468 } 469 } 470 s.cursor++ 471 if s.char() != 'l' { 472 if err := retryReadNull(s); err != nil { 473 return err 474 } 475 } 476 s.cursor++ 477 if s.char() != 'l' { 478 if err := retryReadNull(s); err != nil { 479 return err 480 } 481 } 482 s.cursor++ 483 return nil 484 } 485 486 func retryReadNull(s *Stream) error { 487 if s.char() == nul && s.read() { 488 return nil 489 } 490 return errors.ErrInvalidCharacter(s.char(), "null", s.totalOffset()) 491 } 492 493 func trueBytes(s *Stream) error { 494 // current cursor's character is 't' 495 s.cursor++ 496 if s.char() != 'r' { 497 if err := retryReadTrue(s); err != nil { 498 return err 499 } 500 } 501 s.cursor++ 502 if s.char() != 'u' { 503 if err := retryReadTrue(s); err != nil { 504 return err 505 } 506 } 507 s.cursor++ 508 if s.char() != 'e' { 509 if err := retryReadTrue(s); err != nil { 510 return err 511 } 512 } 513 s.cursor++ 514 return nil 515 } 516 517 func retryReadTrue(s *Stream) error { 518 if s.char() == nul && s.read() { 519 return nil 520 } 521 return errors.ErrInvalidCharacter(s.char(), "bool(true)", s.totalOffset()) 522 } 523 524 func falseBytes(s *Stream) error { 525 // current cursor's character is 'f' 526 s.cursor++ 527 if s.char() != 'a' { 528 if err := retryReadFalse(s); err != nil { 529 return err 530 } 531 } 532 s.cursor++ 533 if s.char() != 'l' { 534 if err := retryReadFalse(s); err != nil { 535 return err 536 } 537 } 538 s.cursor++ 539 if s.char() != 's' { 540 if err := retryReadFalse(s); err != nil { 541 return err 542 } 543 } 544 s.cursor++ 545 if s.char() != 'e' { 546 if err := retryReadFalse(s); err != nil { 547 return err 548 } 549 } 550 s.cursor++ 551 return nil 552 } 553 554 func retryReadFalse(s *Stream) error { 555 if s.char() == nul && s.read() { 556 return nil 557 } 558 return errors.ErrInvalidCharacter(s.char(), "bool(false)", s.totalOffset()) 559 }