forked from mirror/go-json
WIP
This commit is contained in:
parent
76baae6ce8
commit
5090a4bf5e
60
decode.go
60
decode.go
|
@ -117,8 +117,58 @@ func (d *Decoder) decodeForUnmarshalNoEscape(src []byte, v interface{}) error {
|
||||||
return d.decode(src, header)
|
return d.decode(src, header)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) prepareForDecodeArray() error {
|
||||||
|
for {
|
||||||
|
switch s.char() {
|
||||||
|
case ' ', '\t', '\r', '\n':
|
||||||
|
s.cursor++
|
||||||
|
continue
|
||||||
|
case ',', ':':
|
||||||
|
return errExpected("value in array element", s.totalOffset())
|
||||||
|
case nul:
|
||||||
|
if s.read() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return io.EOF
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
s.context = streamContextTypeArrayDelim
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) prepareForDecodeArrayDelim() error {
|
||||||
|
for {
|
||||||
|
switch s.char() {
|
||||||
|
case ' ', '\t', '\r', '\n':
|
||||||
|
s.cursor++
|
||||||
|
continue
|
||||||
|
case ',':
|
||||||
|
s.cursor++
|
||||||
|
return nil
|
||||||
|
case ']':
|
||||||
|
s.cursor++
|
||||||
|
s.context = streamContextTypeValue
|
||||||
|
return nil
|
||||||
|
case nul:
|
||||||
|
if s.read() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return io.EOF
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Decoder) prepareForDecode() error {
|
func (d *Decoder) prepareForDecode() error {
|
||||||
s := d.s
|
s := d.s
|
||||||
|
switch s.context {
|
||||||
|
case streamContextTypeArray:
|
||||||
|
return d.prepareForDecodeArray()
|
||||||
|
case streamContextTypeArrayDelim:
|
||||||
|
return d.prepareForDecodeArrayDelim()
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
switch s.char() {
|
switch s.char() {
|
||||||
case ' ', '\t', '\r', '\n':
|
case ' ', '\t', '\r', '\n':
|
||||||
|
@ -202,8 +252,16 @@ func (d *Decoder) Token() (Token, error) {
|
||||||
switch c {
|
switch c {
|
||||||
case ' ', '\n', '\r', '\t':
|
case ' ', '\n', '\r', '\t':
|
||||||
s.cursor++
|
s.cursor++
|
||||||
case '{', '[', ']', '}':
|
case ']', '}':
|
||||||
s.cursor++
|
s.cursor++
|
||||||
|
d.s.context = streamContextTypeValue
|
||||||
|
return Delim(c), nil
|
||||||
|
case '{':
|
||||||
|
s.cursor++
|
||||||
|
d.s.context = streamContextTypeObject
|
||||||
|
return Delim(c), nil
|
||||||
|
case '[':
|
||||||
|
d.s.context = streamContextTypeArray
|
||||||
return Delim(c), nil
|
return Delim(c), nil
|
||||||
case ',', ':':
|
case ',', ':':
|
||||||
s.cursor++
|
s.cursor++
|
||||||
|
|
|
@ -20,8 +20,18 @@ type stream struct {
|
||||||
allRead bool
|
allRead bool
|
||||||
useNumber bool
|
useNumber bool
|
||||||
disallowUnknownFields bool
|
disallowUnknownFields bool
|
||||||
|
context streamContextType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
streamContextTypeValue streamContextType = iota
|
||||||
|
streamContextTypeArray
|
||||||
|
streamContextTypeArrayDelim /* expect ',' or ']' */
|
||||||
|
streamContextTypeObject
|
||||||
|
streamContextTypeObjectColon /* expect ':' */
|
||||||
|
streamContextTypeObjectDelim /* expect ',' or '}' */
|
||||||
|
)
|
||||||
|
|
||||||
func newStream(r io.Reader) *stream {
|
func newStream(r io.Reader) *stream {
|
||||||
return &stream{
|
return &stream{
|
||||||
r: r,
|
r: r,
|
||||||
|
|
2
error.go
2
error.go
|
@ -3,6 +3,7 @@ package json
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -122,6 +123,7 @@ func errNotAtBeginningOfValue(cursor int64) *SyntaxError {
|
||||||
}
|
}
|
||||||
|
|
||||||
func errUnexpectedEndOfJSON(msg string, cursor int64) *SyntaxError {
|
func errUnexpectedEndOfJSON(msg string, cursor int64) *SyntaxError {
|
||||||
|
fmt.Println(runtime.Caller(1))
|
||||||
return &SyntaxError{
|
return &SyntaxError{
|
||||||
msg: fmt.Sprintf("json: %s unexpected end of JSON input", msg),
|
msg: fmt.Sprintf("json: %s unexpected end of JSON input", msg),
|
||||||
Offset: cursor,
|
Offset: cursor,
|
||||||
|
|
102
stream_test.go
102
stream_test.go
|
@ -324,57 +324,59 @@ type decodeThis struct {
|
||||||
|
|
||||||
var tokenStreamCases = []tokenStreamCase{
|
var tokenStreamCases = []tokenStreamCase{
|
||||||
// streaming token cases
|
// streaming token cases
|
||||||
{json: `10`, expTokens: []interface{}{float64(10)}},
|
/*
|
||||||
{json: ` [10] `, expTokens: []interface{}{
|
{json: `10`, expTokens: []interface{}{float64(10)}},
|
||||||
json.Delim('['), float64(10), json.Delim(']')}},
|
{json: ` [10] `, expTokens: []interface{}{
|
||||||
{json: ` [false,10,"b"] `, expTokens: []interface{}{
|
json.Delim('['), float64(10), json.Delim(']')}},
|
||||||
json.Delim('['), false, float64(10), "b", json.Delim(']')}},
|
{json: ` [false,10,"b"] `, expTokens: []interface{}{
|
||||||
{json: `{ "a": 1 }`, expTokens: []interface{}{
|
json.Delim('['), false, float64(10), "b", json.Delim(']')}},
|
||||||
json.Delim('{'), "a", float64(1), json.Delim('}')}},
|
{json: `{ "a": 1 }`, expTokens: []interface{}{
|
||||||
{json: `{"a": 1, "b":"3"}`, expTokens: []interface{}{
|
json.Delim('{'), "a", float64(1), json.Delim('}')}},
|
||||||
json.Delim('{'), "a", float64(1), "b", "3", json.Delim('}')}},
|
{json: `{"a": 1, "b":"3"}`, expTokens: []interface{}{
|
||||||
{json: ` [{"a": 1},{"a": 2}] `, expTokens: []interface{}{
|
json.Delim('{'), "a", float64(1), "b", "3", json.Delim('}')}},
|
||||||
json.Delim('['),
|
{json: ` [{"a": 1},{"a": 2}] `, expTokens: []interface{}{
|
||||||
json.Delim('{'), "a", float64(1), json.Delim('}'),
|
json.Delim('['),
|
||||||
json.Delim('{'), "a", float64(2), json.Delim('}'),
|
json.Delim('{'), "a", float64(1), json.Delim('}'),
|
||||||
json.Delim(']')}},
|
json.Delim('{'), "a", float64(2), json.Delim('}'),
|
||||||
{json: `{"obj": {"a": 1}}`, expTokens: []interface{}{
|
json.Delim(']')}},
|
||||||
json.Delim('{'), "obj", json.Delim('{'), "a", float64(1), json.Delim('}'),
|
{json: `{"obj": {"a": 1}}`, expTokens: []interface{}{
|
||||||
json.Delim('}')}},
|
json.Delim('{'), "obj", json.Delim('{'), "a", float64(1), json.Delim('}'),
|
||||||
{json: `{"obj": [{"a": 1}]}`, expTokens: []interface{}{
|
json.Delim('}')}},
|
||||||
json.Delim('{'), "obj", json.Delim('['),
|
{json: `{"obj": [{"a": 1}]}`, expTokens: []interface{}{
|
||||||
json.Delim('{'), "a", float64(1), json.Delim('}'),
|
json.Delim('{'), "obj", json.Delim('['),
|
||||||
json.Delim(']'), json.Delim('}')}},
|
json.Delim('{'), "a", float64(1), json.Delim('}'),
|
||||||
|
json.Delim(']'), json.Delim('}')}},
|
||||||
|
|
||||||
// streaming tokens with intermittent Decode()
|
// streaming tokens with intermittent Decode()
|
||||||
{json: `{ "a": 1 }`, expTokens: []interface{}{
|
{json: `{ "a": 1 }`, expTokens: []interface{}{
|
||||||
json.Delim('{'), "a",
|
json.Delim('{'), "a",
|
||||||
decodeThis{float64(1)},
|
decodeThis{float64(1)},
|
||||||
json.Delim('}')}},
|
json.Delim('}')}},
|
||||||
{json: ` [ { "a" : 1 } ] `, expTokens: []interface{}{
|
{json: ` [ { "a" : 1 } ] `, expTokens: []interface{}{
|
||||||
json.Delim('['),
|
json.Delim('['),
|
||||||
decodeThis{map[string]interface{}{"a": float64(1)}},
|
decodeThis{map[string]interface{}{"a": float64(1)}},
|
||||||
json.Delim(']')}},
|
json.Delim(']')}},
|
||||||
{json: ` [{"a": 1},{"a": 2}] `, expTokens: []interface{}{
|
{json: ` [{"a": 1},{"a": 2}] `, expTokens: []interface{}{
|
||||||
json.Delim('['),
|
json.Delim('['),
|
||||||
decodeThis{map[string]interface{}{"a": float64(1)}},
|
decodeThis{map[string]interface{}{"a": float64(1)}},
|
||||||
decodeThis{map[string]interface{}{"a": float64(2)}},
|
decodeThis{map[string]interface{}{"a": float64(2)}},
|
||||||
json.Delim(']')}},
|
json.Delim(']')}},
|
||||||
{json: `{ "obj" : [ { "a" : 1 } ] }`, expTokens: []interface{}{
|
{json: `{ "obj" : [ { "a" : 1 } ] }`, expTokens: []interface{}{
|
||||||
json.Delim('{'), "obj", json.Delim('['),
|
json.Delim('{'), "obj", json.Delim('['),
|
||||||
decodeThis{map[string]interface{}{"a": float64(1)}},
|
decodeThis{map[string]interface{}{"a": float64(1)}},
|
||||||
json.Delim(']'), json.Delim('}')}},
|
json.Delim(']'), json.Delim('}')}},
|
||||||
|
|
||||||
{json: `{"obj": {"a": 1}}`, expTokens: []interface{}{
|
{json: `{"obj": {"a": 1}}`, expTokens: []interface{}{
|
||||||
json.Delim('{'), "obj",
|
json.Delim('{'), "obj",
|
||||||
decodeThis{map[string]interface{}{"a": float64(1)}},
|
decodeThis{map[string]interface{}{"a": float64(1)}},
|
||||||
json.Delim('}')}},
|
json.Delim('}')}},
|
||||||
{json: `{"obj": [{"a": 1}]}`, expTokens: []interface{}{
|
{json: `{"obj": [{"a": 1}]}`, expTokens: []interface{}{
|
||||||
json.Delim('{'), "obj",
|
json.Delim('{'), "obj",
|
||||||
decodeThis{[]interface{}{
|
decodeThis{[]interface{}{
|
||||||
map[string]interface{}{"a": float64(1)},
|
map[string]interface{}{"a": float64(1)},
|
||||||
}},
|
}},
|
||||||
json.Delim('}')}},
|
json.Delim('}')}},
|
||||||
|
*/
|
||||||
{json: ` [{"a": 1} {"a": 2}] `, expTokens: []interface{}{
|
{json: ` [{"a": 1} {"a": 2}] `, expTokens: []interface{}{
|
||||||
json.Delim('['),
|
json.Delim('['),
|
||||||
decodeThis{map[string]interface{}{"a": float64(1)}},
|
decodeThis{map[string]interface{}{"a": float64(1)}},
|
||||||
|
@ -393,7 +395,6 @@ var tokenStreamCases = []tokenStreamCase{
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func TestDecodeInStream(t *testing.T) {
|
func TestDecodeInStream(t *testing.T) {
|
||||||
for ci, tcase := range tokenStreamCases {
|
for ci, tcase := range tokenStreamCases {
|
||||||
|
|
||||||
|
@ -428,7 +429,6 @@ func TestDecodeInStream(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// Test from golang.org/issue/11893
|
// Test from golang.org/issue/11893
|
||||||
func TestHTTPDecoding(t *testing.T) {
|
func TestHTTPDecoding(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue