Source File
scanner.go
Belonging Package
encoding/json
package json
import (
)
func ( []byte) bool {
:= newScanner()
defer freeScanner()
return checkValid(, ) == nil
}
type SyntaxError struct {
msg string // description of error
Offset int64 // error occurred after reading Offset bytes
}
func ( *SyntaxError) () string { return .msg }
if len(.parseState) > 1024 {
.parseState = nil
}
scannerPool.Put()
}
scanContinue = iota // uninteresting byte
scanBeginLiteral // end implied by next result != scanContinue
scanBeginObject // begin object
scanObjectKey // just finished object key (string)
scanObjectValue // just finished non-last object value
scanEndObject // end object (implies scanObjectValue if possible)
scanBeginArray // begin array
scanArrayValue // just finished array value
scanEndArray // end array (implies scanArrayValue if possible)
scanSkipSpace // space byte; can skip; known to be last "continue" result
const (
parseObjectKey = iota // parsing object key (before colon)
parseObjectValue // parsing object value (after colon)
parseArrayValue // parsing array value
)
const maxNestingDepth = 10000
func ( *scanner) () {
.step = stateBeginValue
.parseState = .parseState[0:0]
.err = nil
.endTop = false
}
func ( *scanner) ( byte, int, int) int {
.parseState = append(.parseState, )
if len(.parseState) <= maxNestingDepth {
return
}
return .error(, "exceeded max depth")
}
func ( *scanner) () {
:= len(.parseState) - 1
.parseState = .parseState[0:]
if == 0 {
.step = stateEndTop
.endTop = true
} else {
.step = stateEndValue
}
}
func ( byte) bool {
return <= ' ' && ( == ' ' || == '\t' || == '\r' || == '\n')
}
func ( *scanner, byte) int {
if isSpace() {
return scanSkipSpace
}
if == ']' {
return stateEndValue(, )
}
return stateBeginValue(, )
}
func ( *scanner, byte) int {
if isSpace() {
return scanSkipSpace
}
switch {
case '{':
.step = stateBeginStringOrEmpty
return .pushParseState(, parseObjectKey, scanBeginObject)
case '[':
.step = stateBeginValueOrEmpty
return .pushParseState(, parseArrayValue, scanBeginArray)
case '"':
.step = stateInString
return scanBeginLiteral
case '-':
.step = stateNeg
return scanBeginLiteral
case '0': // beginning of 0.123
.step = state0
return scanBeginLiteral
case 't': // beginning of true
.step = stateT
return scanBeginLiteral
case 'f': // beginning of false
.step = stateF
return scanBeginLiteral
case 'n': // beginning of null
.step = stateN
return scanBeginLiteral
}
if '1' <= && <= '9' { // beginning of 1234.5
.step = state1
return scanBeginLiteral
}
return .error(, "looking for beginning of value")
}
func ( *scanner, byte) int {
if isSpace() {
return scanSkipSpace
}
if == '}' {
:= len(.parseState)
.parseState[-1] = parseObjectValue
return stateEndValue(, )
}
return stateBeginString(, )
}
func ( *scanner, byte) int {
if isSpace() {
return scanSkipSpace
}
if == '"' {
.step = stateInString
return scanBeginLiteral
}
return .error(, "looking for beginning of object key string")
}
func ( *scanner, byte) int {
:= len(.parseState)
.step = stateEndTop
.endTop = true
return stateEndTop(, )
}
if isSpace() {
.step =
return scanSkipSpace
}
:= .parseState[-1]
switch {
case parseObjectKey:
if == ':' {
.parseState[-1] = parseObjectValue
.step = stateBeginValue
return scanObjectKey
}
return .error(, "after object key")
case parseObjectValue:
if == ',' {
.parseState[-1] = parseObjectKey
.step = stateBeginString
return scanObjectValue
}
if == '}' {
.popParseState()
return scanEndObject
}
return .error(, "after object key:value pair")
case parseArrayValue:
if == ',' {
.step = stateBeginValue
return scanArrayValue
}
if == ']' {
.popParseState()
return scanEndArray
}
return .error(, "after array element")
}
return .error(, "")
}
func ( *scanner, byte) int {
if == '"' {
.step = stateEndValue
return scanContinue
}
if == '\\' {
.step = stateInStringEsc
return scanContinue
}
if < 0x20 {
return .error(, "in string literal")
}
return scanContinue
}
func ( *scanner, byte) int {
switch {
case 'b', 'f', 'n', 'r', 't', '\\', '/', '"':
.step = stateInString
return scanContinue
case 'u':
.step = stateInStringEscU
return scanContinue
}
return .error(, "in string escape code")
}
func ( *scanner, byte) int {
if '0' <= && <= '9' || 'a' <= && <= 'f' || 'A' <= && <= 'F' {
.step = stateInStringEscU1
return scanContinue
return .error(, "in \\u hexadecimal character escape")
}
func ( *scanner, byte) int {
if '0' <= && <= '9' || 'a' <= && <= 'f' || 'A' <= && <= 'F' {
.step = stateInStringEscU12
return scanContinue
return .error(, "in \\u hexadecimal character escape")
}
func ( *scanner, byte) int {
if '0' <= && <= '9' || 'a' <= && <= 'f' || 'A' <= && <= 'F' {
.step = stateInStringEscU123
return scanContinue
return .error(, "in \\u hexadecimal character escape")
}
func ( *scanner, byte) int {
if '0' <= && <= '9' || 'a' <= && <= 'f' || 'A' <= && <= 'F' {
.step = stateInString
return scanContinue
return .error(, "in \\u hexadecimal character escape")
}
func ( *scanner, byte) int {
if == '0' {
.step = state0
return scanContinue
}
if '1' <= && <= '9' {
.step = state1
return scanContinue
}
return .error(, "in numeric literal")
}
func ( *scanner, byte) int {
if == '.' {
.step = stateDot
return scanContinue
}
if == 'e' || == 'E' {
.step = stateE
return scanContinue
}
return stateEndValue(, )
}
func ( *scanner, byte) int {
if '0' <= && <= '9' {
return scanContinue
}
if == 'e' || == 'E' {
.step = stateE
return scanContinue
}
return stateEndValue(, )
}
func ( *scanner, byte) int {
if == '+' || == '-' {
.step = stateESign
return scanContinue
}
return stateESign(, )
}
func ( *scanner, byte) int {
if '0' <= && <= '9' {
return scanContinue
}
return stateEndValue(, )
}
func ( *scanner, byte) int {
if == 'e' {
.step = stateEndValue
return scanContinue
}
return .error(, "in literal true (expecting 'e')")
}
func ( *scanner, byte) int {
if == 'e' {
.step = stateEndValue
return scanContinue
}
return .error(, "in literal false (expecting 'e')")
}
func ( *scanner, byte) int {
if == 'l' {
.step = stateEndValue
return scanContinue
}
return .error(, "in literal null (expecting 'l')")
}
if == '\'' {
return `'\''`
}
if == '"' {
return `'"'`
}
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |