package fastjson
import (
)
func ( string) error {
= skipWS()
, := validateValue()
if != nil {
return fmt.Errorf("cannot parse JSON: %s; unparsed tail: %q", , startEndString())
}
= skipWS()
if len() > 0 {
return fmt.Errorf("unexpected tail: %q", startEndString())
}
return nil
}
func ( []byte) error {
return Validate(b2s())
}
func ( string) (string, error) {
if len() == 0 {
return , fmt.Errorf("cannot parse empty string")
}
if [0] == '{' {
, := validateObject([1:])
if != nil {
return , fmt.Errorf("cannot parse object: %s", )
}
return , nil
}
if [0] == '[' {
, := validateArray([1:])
if != nil {
return , fmt.Errorf("cannot parse array: %s", )
}
return , nil
}
if [0] == '"' {
, , := validateString([1:])
if != nil {
return , fmt.Errorf("cannot parse string: %s", )
}
for := 0; < len(); ++ {
if [] < 0x20 {
return , fmt.Errorf("string cannot contain control char 0x%02X", [])
}
}
return , nil
}
if [0] == 't' {
if len() < len("true") || [:len("true")] != "true" {
return , fmt.Errorf("unexpected value found: %q", )
}
return [len("true"):], nil
}
if [0] == 'f' {
if len() < len("false") || [:len("false")] != "false" {
return , fmt.Errorf("unexpected value found: %q", )
}
return [len("false"):], nil
}
if [0] == 'n' {
if len() < len("null") || [:len("null")] != "null" {
return , fmt.Errorf("unexpected value found: %q", )
}
return [len("null"):], nil
}
, := validateNumber()
if != nil {
return , fmt.Errorf("cannot parse number: %s", )
}
return , nil
}
func ( string) (string, error) {
= skipWS()
if len() == 0 {
return , fmt.Errorf("missing ']'")
}
if [0] == ']' {
return [1:], nil
}
for {
var error
= skipWS()
, = validateValue()
if != nil {
return , fmt.Errorf("cannot parse array value: %s", )
}
= skipWS()
if len() == 0 {
return , fmt.Errorf("unexpected end of array")
}
if [0] == ',' {
= [1:]
continue
}
if [0] == ']' {
= [1:]
return , nil
}
return , fmt.Errorf("missing ',' after array value")
}
}
func ( string) (string, error) {
= skipWS()
if len() == 0 {
return , fmt.Errorf("missing '}'")
}
if [0] == '}' {
return [1:], nil
}
for {
var error
= skipWS()
if len() == 0 || [0] != '"' {
return , fmt.Errorf(`cannot find opening '"" for object key`)
}
var string
, , = validateKey([1:])
if != nil {
return , fmt.Errorf("cannot parse object key: %s", )
}
for := 0; < len(); ++ {
if [] < 0x20 {
return , fmt.Errorf("object key cannot contain control char 0x%02X", [])
}
}
= skipWS()
if len() == 0 || [0] != ':' {
return , fmt.Errorf("missing ':' after object key")
}
= [1:]
= skipWS()
, = validateValue()
if != nil {
return , fmt.Errorf("cannot parse object value: %s", )
}
= skipWS()
if len() == 0 {
return , fmt.Errorf("unexpected end of object")
}
if [0] == ',' {
= [1:]
continue
}
if [0] == '}' {
return [1:], nil
}
return , fmt.Errorf("missing ',' after object value")
}
}
func ( string) (string, string, error) {
for := 0; < len(); ++ {
if [] == '"' {
return [:], [+1:], nil
}
if [] == '\\' {
return validateString()
}
}
return "", , fmt.Errorf(`missing closing '"'`)
}
func ( string) (string, string, error) {
if := strings.IndexByte(, '"'); >= 0 && strings.IndexByte([:], '\\') < 0 {
return [:], [+1:], nil
}
, , := parseRawString()
if != nil {
return , ,
}
for {
:= strings.IndexByte(, '\\')
if < 0 {
return , , nil
}
++
if >= len() {
return , , fmt.Errorf("BUG: parseRawString returned invalid string with trailing backslash: %q", )
}
:= []
= [+1:]
switch {
case '"', '\\', '/', 'b', 'f', 'n', 'r', 't':
break
case 'u':
if len() < 4 {
return , , fmt.Errorf(`too short escape sequence: \u%s`, )
}
:= [:4]
, := strconv.ParseUint(, 16, 16)
if != nil {
return , , fmt.Errorf(`invalid escape sequence \u%s: %s`, , )
}
= [4:]
default:
return , , fmt.Errorf(`unknown escape sequence \%c`, )
}
}
}
func ( string) (string, error) {
if len() == 0 {
return , fmt.Errorf("zero-length number")
}
if [0] == '-' {
= [1:]
if len() == 0 {
return , fmt.Errorf("missing number after minus")
}
}
:= 0
for < len() {
if [] < '0' || [] > '9' {
break
}
++
}
if <= 0 {
return , fmt.Errorf("expecting 0..9 digit, got %c", [0])
}
if [0] == '0' && != 1 {
return , fmt.Errorf("unexpected number starting from 0")
}
if >= len() {
return "", nil
}
if [] == '.' {
= [+1:]
if len() == 0 {
return , fmt.Errorf("missing fractional part")
}
= 0
for < len() {
if [] < '0' || [] > '9' {
break
}
++
}
if == 0 {
return , fmt.Errorf("expecting 0..9 digit in fractional part, got %c", [0])
}
if >= len() {
return "", nil
}
}
if [] == 'e' || [] == 'E' {
= [+1:]
if len() == 0 {
return , fmt.Errorf("missing exponent part")
}
if [0] == '-' || [0] == '+' {
= [1:]
if len() == 0 {
return , fmt.Errorf("missing exponent part")
}
}
= 0
for < len() {
if [] < '0' || [] > '9' {
break
}
++
}
if == 0 {
return , fmt.Errorf("expecting 0..9 digit in exponent part, got %c", [0])
}
if >= len() {
return "", nil
}
}
return [:], nil
}