Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Xiaomi
soar
提交
ee667a09
S
soar
项目概览
Xiaomi
/
soar
大约 2 年 前同步成功
通知
467
Star
8513
Fork
1329
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
soar
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
ee667a09
编写于
1月 10, 2019
作者:
martianzhang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
tiast-json marshal unexported type
change encoding/json -> github.com/CorgiMan/json2
上级
d891be61
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
3220 addition
and
2 deletion
+3220
-2
ast/tidb.go
ast/tidb.go
+2
-2
vendor/github.com/CorgiMan/json2/README.md
vendor/github.com/CorgiMan/json2/README.md
+0
-0
vendor/github.com/CorgiMan/json2/decode.go
vendor/github.com/CorgiMan/json2/decode.go
+1047
-0
vendor/github.com/CorgiMan/json2/encode.go
vendor/github.com/CorgiMan/json2/encode.go
+1168
-0
vendor/github.com/CorgiMan/json2/indent.go
vendor/github.com/CorgiMan/json2/indent.go
+136
-0
vendor/github.com/CorgiMan/json2/scanner.go
vendor/github.com/CorgiMan/json2/scanner.go
+623
-0
vendor/github.com/CorgiMan/json2/stream.go
vendor/github.com/CorgiMan/json2/stream.go
+200
-0
vendor/github.com/CorgiMan/json2/tags.go
vendor/github.com/CorgiMan/json2/tags.go
+44
-0
未找到文件。
ast/tidb.go
浏览文件 @
ee667a09
...
...
@@ -17,14 +17,14 @@
package
ast
import
(
"encoding/json"
"github.com/XiaoMi/soar/common"
"github.com/kr/pretty"
"github.com/pingcap/parser"
"github.com/pingcap/parser/ast"
json
"github.com/CorgiMan/json2"
// for pingcap parser
_
"github.com/pingcap/tidb/types/parser_driver"
)
...
...
vendor/github.com/CorgiMan/json2/README.md
0 → 100644
浏览文件 @
ee667a09
B
#JSON2
vendor/github.com/CorgiMan/json2/decode.go
0 → 100644
浏览文件 @
ee667a09
// I stole this from golang, only changed package name
// and commented out line 1018-1020 of encode.go
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Represents JSON data structure using native Go types: booleans, floats,
// strings, arrays, and maps.
package
json2
import
(
"encoding"
"encoding/base64"
"errors"
"fmt"
"reflect"
"runtime"
"strconv"
"strings"
"unicode"
"unicode/utf16"
"unicode/utf8"
)
// Unmarshal parses the JSON-encoded data and stores the result
// in the value pointed to by v.
//
// Unmarshal uses the inverse of the encodings that
// Marshal uses, allocating maps, slices, and pointers as necessary,
// with the following additional rules:
//
// To unmarshal JSON into a pointer, Unmarshal first handles the case of
// the JSON being the JSON literal null. In that case, Unmarshal sets
// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into
// the value pointed at by the pointer. If the pointer is nil, Unmarshal
// allocates a new value for it to point to.
//
// To unmarshal JSON into a struct, Unmarshal matches incoming object
// keys to the keys used by Marshal (either the struct field name or its tag),
// preferring an exact match but also accepting a case-insensitive match.
//
// To unmarshal JSON into an interface value,
// Unmarshal stores one of these in the interface value:
//
// bool, for JSON booleans
// float64, for JSON numbers
// string, for JSON strings
// []interface{}, for JSON arrays
// map[string]interface{}, for JSON objects
// nil for JSON null
//
// If a JSON value is not appropriate for a given target type,
// or if a JSON number overflows the target type, Unmarshal
// skips that field and completes the unmarshalling as best it can.
// If no more serious errors are encountered, Unmarshal returns
// an UnmarshalTypeError describing the earliest such error.
//
// When unmarshaling quoted strings, invalid UTF-8 or
// invalid UTF-16 surrogate pairs are not treated as an error.
// Instead, they are replaced by the Unicode replacement
// character U+FFFD.
//
func
Unmarshal
(
data
[]
byte
,
v
interface
{})
error
{
// Check for well-formedness.
// Avoids filling out half a data structure
// before discovering a JSON syntax error.
var
d
decodeState
err
:=
checkValid
(
data
,
&
d
.
scan
)
if
err
!=
nil
{
return
err
}
d
.
init
(
data
)
return
d
.
unmarshal
(
v
)
}
// Unmarshaler is the interface implemented by objects
// that can unmarshal a JSON description of themselves.
// The input can be assumed to be a valid encoding of
// a JSON value. UnmarshalJSON must copy the JSON data
// if it wishes to retain the data after returning.
type
Unmarshaler
interface
{
UnmarshalJSON
([]
byte
)
error
}
// An UnmarshalTypeError describes a JSON value that was
// not appropriate for a value of a specific Go type.
type
UnmarshalTypeError
struct
{
Value
string
// description of JSON value - "bool", "array", "number -5"
Type
reflect
.
Type
// type of Go value it could not be assigned to
}
func
(
e
*
UnmarshalTypeError
)
Error
()
string
{
return
"json: cannot unmarshal "
+
e
.
Value
+
" into Go value of type "
+
e
.
Type
.
String
()
}
// An UnmarshalFieldError describes a JSON object key that
// led to an unexported (and therefore unwritable) struct field.
// (No longer used; kept for compatibility.)
type
UnmarshalFieldError
struct
{
Key
string
Type
reflect
.
Type
Field
reflect
.
StructField
}
func
(
e
*
UnmarshalFieldError
)
Error
()
string
{
return
"json: cannot unmarshal object key "
+
strconv
.
Quote
(
e
.
Key
)
+
" into unexported field "
+
e
.
Field
.
Name
+
" of type "
+
e
.
Type
.
String
()
}
// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
// (The argument to Unmarshal must be a non-nil pointer.)
type
InvalidUnmarshalError
struct
{
Type
reflect
.
Type
}
func
(
e
*
InvalidUnmarshalError
)
Error
()
string
{
if
e
.
Type
==
nil
{
return
"json: Unmarshal(nil)"
}
if
e
.
Type
.
Kind
()
!=
reflect
.
Ptr
{
return
"json: Unmarshal(non-pointer "
+
e
.
Type
.
String
()
+
")"
}
return
"json: Unmarshal(nil "
+
e
.
Type
.
String
()
+
")"
}
func
(
d
*
decodeState
)
unmarshal
(
v
interface
{})
(
err
error
)
{
defer
func
()
{
if
r
:=
recover
();
r
!=
nil
{
if
_
,
ok
:=
r
.
(
runtime
.
Error
);
ok
{
panic
(
r
)
}
err
=
r
.
(
error
)
}
}()
rv
:=
reflect
.
ValueOf
(
v
)
if
rv
.
Kind
()
!=
reflect
.
Ptr
||
rv
.
IsNil
()
{
return
&
InvalidUnmarshalError
{
reflect
.
TypeOf
(
v
)}
}
d
.
scan
.
reset
()
// We decode rv not rv.Elem because the Unmarshaler interface
// test must be applied at the top level of the value.
d
.
value
(
rv
)
return
d
.
savedError
}
// A Number represents a JSON number literal.
type
Number
string
// String returns the literal text of the number.
func
(
n
Number
)
String
()
string
{
return
string
(
n
)
}
// Float64 returns the number as a float64.
func
(
n
Number
)
Float64
()
(
float64
,
error
)
{
return
strconv
.
ParseFloat
(
string
(
n
),
64
)
}
// Int64 returns the number as an int64.
func
(
n
Number
)
Int64
()
(
int64
,
error
)
{
return
strconv
.
ParseInt
(
string
(
n
),
10
,
64
)
}
// decodeState represents the state while decoding a JSON value.
type
decodeState
struct
{
data
[]
byte
off
int
// read offset in data
scan
scanner
nextscan
scanner
// for calls to nextValue
savedError
error
tempstr
string
// scratch space to avoid some allocations
useNumber
bool
}
// errPhase is used for errors that should not happen unless
// there is a bug in the JSON decoder or something is editing
// the data slice while the decoder executes.
var
errPhase
=
errors
.
New
(
"JSON decoder out of sync - data changing underfoot?"
)
func
(
d
*
decodeState
)
init
(
data
[]
byte
)
*
decodeState
{
d
.
data
=
data
d
.
off
=
0
d
.
savedError
=
nil
return
d
}
// error aborts the decoding by panicking with err.
func
(
d
*
decodeState
)
error
(
err
error
)
{
panic
(
err
)
}
// saveError saves the first err it is called with,
// for reporting at the end of the unmarshal.
func
(
d
*
decodeState
)
saveError
(
err
error
)
{
if
d
.
savedError
==
nil
{
d
.
savedError
=
err
}
}
// next cuts off and returns the next full JSON value in d.data[d.off:].
// The next value is known to be an object or array, not a literal.
func
(
d
*
decodeState
)
next
()
[]
byte
{
c
:=
d
.
data
[
d
.
off
]
item
,
rest
,
err
:=
nextValue
(
d
.
data
[
d
.
off
:
],
&
d
.
nextscan
)
if
err
!=
nil
{
d
.
error
(
err
)
}
d
.
off
=
len
(
d
.
data
)
-
len
(
rest
)
// Our scanner has seen the opening brace/bracket
// and thinks we're still in the middle of the object.
// invent a closing brace/bracket to get it out.
if
c
==
'{'
{
d
.
scan
.
step
(
&
d
.
scan
,
'}'
)
}
else
{
d
.
scan
.
step
(
&
d
.
scan
,
']'
)
}
return
item
}
// scanWhile processes bytes in d.data[d.off:] until it
// receives a scan code not equal to op.
// It updates d.off and returns the new scan code.
func
(
d
*
decodeState
)
scanWhile
(
op
int
)
int
{
var
newOp
int
for
{
if
d
.
off
>=
len
(
d
.
data
)
{
newOp
=
d
.
scan
.
eof
()
d
.
off
=
len
(
d
.
data
)
+
1
// mark processed EOF with len+1
}
else
{
c
:=
int
(
d
.
data
[
d
.
off
])
d
.
off
++
newOp
=
d
.
scan
.
step
(
&
d
.
scan
,
c
)
}
if
newOp
!=
op
{
break
}
}
return
newOp
}
// value decodes a JSON value from d.data[d.off:] into the value.
// it updates d.off to point past the decoded value.
func
(
d
*
decodeState
)
value
(
v
reflect
.
Value
)
{
if
!
v
.
IsValid
()
{
_
,
rest
,
err
:=
nextValue
(
d
.
data
[
d
.
off
:
],
&
d
.
nextscan
)
if
err
!=
nil
{
d
.
error
(
err
)
}
d
.
off
=
len
(
d
.
data
)
-
len
(
rest
)
// d.scan thinks we're still at the beginning of the item.
// Feed in an empty string - the shortest, simplest value -
// so that it knows we got to the end of the value.
if
d
.
scan
.
redo
{
// rewind.
d
.
scan
.
redo
=
false
d
.
scan
.
step
=
stateBeginValue
}
d
.
scan
.
step
(
&
d
.
scan
,
'"'
)
d
.
scan
.
step
(
&
d
.
scan
,
'"'
)
n
:=
len
(
d
.
scan
.
parseState
)
if
n
>
0
&&
d
.
scan
.
parseState
[
n
-
1
]
==
parseObjectKey
{
// d.scan thinks we just read an object key; finish the object
d
.
scan
.
step
(
&
d
.
scan
,
':'
)
d
.
scan
.
step
(
&
d
.
scan
,
'"'
)
d
.
scan
.
step
(
&
d
.
scan
,
'"'
)
d
.
scan
.
step
(
&
d
.
scan
,
'}'
)
}
return
}
switch
op
:=
d
.
scanWhile
(
scanSkipSpace
);
op
{
default
:
d
.
error
(
errPhase
)
case
scanBeginArray
:
d
.
array
(
v
)
case
scanBeginObject
:
d
.
object
(
v
)
case
scanBeginLiteral
:
d
.
literal
(
v
)
}
}
// indirect walks down v allocating pointers as needed,
// until it gets to a non-pointer.
// if it encounters an Unmarshaler, indirect stops and returns that.
// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.
func
(
d
*
decodeState
)
indirect
(
v
reflect
.
Value
,
decodingNull
bool
)
(
Unmarshaler
,
encoding
.
TextUnmarshaler
,
reflect
.
Value
)
{
// If v is a named type and is addressable,
// start with its address, so that if the type has pointer methods,
// we find them.
if
v
.
Kind
()
!=
reflect
.
Ptr
&&
v
.
Type
()
.
Name
()
!=
""
&&
v
.
CanAddr
()
{
v
=
v
.
Addr
()
}
for
{
// Load value from interface, but only if the result will be
// usefully addressable.
if
v
.
Kind
()
==
reflect
.
Interface
&&
!
v
.
IsNil
()
{
e
:=
v
.
Elem
()
if
e
.
Kind
()
==
reflect
.
Ptr
&&
!
e
.
IsNil
()
&&
(
!
decodingNull
||
e
.
Elem
()
.
Kind
()
==
reflect
.
Ptr
)
{
v
=
e
continue
}
}
if
v
.
Kind
()
!=
reflect
.
Ptr
{
break
}
if
v
.
Elem
()
.
Kind
()
!=
reflect
.
Ptr
&&
decodingNull
&&
v
.
CanSet
()
{
break
}
if
v
.
IsNil
()
{
v
.
Set
(
reflect
.
New
(
v
.
Type
()
.
Elem
()))
}
if
v
.
Type
()
.
NumMethod
()
>
0
{
if
u
,
ok
:=
v
.
Interface
()
.
(
Unmarshaler
);
ok
{
return
u
,
nil
,
reflect
.
Value
{}
}
if
u
,
ok
:=
v
.
Interface
()
.
(
encoding
.
TextUnmarshaler
);
ok
{
return
nil
,
u
,
reflect
.
Value
{}
}
}
v
=
v
.
Elem
()
}
return
nil
,
nil
,
v
}
// array consumes an array from d.data[d.off-1:], decoding into the value v.
// the first byte of the array ('[') has been read already.
func
(
d
*
decodeState
)
array
(
v
reflect
.
Value
)
{
// Check for unmarshaler.
u
,
ut
,
pv
:=
d
.
indirect
(
v
,
false
)
if
u
!=
nil
{
d
.
off
--
err
:=
u
.
UnmarshalJSON
(
d
.
next
())
if
err
!=
nil
{
d
.
error
(
err
)
}
return
}
if
ut
!=
nil
{
d
.
saveError
(
&
UnmarshalTypeError
{
"array"
,
v
.
Type
()})
d
.
off
--
d
.
next
()
return
}
v
=
pv
// Check type of target.
switch
v
.
Kind
()
{
case
reflect
.
Interface
:
if
v
.
NumMethod
()
==
0
{
// Decoding into nil interface? Switch to non-reflect code.
v
.
Set
(
reflect
.
ValueOf
(
d
.
arrayInterface
()))
return
}
// Otherwise it's invalid.
fallthrough
default
:
d
.
saveError
(
&
UnmarshalTypeError
{
"array"
,
v
.
Type
()})
d
.
off
--
d
.
next
()
return
case
reflect
.
Array
:
case
reflect
.
Slice
:
break
}
i
:=
0
for
{
// Look ahead for ] - can only happen on first iteration.
op
:=
d
.
scanWhile
(
scanSkipSpace
)
if
op
==
scanEndArray
{
break
}
// Back up so d.value can have the byte we just read.
d
.
off
--
d
.
scan
.
undo
(
op
)
// Get element of array, growing if necessary.
if
v
.
Kind
()
==
reflect
.
Slice
{
// Grow slice if necessary
if
i
>=
v
.
Cap
()
{
newcap
:=
v
.
Cap
()
+
v
.
Cap
()
/
2
if
newcap
<
4
{
newcap
=
4
}
newv
:=
reflect
.
MakeSlice
(
v
.
Type
(),
v
.
Len
(),
newcap
)
reflect
.
Copy
(
newv
,
v
)
v
.
Set
(
newv
)
}
if
i
>=
v
.
Len
()
{
v
.
SetLen
(
i
+
1
)
}
}
if
i
<
v
.
Len
()
{
// Decode into element.
d
.
value
(
v
.
Index
(
i
))
}
else
{
// Ran out of fixed array: skip.
d
.
value
(
reflect
.
Value
{})
}
i
++
// Next token must be , or ].
op
=
d
.
scanWhile
(
scanSkipSpace
)
if
op
==
scanEndArray
{
break
}
if
op
!=
scanArrayValue
{
d
.
error
(
errPhase
)
}
}
if
i
<
v
.
Len
()
{
if
v
.
Kind
()
==
reflect
.
Array
{
// Array. Zero the rest.
z
:=
reflect
.
Zero
(
v
.
Type
()
.
Elem
())
for
;
i
<
v
.
Len
();
i
++
{
v
.
Index
(
i
)
.
Set
(
z
)
}
}
else
{
v
.
SetLen
(
i
)
}
}
if
i
==
0
&&
v
.
Kind
()
==
reflect
.
Slice
{
v
.
Set
(
reflect
.
MakeSlice
(
v
.
Type
(),
0
,
0
))
}
}
// object consumes an object from d.data[d.off-1:], decoding into the value v.
// the first byte of the object ('{') has been read already.
func
(
d
*
decodeState
)
object
(
v
reflect
.
Value
)
{
// Check for unmarshaler.
u
,
ut
,
pv
:=
d
.
indirect
(
v
,
false
)
if
u
!=
nil
{
d
.
off
--
err
:=
u
.
UnmarshalJSON
(
d
.
next
())
if
err
!=
nil
{
d
.
error
(
err
)
}
return
}
if
ut
!=
nil
{
d
.
saveError
(
&
UnmarshalTypeError
{
"object"
,
v
.
Type
()})
d
.
off
--
d
.
next
()
// skip over { } in input
return
}
v
=
pv
// Decoding into nil interface? Switch to non-reflect code.
if
v
.
Kind
()
==
reflect
.
Interface
&&
v
.
NumMethod
()
==
0
{
v
.
Set
(
reflect
.
ValueOf
(
d
.
objectInterface
()))
return
}
// Check type of target: struct or map[string]T
switch
v
.
Kind
()
{
case
reflect
.
Map
:
// map must have string kind
t
:=
v
.
Type
()
if
t
.
Key
()
.
Kind
()
!=
reflect
.
String
{
d
.
saveError
(
&
UnmarshalTypeError
{
"object"
,
v
.
Type
()})
break
}
if
v
.
IsNil
()
{
v
.
Set
(
reflect
.
MakeMap
(
t
))
}
case
reflect
.
Struct
:
default
:
d
.
saveError
(
&
UnmarshalTypeError
{
"object"
,
v
.
Type
()})
d
.
off
--
d
.
next
()
// skip over { } in input
return
}
var
mapElem
reflect
.
Value
for
{
// Read opening " of string key or closing }.
op
:=
d
.
scanWhile
(
scanSkipSpace
)
if
op
==
scanEndObject
{
// closing } - can only happen on first iteration.
break
}
if
op
!=
scanBeginLiteral
{
d
.
error
(
errPhase
)
}
// Read string key.
start
:=
d
.
off
-
1
op
=
d
.
scanWhile
(
scanContinue
)
item
:=
d
.
data
[
start
:
d
.
off
-
1
]
key
,
ok
:=
unquote
(
item
)
if
!
ok
{
d
.
error
(
errPhase
)
}
// Figure out field corresponding to key.
var
subv
reflect
.
Value
destring
:=
false
// whether the value is wrapped in a string to be decoded first
if
v
.
Kind
()
==
reflect
.
Map
{
elemType
:=
v
.
Type
()
.
Elem
()
if
!
mapElem
.
IsValid
()
{
mapElem
=
reflect
.
New
(
elemType
)
.
Elem
()
}
else
{
mapElem
.
Set
(
reflect
.
Zero
(
elemType
))
}
subv
=
mapElem
}
else
{
var
f
*
field
fields
:=
cachedTypeFields
(
v
.
Type
())
for
i
:=
range
fields
{
ff
:=
&
fields
[
i
]
if
ff
.
name
==
key
{
f
=
ff
break
}
if
f
==
nil
&&
strings
.
EqualFold
(
ff
.
name
,
key
)
{
f
=
ff
}
}
if
f
!=
nil
{
subv
=
v
destring
=
f
.
quoted
for
_
,
i
:=
range
f
.
index
{
if
subv
.
Kind
()
==
reflect
.
Ptr
{
if
subv
.
IsNil
()
{
subv
.
Set
(
reflect
.
New
(
subv
.
Type
()
.
Elem
()))
}
subv
=
subv
.
Elem
()
}
subv
=
subv
.
Field
(
i
)
}
}
}
// Read : before value.
if
op
==
scanSkipSpace
{
op
=
d
.
scanWhile
(
scanSkipSpace
)
}
if
op
!=
scanObjectKey
{
d
.
error
(
errPhase
)
}
// Read value.
if
destring
{
d
.
value
(
reflect
.
ValueOf
(
&
d
.
tempstr
))
d
.
literalStore
([]
byte
(
d
.
tempstr
),
subv
,
true
)
}
else
{
d
.
value
(
subv
)
}
// Write value back to map;
// if using struct, subv points into struct already.
if
v
.
Kind
()
==
reflect
.
Map
{
kv
:=
reflect
.
ValueOf
(
key
)
.
Convert
(
v
.
Type
()
.
Key
())
v
.
SetMapIndex
(
kv
,
subv
)
}
// Next token must be , or }.
op
=
d
.
scanWhile
(
scanSkipSpace
)
if
op
==
scanEndObject
{
break
}
if
op
!=
scanObjectValue
{
d
.
error
(
errPhase
)
}
}
}
// literal consumes a literal from d.data[d.off-1:], decoding into the value v.
// The first byte of the literal has been read already
// (that's how the caller knows it's a literal).
func
(
d
*
decodeState
)
literal
(
v
reflect
.
Value
)
{
// All bytes inside literal return scanContinue op code.
start
:=
d
.
off
-
1
op
:=
d
.
scanWhile
(
scanContinue
)
// Scan read one byte too far; back up.
d
.
off
--
d
.
scan
.
undo
(
op
)
d
.
literalStore
(
d
.
data
[
start
:
d
.
off
],
v
,
false
)
}
// convertNumber converts the number literal s to a float64 or a Number
// depending on the setting of d.useNumber.
func
(
d
*
decodeState
)
convertNumber
(
s
string
)
(
interface
{},
error
)
{
if
d
.
useNumber
{
return
Number
(
s
),
nil
}
f
,
err
:=
strconv
.
ParseFloat
(
s
,
64
)
if
err
!=
nil
{
return
nil
,
&
UnmarshalTypeError
{
"number "
+
s
,
reflect
.
TypeOf
(
0.0
)}
}
return
f
,
nil
}
var
numberType
=
reflect
.
TypeOf
(
Number
(
""
))
// literalStore decodes a literal stored in item into v.
//
// fromQuoted indicates whether this literal came from unwrapping a
// string from the ",string" struct tag option. this is used only to
// produce more helpful error messages.
func
(
d
*
decodeState
)
literalStore
(
item
[]
byte
,
v
reflect
.
Value
,
fromQuoted
bool
)
{
// Check for unmarshaler.
if
len
(
item
)
==
0
{
//Empty string given
d
.
saveError
(
fmt
.
Errorf
(
"json: invalid use of ,string struct tag, trying to unmarshal %q into %v"
,
item
,
v
.
Type
()))
return
}
wantptr
:=
item
[
0
]
==
'n'
// null
u
,
ut
,
pv
:=
d
.
indirect
(
v
,
wantptr
)
if
u
!=
nil
{
err
:=
u
.
UnmarshalJSON
(
item
)
if
err
!=
nil
{
d
.
error
(
err
)
}
return
}
if
ut
!=
nil
{
if
item
[
0
]
!=
'"'
{
if
fromQuoted
{
d
.
saveError
(
fmt
.
Errorf
(
"json: invalid use of ,string struct tag, trying to unmarshal %q into %v"
,
item
,
v
.
Type
()))
}
else
{
d
.
saveError
(
&
UnmarshalTypeError
{
"string"
,
v
.
Type
()})
}
}
s
,
ok
:=
unquoteBytes
(
item
)
if
!
ok
{
if
fromQuoted
{
d
.
error
(
fmt
.
Errorf
(
"json: invalid use of ,string struct tag, trying to unmarshal %q into %v"
,
item
,
v
.
Type
()))
}
else
{
d
.
error
(
errPhase
)
}
}
err
:=
ut
.
UnmarshalText
(
s
)
if
err
!=
nil
{
d
.
error
(
err
)
}
return
}
v
=
pv
switch
c
:=
item
[
0
];
c
{
case
'n'
:
// null
switch
v
.
Kind
()
{
case
reflect
.
Interface
,
reflect
.
Ptr
,
reflect
.
Map
,
reflect
.
Slice
:
v
.
Set
(
reflect
.
Zero
(
v
.
Type
()))
// otherwise, ignore null for primitives/string
}
case
't'
,
'f'
:
// true, false
value
:=
c
==
't'
switch
v
.
Kind
()
{
default
:
if
fromQuoted
{
d
.
saveError
(
fmt
.
Errorf
(
"json: invalid use of ,string struct tag, trying to unmarshal %q into %v"
,
item
,
v
.
Type
()))
}
else
{
d
.
saveError
(
&
UnmarshalTypeError
{
"bool"
,
v
.
Type
()})
}
case
reflect
.
Bool
:
v
.
SetBool
(
value
)
case
reflect
.
Interface
:
if
v
.
NumMethod
()
==
0
{
v
.
Set
(
reflect
.
ValueOf
(
value
))
}
else
{
d
.
saveError
(
&
UnmarshalTypeError
{
"bool"
,
v
.
Type
()})
}
}
case
'"'
:
// string
s
,
ok
:=
unquoteBytes
(
item
)
if
!
ok
{
if
fromQuoted
{
d
.
error
(
fmt
.
Errorf
(
"json: invalid use of ,string struct tag, trying to unmarshal %q into %v"
,
item
,
v
.
Type
()))
}
else
{
d
.
error
(
errPhase
)
}
}
switch
v
.
Kind
()
{
default
:
d
.
saveError
(
&
UnmarshalTypeError
{
"string"
,
v
.
Type
()})
case
reflect
.
Slice
:
if
v
.
Type
()
!=
byteSliceType
{
d
.
saveError
(
&
UnmarshalTypeError
{
"string"
,
v
.
Type
()})
break
}
b
:=
make
([]
byte
,
base64
.
StdEncoding
.
DecodedLen
(
len
(
s
)))
n
,
err
:=
base64
.
StdEncoding
.
Decode
(
b
,
s
)
if
err
!=
nil
{
d
.
saveError
(
err
)
break
}
v
.
Set
(
reflect
.
ValueOf
(
b
[
0
:
n
]))
case
reflect
.
String
:
v
.
SetString
(
string
(
s
))
case
reflect
.
Interface
:
if
v
.
NumMethod
()
==
0
{
v
.
Set
(
reflect
.
ValueOf
(
string
(
s
)))
}
else
{
d
.
saveError
(
&
UnmarshalTypeError
{
"string"
,
v
.
Type
()})
}
}
default
:
// number
if
c
!=
'-'
&&
(
c
<
'0'
||
c
>
'9'
)
{
if
fromQuoted
{
d
.
error
(
fmt
.
Errorf
(
"json: invalid use of ,string struct tag, trying to unmarshal %q into %v"
,
item
,
v
.
Type
()))
}
else
{
d
.
error
(
errPhase
)
}
}
s
:=
string
(
item
)
switch
v
.
Kind
()
{
default
:
if
v
.
Kind
()
==
reflect
.
String
&&
v
.
Type
()
==
numberType
{
v
.
SetString
(
s
)
break
}
if
fromQuoted
{
d
.
error
(
fmt
.
Errorf
(
"json: invalid use of ,string struct tag, trying to unmarshal %q into %v"
,
item
,
v
.
Type
()))
}
else
{
d
.
error
(
&
UnmarshalTypeError
{
"number"
,
v
.
Type
()})
}
case
reflect
.
Interface
:
n
,
err
:=
d
.
convertNumber
(
s
)
if
err
!=
nil
{
d
.
saveError
(
err
)
break
}
if
v
.
NumMethod
()
!=
0
{
d
.
saveError
(
&
UnmarshalTypeError
{
"number"
,
v
.
Type
()})
break
}
v
.
Set
(
reflect
.
ValueOf
(
n
))
case
reflect
.
Int
,
reflect
.
Int8
,
reflect
.
Int16
,
reflect
.
Int32
,
reflect
.
Int64
:
n
,
err
:=
strconv
.
ParseInt
(
s
,
10
,
64
)
if
err
!=
nil
||
v
.
OverflowInt
(
n
)
{
d
.
saveError
(
&
UnmarshalTypeError
{
"number "
+
s
,
v
.
Type
()})
break
}
v
.
SetInt
(
n
)
case
reflect
.
Uint
,
reflect
.
Uint8
,
reflect
.
Uint16
,
reflect
.
Uint32
,
reflect
.
Uint64
,
reflect
.
Uintptr
:
n
,
err
:=
strconv
.
ParseUint
(
s
,
10
,
64
)
if
err
!=
nil
||
v
.
OverflowUint
(
n
)
{
d
.
saveError
(
&
UnmarshalTypeError
{
"number "
+
s
,
v
.
Type
()})
break
}
v
.
SetUint
(
n
)
case
reflect
.
Float32
,
reflect
.
Float64
:
n
,
err
:=
strconv
.
ParseFloat
(
s
,
v
.
Type
()
.
Bits
())
if
err
!=
nil
||
v
.
OverflowFloat
(
n
)
{
d
.
saveError
(
&
UnmarshalTypeError
{
"number "
+
s
,
v
.
Type
()})
break
}
v
.
SetFloat
(
n
)
}
}
}
// The xxxInterface routines build up a value to be stored
// in an empty interface. They are not strictly necessary,
// but they avoid the weight of reflection in this common case.
// valueInterface is like value but returns interface{}
func
(
d
*
decodeState
)
valueInterface
()
interface
{}
{
switch
d
.
scanWhile
(
scanSkipSpace
)
{
default
:
d
.
error
(
errPhase
)
panic
(
"unreachable"
)
case
scanBeginArray
:
return
d
.
arrayInterface
()
case
scanBeginObject
:
return
d
.
objectInterface
()
case
scanBeginLiteral
:
return
d
.
literalInterface
()
}
}
// arrayInterface is like array but returns []interface{}.
func
(
d
*
decodeState
)
arrayInterface
()
[]
interface
{}
{
var
v
=
make
([]
interface
{},
0
)
for
{
// Look ahead for ] - can only happen on first iteration.
op
:=
d
.
scanWhile
(
scanSkipSpace
)
if
op
==
scanEndArray
{
break
}
// Back up so d.value can have the byte we just read.
d
.
off
--
d
.
scan
.
undo
(
op
)
v
=
append
(
v
,
d
.
valueInterface
())
// Next token must be , or ].
op
=
d
.
scanWhile
(
scanSkipSpace
)
if
op
==
scanEndArray
{
break
}
if
op
!=
scanArrayValue
{
d
.
error
(
errPhase
)
}
}
return
v
}
// objectInterface is like object but returns map[string]interface{}.
func
(
d
*
decodeState
)
objectInterface
()
map
[
string
]
interface
{}
{
m
:=
make
(
map
[
string
]
interface
{})
for
{
// Read opening " of string key or closing }.
op
:=
d
.
scanWhile
(
scanSkipSpace
)
if
op
==
scanEndObject
{
// closing } - can only happen on first iteration.
break
}
if
op
!=
scanBeginLiteral
{
d
.
error
(
errPhase
)
}
// Read string key.
start
:=
d
.
off
-
1
op
=
d
.
scanWhile
(
scanContinue
)
item
:=
d
.
data
[
start
:
d
.
off
-
1
]
key
,
ok
:=
unquote
(
item
)
if
!
ok
{
d
.
error
(
errPhase
)
}
// Read : before value.
if
op
==
scanSkipSpace
{
op
=
d
.
scanWhile
(
scanSkipSpace
)
}
if
op
!=
scanObjectKey
{
d
.
error
(
errPhase
)
}
// Read value.
m
[
key
]
=
d
.
valueInterface
()
// Next token must be , or }.
op
=
d
.
scanWhile
(
scanSkipSpace
)
if
op
==
scanEndObject
{
break
}
if
op
!=
scanObjectValue
{
d
.
error
(
errPhase
)
}
}
return
m
}
// literalInterface is like literal but returns an interface value.
func
(
d
*
decodeState
)
literalInterface
()
interface
{}
{
// All bytes inside literal return scanContinue op code.
start
:=
d
.
off
-
1
op
:=
d
.
scanWhile
(
scanContinue
)
// Scan read one byte too far; back up.
d
.
off
--
d
.
scan
.
undo
(
op
)
item
:=
d
.
data
[
start
:
d
.
off
]
switch
c
:=
item
[
0
];
c
{
case
'n'
:
// null
return
nil
case
't'
,
'f'
:
// true, false
return
c
==
't'
case
'"'
:
// string
s
,
ok
:=
unquote
(
item
)
if
!
ok
{
d
.
error
(
errPhase
)
}
return
s
default
:
// number
if
c
!=
'-'
&&
(
c
<
'0'
||
c
>
'9'
)
{
d
.
error
(
errPhase
)
}
n
,
err
:=
d
.
convertNumber
(
string
(
item
))
if
err
!=
nil
{
d
.
saveError
(
err
)
}
return
n
}
}
// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
// or it returns -1.
func
getu4
(
s
[]
byte
)
rune
{
if
len
(
s
)
<
6
||
s
[
0
]
!=
'\\'
||
s
[
1
]
!=
'u'
{
return
-
1
}
r
,
err
:=
strconv
.
ParseUint
(
string
(
s
[
2
:
6
]),
16
,
64
)
if
err
!=
nil
{
return
-
1
}
return
rune
(
r
)
}
// unquote converts a quoted JSON string literal s into an actual string t.
// The rules are different than for Go, so cannot use strconv.Unquote.
func
unquote
(
s
[]
byte
)
(
t
string
,
ok
bool
)
{
s
,
ok
=
unquoteBytes
(
s
)
t
=
string
(
s
)
return
}
func
unquoteBytes
(
s
[]
byte
)
(
t
[]
byte
,
ok
bool
)
{
if
len
(
s
)
<
2
||
s
[
0
]
!=
'"'
||
s
[
len
(
s
)
-
1
]
!=
'"'
{
return
}
s
=
s
[
1
:
len
(
s
)
-
1
]
// Check for unusual characters. If there are none,
// then no unquoting is needed, so return a slice of the
// original bytes.
r
:=
0
for
r
<
len
(
s
)
{
c
:=
s
[
r
]
if
c
==
'\\'
||
c
==
'"'
||
c
<
' '
{
break
}
if
c
<
utf8
.
RuneSelf
{
r
++
continue
}
rr
,
size
:=
utf8
.
DecodeRune
(
s
[
r
:
])
if
rr
==
utf8
.
RuneError
&&
size
==
1
{
break
}
r
+=
size
}
if
r
==
len
(
s
)
{
return
s
,
true
}
b
:=
make
([]
byte
,
len
(
s
)
+
2
*
utf8
.
UTFMax
)
w
:=
copy
(
b
,
s
[
0
:
r
])
for
r
<
len
(
s
)
{
// Out of room? Can only happen if s is full of
// malformed UTF-8 and we're replacing each
// byte with RuneError.
if
w
>=
len
(
b
)
-
2
*
utf8
.
UTFMax
{
nb
:=
make
([]
byte
,
(
len
(
b
)
+
utf8
.
UTFMax
)
*
2
)
copy
(
nb
,
b
[
0
:
w
])
b
=
nb
}
switch
c
:=
s
[
r
];
{
case
c
==
'\\'
:
r
++
if
r
>=
len
(
s
)
{
return
}
switch
s
[
r
]
{
default
:
return
case
'"'
,
'\\'
,
'/'
,
'\'
'
:
b
[
w
]
=
s
[
r
]
r
++
w
++
case
'b'
:
b
[
w
]
=
'\b'
r
++
w
++
case
'f'
:
b
[
w
]
=
'\f'
r
++
w
++
case
'n'
:
b
[
w
]
=
'\n'
r
++
w
++
case
'r'
:
b
[
w
]
=
'\r'
r
++
w
++
case
't'
:
b
[
w
]
=
'\t'
r
++
w
++
case
'u'
:
r
--
rr
:=
getu4
(
s
[
r
:
])
if
rr
<
0
{
return
}
r
+=
6
if
utf16
.
IsSurrogate
(
rr
)
{
rr1
:=
getu4
(
s
[
r
:
])
if
dec
:=
utf16
.
DecodeRune
(
rr
,
rr1
);
dec
!=
unicode
.
ReplacementChar
{
// A valid pair; consume.
r
+=
6
w
+=
utf8
.
EncodeRune
(
b
[
w
:
],
dec
)
break
}
// Invalid surrogate; fall back to replacement rune.
rr
=
unicode
.
ReplacementChar
}
w
+=
utf8
.
EncodeRune
(
b
[
w
:
],
rr
)
}
// Quote, control characters are invalid.
case
c
==
'"'
,
c
<
' '
:
return
// ASCII
case
c
<
utf8
.
RuneSelf
:
b
[
w
]
=
c
r
++
w
++
// Coerce to well-formed UTF-8.
default
:
rr
,
size
:=
utf8
.
DecodeRune
(
s
[
r
:
])
r
+=
size
w
+=
utf8
.
EncodeRune
(
b
[
w
:
],
rr
)
}
}
return
b
[
0
:
w
],
true
}
vendor/github.com/CorgiMan/json2/encode.go
0 → 100644
浏览文件 @
ee667a09
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package json implements encoding and decoding of JSON objects as defined in
// RFC 4627. The mapping between JSON objects and Go values is described
// in the documentation for the Marshal and Unmarshal functions.
//
// See "JSON and Go" for an introduction to this package:
// http://golang.org/doc/articles/json_and_go.html
package
json2
import
(
"bytes"
"encoding"
"encoding/base64"
"math"
"reflect"
"runtime"
"sort"
"strconv"
"strings"
"sync"
"unicode"
"unicode/utf8"
)
// Marshal returns the JSON encoding of v.
//
// Marshal traverses the value v recursively.
// If an encountered value implements the Marshaler interface
// and is not a nil pointer, Marshal calls its MarshalJSON method
// to produce JSON. The nil pointer exception is not strictly necessary
// but mimics a similar, necessary exception in the behavior of
// UnmarshalJSON.
//
// Otherwise, Marshal uses the following type-dependent default encodings:
//
// Boolean values encode as JSON booleans.
//
// Floating point, integer, and Number values encode as JSON numbers.
//
// String values encode as JSON strings. InvalidUTF8Error will be returned
// if an invalid UTF-8 sequence is encountered.
// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e"
// to keep some browsers from misinterpreting JSON output as HTML.
//
// Array and slice values encode as JSON arrays, except that
// []byte encodes as a base64-encoded string, and a nil slice
// encodes as the null JSON object.
//
// Struct values encode as JSON objects. Each exported struct field
// becomes a member of the object unless
// - the field's tag is "-", or
// - the field is empty and its tag specifies the "omitempty" option.
// The empty values are false, 0, any
// nil pointer or interface value, and any array, slice, map, or string of
// length zero. The object's default key string is the struct field name
// but can be specified in the struct field's tag value. The "json" key in
// the struct field's tag value is the key name, followed by an optional comma
// and options. Examples:
//
// // Field is ignored by this package.
// Field int `json:"-"`
//
// // Field appears in JSON as key "myName".
// Field int `json:"myName"`
//
// // Field appears in JSON as key "myName" and
// // the field is omitted from the object if its value is empty,
// // as defined above.
// Field int `json:"myName,omitempty"`
//
// // Field appears in JSON as key "Field" (the default), but
// // the field is skipped if empty.
// // Note the leading comma.
// Field int `json:",omitempty"`
//
// The "string" option signals that a field is stored as JSON inside a
// JSON-encoded string. It applies only to fields of string, floating point,
// or integer types. This extra level of encoding is sometimes used when
// communicating with JavaScript programs:
//
// Int64String int64 `json:",string"`
//
// The key name will be used if it's a non-empty string consisting of
// only Unicode letters, digits, dollar signs, percent signs, hyphens,
// underscores and slashes.
//
// Anonymous struct fields are usually marshaled as if their inner exported fields
// were fields in the outer struct, subject to the usual Go visibility rules amended
// as described in the next paragraph.
// An anonymous struct field with a name given in its JSON tag is treated as
// having that name, rather than being anonymous.
//
// The Go visibility rules for struct fields are amended for JSON when
// deciding which field to marshal or unmarshal. If there are
// multiple fields at the same level, and that level is the least
// nested (and would therefore be the nesting level selected by the
// usual Go rules), the following extra rules apply:
//
// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered,
// even if there are multiple untagged fields that would otherwise conflict.
// 2) If there is exactly one field (tagged or not according to the first rule), that is selected.
// 3) Otherwise there are multiple fields, and all are ignored; no error occurs.
//
// Handling of anonymous struct fields is new in Go 1.1.
// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of
// an anonymous struct field in both current and earlier versions, give the field
// a JSON tag of "-".
//
// Map values encode as JSON objects.
// The map's key type must be string; the object keys are used directly
// as map keys.
//
// Pointer values encode as the value pointed to.
// A nil pointer encodes as the null JSON object.
//
// Interface values encode as the value contained in the interface.
// A nil interface value encodes as the null JSON object.
//
// Channel, complex, and function values cannot be encoded in JSON.
// Attempting to encode such a value causes Marshal to return
// an UnsupportedTypeError.
//
// JSON cannot represent cyclic data structures and Marshal does not
// handle them. Passing cyclic structures to Marshal will result in
// an infinite recursion.
//
func
Marshal
(
v
interface
{})
([]
byte
,
error
)
{
e
:=
&
encodeState
{}
err
:=
e
.
marshal
(
v
)
if
err
!=
nil
{
return
nil
,
err
}
return
e
.
Bytes
(),
nil
}
// MarshalIndent is like Marshal but applies Indent to format the output.
func
MarshalIndent
(
v
interface
{},
prefix
,
indent
string
)
([]
byte
,
error
)
{
b
,
err
:=
Marshal
(
v
)
if
err
!=
nil
{
return
nil
,
err
}
var
buf
bytes
.
Buffer
err
=
Indent
(
&
buf
,
b
,
prefix
,
indent
)
if
err
!=
nil
{
return
nil
,
err
}
return
buf
.
Bytes
(),
nil
}
// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
// so that the JSON will be safe to embed inside HTML <script> tags.
// For historical reasons, web browsers don't honor standard HTML
// escaping within <script> tags, so an alternative JSON encoding must
// be used.
func
HTMLEscape
(
dst
*
bytes
.
Buffer
,
src
[]
byte
)
{
// The characters can only appear in string literals,
// so just scan the string one byte at a time.
start
:=
0
for
i
,
c
:=
range
src
{
if
c
==
'<'
||
c
==
'>'
||
c
==
'&'
{
if
start
<
i
{
dst
.
Write
(
src
[
start
:
i
])
}
dst
.
WriteString
(
`\u00`
)
dst
.
WriteByte
(
hex
[
c
>>
4
])
dst
.
WriteByte
(
hex
[
c
&
0xF
])
start
=
i
+
1
}
// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
if
c
==
0xE2
&&
i
+
2
<
len
(
src
)
&&
src
[
i
+
1
]
==
0x80
&&
src
[
i
+
2
]
&^
1
==
0xA8
{
if
start
<
i
{
dst
.
Write
(
src
[
start
:
i
])
}
dst
.
WriteString
(
`\u202`
)
dst
.
WriteByte
(
hex
[
src
[
i
+
2
]
&
0xF
])
start
=
i
+
3
}
}
if
start
<
len
(
src
)
{
dst
.
Write
(
src
[
start
:
])
}
}
// Marshaler is the interface implemented by objects that
// can marshal themselves into valid JSON.
type
Marshaler
interface
{
MarshalJSON
()
([]
byte
,
error
)
}
// An UnsupportedTypeError is returned by Marshal when attempting
// to encode an unsupported value type.
type
UnsupportedTypeError
struct
{
Type
reflect
.
Type
}
func
(
e
*
UnsupportedTypeError
)
Error
()
string
{
return
"json: unsupported type: "
+
e
.
Type
.
String
()
}
type
UnsupportedValueError
struct
{
Value
reflect
.
Value
Str
string
}
func
(
e
*
UnsupportedValueError
)
Error
()
string
{
return
"json: unsupported value: "
+
e
.
Str
}
// Before Go 1.2, an InvalidUTF8Error was returned by Marshal when
// attempting to encode a string value with invalid UTF-8 sequences.
// As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by
// replacing invalid bytes with the Unicode replacement rune U+FFFD.
// This error is no longer generated but is kept for backwards compatibility
// with programs that might mention it.
type
InvalidUTF8Error
struct
{
S
string
// the whole string value that caused the error
}
func
(
e
*
InvalidUTF8Error
)
Error
()
string
{
return
"json: invalid UTF-8 in string: "
+
strconv
.
Quote
(
e
.
S
)
}
type
MarshalerError
struct
{
Type
reflect
.
Type
Err
error
}
func
(
e
*
MarshalerError
)
Error
()
string
{
return
"json: error calling MarshalJSON for type "
+
e
.
Type
.
String
()
+
": "
+
e
.
Err
.
Error
()
}
var
hex
=
"0123456789abcdef"
// An encodeState encodes JSON into a bytes.Buffer.
type
encodeState
struct
{
bytes
.
Buffer
// accumulated output
scratch
[
64
]
byte
}
// TODO(bradfitz): use a sync.Cache here
var
encodeStatePool
=
make
(
chan
*
encodeState
,
8
)
func
newEncodeState
()
*
encodeState
{
select
{
case
e
:=
<-
encodeStatePool
:
e
.
Reset
()
return
e
default
:
return
new
(
encodeState
)
}
}
func
putEncodeState
(
e
*
encodeState
)
{
select
{
case
encodeStatePool
<-
e
:
default
:
}
}
func
(
e
*
encodeState
)
marshal
(
v
interface
{})
(
err
error
)
{
defer
func
()
{
if
r
:=
recover
();
r
!=
nil
{
if
_
,
ok
:=
r
.
(
runtime
.
Error
);
ok
{
panic
(
r
)
}
if
s
,
ok
:=
r
.
(
string
);
ok
{
panic
(
s
)
}
err
=
r
.
(
error
)
}
}()
e
.
reflectValue
(
reflect
.
ValueOf
(
v
))
return
nil
}
func
(
e
*
encodeState
)
error
(
err
error
)
{
panic
(
err
)
}
var
byteSliceType
=
reflect
.
TypeOf
([]
byte
(
nil
))
func
isEmptyValue
(
v
reflect
.
Value
)
bool
{
switch
v
.
Kind
()
{
case
reflect
.
Array
,
reflect
.
Map
,
reflect
.
Slice
,
reflect
.
String
:
return
v
.
Len
()
==
0
case
reflect
.
Bool
:
return
!
v
.
Bool
()
case
reflect
.
Int
,
reflect
.
Int8
,
reflect
.
Int16
,
reflect
.
Int32
,
reflect
.
Int64
:
return
v
.
Int
()
==
0
case
reflect
.
Uint
,
reflect
.
Uint8
,
reflect
.
Uint16
,
reflect
.
Uint32
,
reflect
.
Uint64
,
reflect
.
Uintptr
:
return
v
.
Uint
()
==
0
case
reflect
.
Float32
,
reflect
.
Float64
:
return
v
.
Float
()
==
0
case
reflect
.
Interface
,
reflect
.
Ptr
:
return
v
.
IsNil
()
}
return
false
}
func
(
e
*
encodeState
)
reflectValue
(
v
reflect
.
Value
)
{
valueEncoder
(
v
)(
e
,
v
,
false
)
}
type
encoderFunc
func
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
var
encoderCache
struct
{
sync
.
RWMutex
m
map
[
reflect
.
Type
]
encoderFunc
}
func
valueEncoder
(
v
reflect
.
Value
)
encoderFunc
{
if
!
v
.
IsValid
()
{
return
invalidValueEncoder
}
return
typeEncoder
(
v
.
Type
())
}
func
typeEncoder
(
t
reflect
.
Type
)
encoderFunc
{
encoderCache
.
RLock
()
f
:=
encoderCache
.
m
[
t
]
encoderCache
.
RUnlock
()
if
f
!=
nil
{
return
f
}
// To deal with recursive types, populate the map with an
// indirect func before we build it. This type waits on the
// real func (f) to be ready and then calls it. This indirect
// func is only used for recursive types.
encoderCache
.
Lock
()
if
encoderCache
.
m
==
nil
{
encoderCache
.
m
=
make
(
map
[
reflect
.
Type
]
encoderFunc
)
}
var
wg
sync
.
WaitGroup
wg
.
Add
(
1
)
encoderCache
.
m
[
t
]
=
func
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
wg
.
Wait
()
f
(
e
,
v
,
quoted
)
}
encoderCache
.
Unlock
()
// Compute fields without lock.
// Might duplicate effort but won't hold other computations back.
f
=
newTypeEncoder
(
t
,
true
)
wg
.
Done
()
encoderCache
.
Lock
()
encoderCache
.
m
[
t
]
=
f
encoderCache
.
Unlock
()
return
f
}
var
(
marshalerType
=
reflect
.
TypeOf
(
new
(
Marshaler
))
.
Elem
()
textMarshalerType
=
reflect
.
TypeOf
(
new
(
encoding
.
TextMarshaler
))
.
Elem
()
)
// newTypeEncoder constructs an encoderFunc for a type.
// The returned encoder only checks CanAddr when allowAddr is true.
func
newTypeEncoder
(
t
reflect
.
Type
,
allowAddr
bool
)
encoderFunc
{
if
t
.
Implements
(
marshalerType
)
{
return
marshalerEncoder
}
if
t
.
Kind
()
!=
reflect
.
Ptr
&&
allowAddr
{
if
reflect
.
PtrTo
(
t
)
.
Implements
(
marshalerType
)
{
return
newCondAddrEncoder
(
addrMarshalerEncoder
,
newTypeEncoder
(
t
,
false
))
}
}
if
t
.
Implements
(
textMarshalerType
)
{
return
textMarshalerEncoder
}
if
t
.
Kind
()
!=
reflect
.
Ptr
&&
allowAddr
{
if
reflect
.
PtrTo
(
t
)
.
Implements
(
textMarshalerType
)
{
return
newCondAddrEncoder
(
addrTextMarshalerEncoder
,
newTypeEncoder
(
t
,
false
))
}
}
switch
t
.
Kind
()
{
case
reflect
.
Bool
:
return
boolEncoder
case
reflect
.
Int
,
reflect
.
Int8
,
reflect
.
Int16
,
reflect
.
Int32
,
reflect
.
Int64
:
return
intEncoder
case
reflect
.
Uint
,
reflect
.
Uint8
,
reflect
.
Uint16
,
reflect
.
Uint32
,
reflect
.
Uint64
,
reflect
.
Uintptr
:
return
uintEncoder
case
reflect
.
Float32
:
return
float32Encoder
case
reflect
.
Float64
:
return
float64Encoder
case
reflect
.
String
:
return
stringEncoder
case
reflect
.
Interface
:
return
interfaceEncoder
case
reflect
.
Struct
:
return
newStructEncoder
(
t
)
case
reflect
.
Map
:
return
newMapEncoder
(
t
)
case
reflect
.
Slice
:
return
newSliceEncoder
(
t
)
case
reflect
.
Array
:
return
newArrayEncoder
(
t
)
case
reflect
.
Ptr
:
return
newPtrEncoder
(
t
)
default
:
return
unsupportedTypeEncoder
}
}
func
invalidValueEncoder
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
e
.
WriteString
(
"null"
)
}
func
marshalerEncoder
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
if
v
.
Kind
()
==
reflect
.
Ptr
&&
v
.
IsNil
()
{
e
.
WriteString
(
"null"
)
return
}
m
:=
v
.
Interface
()
.
(
Marshaler
)
b
,
err
:=
m
.
MarshalJSON
()
if
err
==
nil
{
// copy JSON into buffer, checking validity.
err
=
compact
(
&
e
.
Buffer
,
b
,
true
)
}
if
err
!=
nil
{
e
.
error
(
&
MarshalerError
{
v
.
Type
(),
err
})
}
}
func
addrMarshalerEncoder
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
va
:=
v
.
Addr
()
if
va
.
IsNil
()
{
e
.
WriteString
(
"null"
)
return
}
m
:=
va
.
Interface
()
.
(
Marshaler
)
b
,
err
:=
m
.
MarshalJSON
()
if
err
==
nil
{
// copy JSON into buffer, checking validity.
err
=
compact
(
&
e
.
Buffer
,
b
,
true
)
}
if
err
!=
nil
{
e
.
error
(
&
MarshalerError
{
v
.
Type
(),
err
})
}
}
func
textMarshalerEncoder
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
if
v
.
Kind
()
==
reflect
.
Ptr
&&
v
.
IsNil
()
{
e
.
WriteString
(
"null"
)
return
}
m
:=
v
.
Interface
()
.
(
encoding
.
TextMarshaler
)
b
,
err
:=
m
.
MarshalText
()
if
err
==
nil
{
_
,
err
=
e
.
stringBytes
(
b
)
}
if
err
!=
nil
{
e
.
error
(
&
MarshalerError
{
v
.
Type
(),
err
})
}
}
func
addrTextMarshalerEncoder
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
va
:=
v
.
Addr
()
if
va
.
IsNil
()
{
e
.
WriteString
(
"null"
)
return
}
m
:=
va
.
Interface
()
.
(
encoding
.
TextMarshaler
)
b
,
err
:=
m
.
MarshalText
()
if
err
==
nil
{
_
,
err
=
e
.
stringBytes
(
b
)
}
if
err
!=
nil
{
e
.
error
(
&
MarshalerError
{
v
.
Type
(),
err
})
}
}
func
boolEncoder
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
if
quoted
{
e
.
WriteByte
(
'"'
)
}
if
v
.
Bool
()
{
e
.
WriteString
(
"true"
)
}
else
{
e
.
WriteString
(
"false"
)
}
if
quoted
{
e
.
WriteByte
(
'"'
)
}
}
func
intEncoder
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
b
:=
strconv
.
AppendInt
(
e
.
scratch
[
:
0
],
v
.
Int
(),
10
)
if
quoted
{
e
.
WriteByte
(
'"'
)
}
e
.
Write
(
b
)
if
quoted
{
e
.
WriteByte
(
'"'
)
}
}
func
uintEncoder
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
b
:=
strconv
.
AppendUint
(
e
.
scratch
[
:
0
],
v
.
Uint
(),
10
)
if
quoted
{
e
.
WriteByte
(
'"'
)
}
e
.
Write
(
b
)
if
quoted
{
e
.
WriteByte
(
'"'
)
}
}
type
floatEncoder
int
// number of bits
func
(
bits
floatEncoder
)
encode
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
f
:=
v
.
Float
()
if
math
.
IsInf
(
f
,
0
)
||
math
.
IsNaN
(
f
)
{
e
.
error
(
&
UnsupportedValueError
{
v
,
strconv
.
FormatFloat
(
f
,
'g'
,
-
1
,
int
(
bits
))})
}
b
:=
strconv
.
AppendFloat
(
e
.
scratch
[
:
0
],
f
,
'g'
,
-
1
,
int
(
bits
))
if
quoted
{
e
.
WriteByte
(
'"'
)
}
e
.
Write
(
b
)
if
quoted
{
e
.
WriteByte
(
'"'
)
}
}
var
(
float32Encoder
=
(
floatEncoder
(
32
))
.
encode
float64Encoder
=
(
floatEncoder
(
64
))
.
encode
)
func
stringEncoder
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
if
v
.
Type
()
==
numberType
{
numStr
:=
v
.
String
()
if
numStr
==
""
{
numStr
=
"0"
// Number's zero-val
}
e
.
WriteString
(
numStr
)
return
}
if
quoted
{
sb
,
err
:=
Marshal
(
v
.
String
())
if
err
!=
nil
{
e
.
error
(
err
)
}
e
.
string
(
string
(
sb
))
}
else
{
e
.
string
(
v
.
String
())
}
}
func
interfaceEncoder
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
if
v
.
IsNil
()
{
e
.
WriteString
(
"null"
)
return
}
e
.
reflectValue
(
v
.
Elem
())
}
func
unsupportedTypeEncoder
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
e
.
error
(
&
UnsupportedTypeError
{
v
.
Type
()})
}
type
structEncoder
struct
{
fields
[]
field
fieldEncs
[]
encoderFunc
}
func
(
se
*
structEncoder
)
encode
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
e
.
WriteByte
(
'{'
)
first
:=
true
for
i
,
f
:=
range
se
.
fields
{
fv
:=
fieldByIndex
(
v
,
f
.
index
)
if
!
fv
.
IsValid
()
||
f
.
omitEmpty
&&
isEmptyValue
(
fv
)
{
continue
}
if
first
{
first
=
false
}
else
{
e
.
WriteByte
(
','
)
}
e
.
string
(
f
.
name
)
e
.
WriteByte
(
':'
)
se
.
fieldEncs
[
i
](
e
,
fv
,
f
.
quoted
)
}
e
.
WriteByte
(
'}'
)
}
func
newStructEncoder
(
t
reflect
.
Type
)
encoderFunc
{
fields
:=
cachedTypeFields
(
t
)
se
:=
&
structEncoder
{
fields
:
fields
,
fieldEncs
:
make
([]
encoderFunc
,
len
(
fields
)),
}
for
i
,
f
:=
range
fields
{
se
.
fieldEncs
[
i
]
=
typeEncoder
(
typeByIndex
(
t
,
f
.
index
))
}
return
se
.
encode
}
type
mapEncoder
struct
{
elemEnc
encoderFunc
}
func
(
me
*
mapEncoder
)
encode
(
e
*
encodeState
,
v
reflect
.
Value
,
_
bool
)
{
if
v
.
IsNil
()
{
e
.
WriteString
(
"null"
)
return
}
e
.
WriteByte
(
'{'
)
var
sv
stringValues
=
v
.
MapKeys
()
sort
.
Sort
(
sv
)
for
i
,
k
:=
range
sv
{
if
i
>
0
{
e
.
WriteByte
(
','
)
}
e
.
string
(
k
.
String
())
e
.
WriteByte
(
':'
)
me
.
elemEnc
(
e
,
v
.
MapIndex
(
k
),
false
)
}
e
.
WriteByte
(
'}'
)
}
func
newMapEncoder
(
t
reflect
.
Type
)
encoderFunc
{
if
t
.
Key
()
.
Kind
()
!=
reflect
.
String
{
return
unsupportedTypeEncoder
}
me
:=
&
mapEncoder
{
typeEncoder
(
t
.
Elem
())}
return
me
.
encode
}
func
encodeByteSlice
(
e
*
encodeState
,
v
reflect
.
Value
,
_
bool
)
{
if
v
.
IsNil
()
{
e
.
WriteString
(
"null"
)
return
}
s
:=
v
.
Bytes
()
e
.
WriteByte
(
'"'
)
if
len
(
s
)
<
1024
{
// for small buffers, using Encode directly is much faster.
dst
:=
make
([]
byte
,
base64
.
StdEncoding
.
EncodedLen
(
len
(
s
)))
base64
.
StdEncoding
.
Encode
(
dst
,
s
)
e
.
Write
(
dst
)
}
else
{
// for large buffers, avoid unnecessary extra temporary
// buffer space.
enc
:=
base64
.
NewEncoder
(
base64
.
StdEncoding
,
e
)
enc
.
Write
(
s
)
enc
.
Close
()
}
e
.
WriteByte
(
'"'
)
}
// sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil.
type
sliceEncoder
struct
{
arrayEnc
encoderFunc
}
func
(
se
*
sliceEncoder
)
encode
(
e
*
encodeState
,
v
reflect
.
Value
,
_
bool
)
{
if
v
.
IsNil
()
{
e
.
WriteString
(
"null"
)
return
}
se
.
arrayEnc
(
e
,
v
,
false
)
}
func
newSliceEncoder
(
t
reflect
.
Type
)
encoderFunc
{
// Byte slices get special treatment; arrays don't.
if
t
.
Elem
()
.
Kind
()
==
reflect
.
Uint8
{
return
encodeByteSlice
}
enc
:=
&
sliceEncoder
{
newArrayEncoder
(
t
)}
return
enc
.
encode
}
type
arrayEncoder
struct
{
elemEnc
encoderFunc
}
func
(
ae
*
arrayEncoder
)
encode
(
e
*
encodeState
,
v
reflect
.
Value
,
_
bool
)
{
e
.
WriteByte
(
'['
)
n
:=
v
.
Len
()
for
i
:=
0
;
i
<
n
;
i
++
{
if
i
>
0
{
e
.
WriteByte
(
','
)
}
ae
.
elemEnc
(
e
,
v
.
Index
(
i
),
false
)
}
e
.
WriteByte
(
']'
)
}
func
newArrayEncoder
(
t
reflect
.
Type
)
encoderFunc
{
enc
:=
&
arrayEncoder
{
typeEncoder
(
t
.
Elem
())}
return
enc
.
encode
}
type
ptrEncoder
struct
{
elemEnc
encoderFunc
}
func
(
pe
*
ptrEncoder
)
encode
(
e
*
encodeState
,
v
reflect
.
Value
,
_
bool
)
{
if
v
.
IsNil
()
{
e
.
WriteString
(
"null"
)
return
}
pe
.
elemEnc
(
e
,
v
.
Elem
(),
false
)
}
func
newPtrEncoder
(
t
reflect
.
Type
)
encoderFunc
{
enc
:=
&
ptrEncoder
{
typeEncoder
(
t
.
Elem
())}
return
enc
.
encode
}
type
condAddrEncoder
struct
{
canAddrEnc
,
elseEnc
encoderFunc
}
func
(
ce
*
condAddrEncoder
)
encode
(
e
*
encodeState
,
v
reflect
.
Value
,
quoted
bool
)
{
if
v
.
CanAddr
()
{
ce
.
canAddrEnc
(
e
,
v
,
quoted
)
}
else
{
ce
.
elseEnc
(
e
,
v
,
quoted
)
}
}
// newCondAddrEncoder returns an encoder that checks whether its value
// CanAddr and delegates to canAddrEnc if so, else to elseEnc.
func
newCondAddrEncoder
(
canAddrEnc
,
elseEnc
encoderFunc
)
encoderFunc
{
enc
:=
&
condAddrEncoder
{
canAddrEnc
:
canAddrEnc
,
elseEnc
:
elseEnc
}
return
enc
.
encode
}
func
isValidTag
(
s
string
)
bool
{
if
s
==
""
{
return
false
}
for
_
,
c
:=
range
s
{
switch
{
case
strings
.
ContainsRune
(
"!#$%&()*+-./:<=>?@[]^_{|}~ "
,
c
)
:
// Backslash and quote chars are reserved, but
// otherwise any punctuation chars are allowed
// in a tag name.
default
:
if
!
unicode
.
IsLetter
(
c
)
&&
!
unicode
.
IsDigit
(
c
)
{
return
false
}
}
}
return
true
}
func
fieldByIndex
(
v
reflect
.
Value
,
index
[]
int
)
reflect
.
Value
{
for
_
,
i
:=
range
index
{
if
v
.
Kind
()
==
reflect
.
Ptr
{
if
v
.
IsNil
()
{
return
reflect
.
Value
{}
}
v
=
v
.
Elem
()
}
v
=
v
.
Field
(
i
)
}
return
v
}
func
typeByIndex
(
t
reflect
.
Type
,
index
[]
int
)
reflect
.
Type
{
for
_
,
i
:=
range
index
{
if
t
.
Kind
()
==
reflect
.
Ptr
{
t
=
t
.
Elem
()
}
t
=
t
.
Field
(
i
)
.
Type
}
return
t
}
// stringValues is a slice of reflect.Value holding *reflect.StringValue.
// It implements the methods to sort by string.
type
stringValues
[]
reflect
.
Value
func
(
sv
stringValues
)
Len
()
int
{
return
len
(
sv
)
}
func
(
sv
stringValues
)
Swap
(
i
,
j
int
)
{
sv
[
i
],
sv
[
j
]
=
sv
[
j
],
sv
[
i
]
}
func
(
sv
stringValues
)
Less
(
i
,
j
int
)
bool
{
return
sv
.
get
(
i
)
<
sv
.
get
(
j
)
}
func
(
sv
stringValues
)
get
(
i
int
)
string
{
return
sv
[
i
]
.
String
()
}
// NOTE: keep in sync with stringBytes below.
func
(
e
*
encodeState
)
string
(
s
string
)
(
int
,
error
)
{
len0
:=
e
.
Len
()
e
.
WriteByte
(
'"'
)
start
:=
0
for
i
:=
0
;
i
<
len
(
s
);
{
if
b
:=
s
[
i
];
b
<
utf8
.
RuneSelf
{
if
0x20
<=
b
&&
b
!=
'\\'
&&
b
!=
'"'
&&
b
!=
'<'
&&
b
!=
'>'
&&
b
!=
'&'
{
i
++
continue
}
if
start
<
i
{
e
.
WriteString
(
s
[
start
:
i
])
}
switch
b
{
case
'\\'
,
'"'
:
e
.
WriteByte
(
'\\'
)
e
.
WriteByte
(
b
)
case
'\n'
:
e
.
WriteByte
(
'\\'
)
e
.
WriteByte
(
'n'
)
case
'\r'
:
e
.
WriteByte
(
'\\'
)
e
.
WriteByte
(
'r'
)
default
:
// This encodes bytes < 0x20 except for \n and \r,
// as well as < and >. The latter are escaped because they
// can lead to security holes when user-controlled strings
// are rendered into JSON and served to some browsers.
e
.
WriteString
(
`\u00`
)
e
.
WriteByte
(
hex
[
b
>>
4
])
e
.
WriteByte
(
hex
[
b
&
0xF
])
}
i
++
start
=
i
continue
}
c
,
size
:=
utf8
.
DecodeRuneInString
(
s
[
i
:
])
if
c
==
utf8
.
RuneError
&&
size
==
1
{
if
start
<
i
{
e
.
WriteString
(
s
[
start
:
i
])
}
e
.
WriteString
(
`\ufffd`
)
i
+=
size
start
=
i
continue
}
// U+2028 is LINE SEPARATOR.
// U+2029 is PARAGRAPH SEPARATOR.
// They are both technically valid characters in JSON strings,
// but don't work in JSONP, which has to be evaluated as JavaScript,
// and can lead to security holes there. It is valid JSON to
// escape them, so we do so unconditionally.
// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
if
c
==
'\u2028'
||
c
==
'\u2029'
{
if
start
<
i
{
e
.
WriteString
(
s
[
start
:
i
])
}
e
.
WriteString
(
`\u202`
)
e
.
WriteByte
(
hex
[
c
&
0xF
])
i
+=
size
start
=
i
continue
}
i
+=
size
}
if
start
<
len
(
s
)
{
e
.
WriteString
(
s
[
start
:
])
}
e
.
WriteByte
(
'"'
)
return
e
.
Len
()
-
len0
,
nil
}
// NOTE: keep in sync with string above.
func
(
e
*
encodeState
)
stringBytes
(
s
[]
byte
)
(
int
,
error
)
{
len0
:=
e
.
Len
()
e
.
WriteByte
(
'"'
)
start
:=
0
for
i
:=
0
;
i
<
len
(
s
);
{
if
b
:=
s
[
i
];
b
<
utf8
.
RuneSelf
{
if
0x20
<=
b
&&
b
!=
'\\'
&&
b
!=
'"'
&&
b
!=
'<'
&&
b
!=
'>'
&&
b
!=
'&'
{
i
++
continue
}
if
start
<
i
{
e
.
Write
(
s
[
start
:
i
])
}
switch
b
{
case
'\\'
,
'"'
:
e
.
WriteByte
(
'\\'
)
e
.
WriteByte
(
b
)
case
'\n'
:
e
.
WriteByte
(
'\\'
)
e
.
WriteByte
(
'n'
)
case
'\r'
:
e
.
WriteByte
(
'\\'
)
e
.
WriteByte
(
'r'
)
default
:
// This encodes bytes < 0x20 except for \n and \r,
// as well as < and >. The latter are escaped because they
// can lead to security holes when user-controlled strings
// are rendered into JSON and served to some browsers.
e
.
WriteString
(
`\u00`
)
e
.
WriteByte
(
hex
[
b
>>
4
])
e
.
WriteByte
(
hex
[
b
&
0xF
])
}
i
++
start
=
i
continue
}
c
,
size
:=
utf8
.
DecodeRune
(
s
[
i
:
])
if
c
==
utf8
.
RuneError
&&
size
==
1
{
if
start
<
i
{
e
.
Write
(
s
[
start
:
i
])
}
e
.
WriteString
(
`\ufffd`
)
i
+=
size
start
=
i
continue
}
// U+2028 is LINE SEPARATOR.
// U+2029 is PARAGRAPH SEPARATOR.
// They are both technically valid characters in JSON strings,
// but don't work in JSONP, which has to be evaluated as JavaScript,
// and can lead to security holes there. It is valid JSON to
// escape them, so we do so unconditionally.
// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
if
c
==
'\u2028'
||
c
==
'\u2029'
{
if
start
<
i
{
e
.
Write
(
s
[
start
:
i
])
}
e
.
WriteString
(
`\u202`
)
e
.
WriteByte
(
hex
[
c
&
0xF
])
i
+=
size
start
=
i
continue
}
i
+=
size
}
if
start
<
len
(
s
)
{
e
.
Write
(
s
[
start
:
])
}
e
.
WriteByte
(
'"'
)
return
e
.
Len
()
-
len0
,
nil
}
// A field represents a single field found in a struct.
type
field
struct
{
name
string
tag
bool
index
[]
int
typ
reflect
.
Type
omitEmpty
bool
quoted
bool
}
// byName sorts field by name, breaking ties with depth,
// then breaking ties with "name came from json tag", then
// breaking ties with index sequence.
type
byName
[]
field
func
(
x
byName
)
Len
()
int
{
return
len
(
x
)
}
func
(
x
byName
)
Swap
(
i
,
j
int
)
{
x
[
i
],
x
[
j
]
=
x
[
j
],
x
[
i
]
}
func
(
x
byName
)
Less
(
i
,
j
int
)
bool
{
if
x
[
i
]
.
name
!=
x
[
j
]
.
name
{
return
x
[
i
]
.
name
<
x
[
j
]
.
name
}
if
len
(
x
[
i
]
.
index
)
!=
len
(
x
[
j
]
.
index
)
{
return
len
(
x
[
i
]
.
index
)
<
len
(
x
[
j
]
.
index
)
}
if
x
[
i
]
.
tag
!=
x
[
j
]
.
tag
{
return
x
[
i
]
.
tag
}
return
byIndex
(
x
)
.
Less
(
i
,
j
)
}
// byIndex sorts field by index sequence.
type
byIndex
[]
field
func
(
x
byIndex
)
Len
()
int
{
return
len
(
x
)
}
func
(
x
byIndex
)
Swap
(
i
,
j
int
)
{
x
[
i
],
x
[
j
]
=
x
[
j
],
x
[
i
]
}
func
(
x
byIndex
)
Less
(
i
,
j
int
)
bool
{
for
k
,
xik
:=
range
x
[
i
]
.
index
{
if
k
>=
len
(
x
[
j
]
.
index
)
{
return
false
}
if
xik
!=
x
[
j
]
.
index
[
k
]
{
return
xik
<
x
[
j
]
.
index
[
k
]
}
}
return
len
(
x
[
i
]
.
index
)
<
len
(
x
[
j
]
.
index
)
}
// typeFields returns a list of fields that JSON should recognize for the given type.
// The algorithm is breadth-first search over the set of structs to include - the top struct
// and then any reachable anonymous structs.
func
typeFields
(
t
reflect
.
Type
)
[]
field
{
// Anonymous fields to explore at the current level and the next.
current
:=
[]
field
{}
next
:=
[]
field
{{
typ
:
t
}}
// Count of queued names for current level and the next.
count
:=
map
[
reflect
.
Type
]
int
{}
nextCount
:=
map
[
reflect
.
Type
]
int
{}
// Types already visited at an earlier level.
visited
:=
map
[
reflect
.
Type
]
bool
{}
// Fields found.
var
fields
[]
field
for
len
(
next
)
>
0
{
current
,
next
=
next
,
current
[
:
0
]
count
,
nextCount
=
nextCount
,
map
[
reflect
.
Type
]
int
{}
for
_
,
f
:=
range
current
{
if
visited
[
f
.
typ
]
{
continue
}
visited
[
f
.
typ
]
=
true
// Scan f.typ for fields to include.
for
i
:=
0
;
i
<
f
.
typ
.
NumField
();
i
++
{
sf
:=
f
.
typ
.
Field
(
i
)
// if sf.PkgPath != "" { // unexported
// continue
// }
tag
:=
sf
.
Tag
.
Get
(
"json"
)
if
tag
==
"-"
{
continue
}
name
,
opts
:=
parseTag
(
tag
)
if
!
isValidTag
(
name
)
{
name
=
""
}
index
:=
make
([]
int
,
len
(
f
.
index
)
+
1
)
copy
(
index
,
f
.
index
)
index
[
len
(
f
.
index
)]
=
i
ft
:=
sf
.
Type
if
ft
.
Name
()
==
""
&&
ft
.
Kind
()
==
reflect
.
Ptr
{
// Follow pointer.
ft
=
ft
.
Elem
()
}
// Record found field and index sequence.
if
name
!=
""
||
!
sf
.
Anonymous
||
ft
.
Kind
()
!=
reflect
.
Struct
{
tagged
:=
name
!=
""
if
name
==
""
{
name
=
sf
.
Name
}
fields
=
append
(
fields
,
field
{
name
,
tagged
,
index
,
ft
,
opts
.
Contains
(
"omitempty"
),
opts
.
Contains
(
"string"
)})
if
count
[
f
.
typ
]
>
1
{
// If there were multiple instances, add a second,
// so that the annihilation code will see a duplicate.
// It only cares about the distinction between 1 or 2,
// so don't bother generating any more copies.
fields
=
append
(
fields
,
fields
[
len
(
fields
)
-
1
])
}
continue
}
// Record new anonymous struct to explore in next round.
nextCount
[
ft
]
++
if
nextCount
[
ft
]
==
1
{
next
=
append
(
next
,
field
{
name
:
ft
.
Name
(),
index
:
index
,
typ
:
ft
})
}
}
}
}
sort
.
Sort
(
byName
(
fields
))
// Delete all fields that are hidden by the Go rules for embedded fields,
// except that fields with JSON tags are promoted.
// The fields are sorted in primary order of name, secondary order
// of field index length. Loop over names; for each name, delete
// hidden fields by choosing the one dominant field that survives.
out
:=
fields
[
:
0
]
for
advance
,
i
:=
0
,
0
;
i
<
len
(
fields
);
i
+=
advance
{
// One iteration per name.
// Find the sequence of fields with the name of this first field.
fi
:=
fields
[
i
]
name
:=
fi
.
name
for
advance
=
1
;
i
+
advance
<
len
(
fields
);
advance
++
{
fj
:=
fields
[
i
+
advance
]
if
fj
.
name
!=
name
{
break
}
}
if
advance
==
1
{
// Only one field with this name
out
=
append
(
out
,
fi
)
continue
}
dominant
,
ok
:=
dominantField
(
fields
[
i
:
i
+
advance
])
if
ok
{
out
=
append
(
out
,
dominant
)
}
}
fields
=
out
sort
.
Sort
(
byIndex
(
fields
))
return
fields
}
// dominantField looks through the fields, all of which are known to
// have the same name, to find the single field that dominates the
// others using Go's embedding rules, modified by the presence of
// JSON tags. If there are multiple top-level fields, the boolean
// will be false: This condition is an error in Go and we skip all
// the fields.
func
dominantField
(
fields
[]
field
)
(
field
,
bool
)
{
// The fields are sorted in increasing index-length order. The winner
// must therefore be one with the shortest index length. Drop all
// longer entries, which is easy: just truncate the slice.
length
:=
len
(
fields
[
0
]
.
index
)
tagged
:=
-
1
// Index of first tagged field.
for
i
,
f
:=
range
fields
{
if
len
(
f
.
index
)
>
length
{
fields
=
fields
[
:
i
]
break
}
if
f
.
tag
{
if
tagged
>=
0
{
// Multiple tagged fields at the same level: conflict.
// Return no field.
return
field
{},
false
}
tagged
=
i
}
}
if
tagged
>=
0
{
return
fields
[
tagged
],
true
}
// All remaining fields have the same length. If there's more than one,
// we have a conflict (two fields named "X" at the same level) and we
// return no field.
if
len
(
fields
)
>
1
{
return
field
{},
false
}
return
fields
[
0
],
true
}
var
fieldCache
struct
{
sync
.
RWMutex
m
map
[
reflect
.
Type
][]
field
}
// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
func
cachedTypeFields
(
t
reflect
.
Type
)
[]
field
{
fieldCache
.
RLock
()
f
:=
fieldCache
.
m
[
t
]
fieldCache
.
RUnlock
()
if
f
!=
nil
{
return
f
}
// Compute fields without lock.
// Might duplicate effort but won't hold other computations back.
f
=
typeFields
(
t
)
if
f
==
nil
{
f
=
[]
field
{}
}
fieldCache
.
Lock
()
if
fieldCache
.
m
==
nil
{
fieldCache
.
m
=
map
[
reflect
.
Type
][]
field
{}
}
fieldCache
.
m
[
t
]
=
f
fieldCache
.
Unlock
()
return
f
}
vendor/github.com/CorgiMan/json2/indent.go
0 → 100644
浏览文件 @
ee667a09
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
json2
import
"bytes"
// Compact appends to dst the JSON-encoded src with
// insignificant space characters elided.
func
Compact
(
dst
*
bytes
.
Buffer
,
src
[]
byte
)
error
{
return
compact
(
dst
,
src
,
false
)
}
func
compact
(
dst
*
bytes
.
Buffer
,
src
[]
byte
,
escape
bool
)
error
{
origLen
:=
dst
.
Len
()
var
scan
scanner
scan
.
reset
()
start
:=
0
for
i
,
c
:=
range
src
{
if
escape
&&
(
c
==
'<'
||
c
==
'>'
||
c
==
'&'
)
{
if
start
<
i
{
dst
.
Write
(
src
[
start
:
i
])
}
dst
.
WriteString
(
`\u00`
)
dst
.
WriteByte
(
hex
[
c
>>
4
])
dst
.
WriteByte
(
hex
[
c
&
0xF
])
start
=
i
+
1
}
// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
if
c
==
0xE2
&&
i
+
2
<
len
(
src
)
&&
src
[
i
+
1
]
==
0x80
&&
src
[
i
+
2
]
&^
1
==
0xA8
{
if
start
<
i
{
dst
.
Write
(
src
[
start
:
i
])
}
dst
.
WriteString
(
`\u202`
)
dst
.
WriteByte
(
hex
[
src
[
i
+
2
]
&
0xF
])
start
=
i
+
3
}
v
:=
scan
.
step
(
&
scan
,
int
(
c
))
if
v
>=
scanSkipSpace
{
if
v
==
scanError
{
break
}
if
start
<
i
{
dst
.
Write
(
src
[
start
:
i
])
}
start
=
i
+
1
}
}
if
scan
.
eof
()
==
scanError
{
dst
.
Truncate
(
origLen
)
return
scan
.
err
}
if
start
<
len
(
src
)
{
dst
.
Write
(
src
[
start
:
])
}
return
nil
}
func
newline
(
dst
*
bytes
.
Buffer
,
prefix
,
indent
string
,
depth
int
)
{
dst
.
WriteByte
(
'\n'
)
dst
.
WriteString
(
prefix
)
for
i
:=
0
;
i
<
depth
;
i
++
{
dst
.
WriteString
(
indent
)
}
}
// Indent appends to dst an indented form of the JSON-encoded src.
// Each element in a JSON object or array begins on a new,
// indented line beginning with prefix followed by one or more
// copies of indent according to the indentation nesting.
// The data appended to dst has no trailing newline, to make it easier
// to embed inside other formatted JSON data.
func
Indent
(
dst
*
bytes
.
Buffer
,
src
[]
byte
,
prefix
,
indent
string
)
error
{
origLen
:=
dst
.
Len
()
var
scan
scanner
scan
.
reset
()
needIndent
:=
false
depth
:=
0
for
_
,
c
:=
range
src
{
scan
.
bytes
++
v
:=
scan
.
step
(
&
scan
,
int
(
c
))
if
v
==
scanSkipSpace
{
continue
}
if
v
==
scanError
{
break
}
if
needIndent
&&
v
!=
scanEndObject
&&
v
!=
scanEndArray
{
needIndent
=
false
depth
++
newline
(
dst
,
prefix
,
indent
,
depth
)
}
// Emit semantically uninteresting bytes
// (in particular, punctuation in strings) unmodified.
if
v
==
scanContinue
{
dst
.
WriteByte
(
c
)
continue
}
// Add spacing around real punctuation.
switch
c
{
case
'{'
,
'['
:
// delay indent so that empty object and array are formatted as {} and [].
needIndent
=
true
dst
.
WriteByte
(
c
)
case
','
:
dst
.
WriteByte
(
c
)
newline
(
dst
,
prefix
,
indent
,
depth
)
case
':'
:
dst
.
WriteByte
(
c
)
dst
.
WriteByte
(
' '
)
case
'}'
,
']'
:
if
needIndent
{
// suppress indent in empty object/array
needIndent
=
false
}
else
{
depth
--
newline
(
dst
,
prefix
,
indent
,
depth
)
}
dst
.
WriteByte
(
c
)
default
:
dst
.
WriteByte
(
c
)
}
}
if
scan
.
eof
()
==
scanError
{
dst
.
Truncate
(
origLen
)
return
scan
.
err
}
return
nil
}
vendor/github.com/CorgiMan/json2/scanner.go
0 → 100644
浏览文件 @
ee667a09
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
json2
// JSON value parser state machine.
// Just about at the limit of what is reasonable to write by hand.
// Some parts are a bit tedious, but overall it nicely factors out the
// otherwise common code from the multiple scanning functions
// in this package (Compact, Indent, checkValid, nextValue, etc).
//
// This file starts with two simple examples using the scanner
// before diving into the scanner itself.
import
"strconv"
// checkValid verifies that data is valid JSON-encoded data.
// scan is passed in for use by checkValid to avoid an allocation.
func
checkValid
(
data
[]
byte
,
scan
*
scanner
)
error
{
scan
.
reset
()
for
_
,
c
:=
range
data
{
scan
.
bytes
++
if
scan
.
step
(
scan
,
int
(
c
))
==
scanError
{
return
scan
.
err
}
}
if
scan
.
eof
()
==
scanError
{
return
scan
.
err
}
return
nil
}
// nextValue splits data after the next whole JSON value,
// returning that value and the bytes that follow it as separate slices.
// scan is passed in for use by nextValue to avoid an allocation.
func
nextValue
(
data
[]
byte
,
scan
*
scanner
)
(
value
,
rest
[]
byte
,
err
error
)
{
scan
.
reset
()
for
i
,
c
:=
range
data
{
v
:=
scan
.
step
(
scan
,
int
(
c
))
if
v
>=
scanEnd
{
switch
v
{
case
scanError
:
return
nil
,
nil
,
scan
.
err
case
scanEnd
:
return
data
[
0
:
i
],
data
[
i
:
],
nil
}
}
}
if
scan
.
eof
()
==
scanError
{
return
nil
,
nil
,
scan
.
err
}
return
data
,
nil
,
nil
}
// A SyntaxError is a description of a JSON syntax error.
type
SyntaxError
struct
{
msg
string
// description of error
Offset
int64
// error occurred after reading Offset bytes
}
func
(
e
*
SyntaxError
)
Error
()
string
{
return
e
.
msg
}
// A scanner is a JSON scanning state machine.
// Callers call scan.reset() and then pass bytes in one at a time
// by calling scan.step(&scan, c) for each byte.
// The return value, referred to as an opcode, tells the
// caller about significant parsing events like beginning
// and ending literals, objects, and arrays, so that the
// caller can follow along if it wishes.
// The return value scanEnd indicates that a single top-level
// JSON value has been completed, *before* the byte that
// just got passed in. (The indication must be delayed in order
// to recognize the end of numbers: is 123 a whole value or
// the beginning of 12345e+6?).
type
scanner
struct
{
// The step is a func to be called to execute the next transition.
// Also tried using an integer constant and a single func
// with a switch, but using the func directly was 10% faster
// on a 64-bit Mac Mini, and it's nicer to read.
step
func
(
*
scanner
,
int
)
int
// Reached end of top-level value.
endTop
bool
// Stack of what we're in the middle of - array values, object keys, object values.
parseState
[]
int
// Error that happened, if any.
err
error
// 1-byte redo (see undo method)
redo
bool
redoCode
int
redoState
func
(
*
scanner
,
int
)
int
// total bytes consumed, updated by decoder.Decode
bytes
int64
}
// These values are returned by the state transition functions
// assigned to scanner.state and the method scanner.eof.
// They give details about the current state of the scan that
// callers might be interested to know about.
// It is okay to ignore the return value of any particular
// call to scanner.state: if one call returns scanError,
// every subsequent call will return scanError too.
const
(
// Continue.
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
// Stop.
scanEnd
// top-level value ended *before* this byte; known to be first "stop" result
scanError
// hit an error, scanner.err.
)
// These values are stored in the parseState stack.
// They give the current state of a composite value
// being scanned. If the parser is inside a nested value
// the parseState describes the nested state, outermost at entry 0.
const
(
parseObjectKey
=
iota
// parsing object key (before colon)
parseObjectValue
// parsing object value (after colon)
parseArrayValue
// parsing array value
)
// reset prepares the scanner for use.
// It must be called before calling s.step.
func
(
s
*
scanner
)
reset
()
{
s
.
step
=
stateBeginValue
s
.
parseState
=
s
.
parseState
[
0
:
0
]
s
.
err
=
nil
s
.
redo
=
false
s
.
endTop
=
false
}
// eof tells the scanner that the end of input has been reached.
// It returns a scan status just as s.step does.
func
(
s
*
scanner
)
eof
()
int
{
if
s
.
err
!=
nil
{
return
scanError
}
if
s
.
endTop
{
return
scanEnd
}
s
.
step
(
s
,
' '
)
if
s
.
endTop
{
return
scanEnd
}
if
s
.
err
==
nil
{
s
.
err
=
&
SyntaxError
{
"unexpected end of JSON input"
,
s
.
bytes
}
}
return
scanError
}
// pushParseState pushes a new parse state p onto the parse stack.
func
(
s
*
scanner
)
pushParseState
(
p
int
)
{
s
.
parseState
=
append
(
s
.
parseState
,
p
)
}
// popParseState pops a parse state (already obtained) off the stack
// and updates s.step accordingly.
func
(
s
*
scanner
)
popParseState
()
{
n
:=
len
(
s
.
parseState
)
-
1
s
.
parseState
=
s
.
parseState
[
0
:
n
]
s
.
redo
=
false
if
n
==
0
{
s
.
step
=
stateEndTop
s
.
endTop
=
true
}
else
{
s
.
step
=
stateEndValue
}
}
func
isSpace
(
c
rune
)
bool
{
return
c
==
' '
||
c
==
'\t'
||
c
==
'\r'
||
c
==
'\n'
}
// stateBeginValueOrEmpty is the state after reading `[`.
func
stateBeginValueOrEmpty
(
s
*
scanner
,
c
int
)
int
{
if
c
<=
' '
&&
isSpace
(
rune
(
c
))
{
return
scanSkipSpace
}
if
c
==
']'
{
return
stateEndValue
(
s
,
c
)
}
return
stateBeginValue
(
s
,
c
)
}
// stateBeginValue is the state at the beginning of the input.
func
stateBeginValue
(
s
*
scanner
,
c
int
)
int
{
if
c
<=
' '
&&
isSpace
(
rune
(
c
))
{
return
scanSkipSpace
}
switch
c
{
case
'{'
:
s
.
step
=
stateBeginStringOrEmpty
s
.
pushParseState
(
parseObjectKey
)
return
scanBeginObject
case
'['
:
s
.
step
=
stateBeginValueOrEmpty
s
.
pushParseState
(
parseArrayValue
)
return
scanBeginArray
case
'"'
:
s
.
step
=
stateInString
return
scanBeginLiteral
case
'-'
:
s
.
step
=
stateNeg
return
scanBeginLiteral
case
'0'
:
// beginning of 0.123
s
.
step
=
state0
return
scanBeginLiteral
case
't'
:
// beginning of true
s
.
step
=
stateT
return
scanBeginLiteral
case
'f'
:
// beginning of false
s
.
step
=
stateF
return
scanBeginLiteral
case
'n'
:
// beginning of null
s
.
step
=
stateN
return
scanBeginLiteral
}
if
'1'
<=
c
&&
c
<=
'9'
{
// beginning of 1234.5
s
.
step
=
state1
return
scanBeginLiteral
}
return
s
.
error
(
c
,
"looking for beginning of value"
)
}
// stateBeginStringOrEmpty is the state after reading `{`.
func
stateBeginStringOrEmpty
(
s
*
scanner
,
c
int
)
int
{
if
c
<=
' '
&&
isSpace
(
rune
(
c
))
{
return
scanSkipSpace
}
if
c
==
'}'
{
n
:=
len
(
s
.
parseState
)
s
.
parseState
[
n
-
1
]
=
parseObjectValue
return
stateEndValue
(
s
,
c
)
}
return
stateBeginString
(
s
,
c
)
}
// stateBeginString is the state after reading `{"key": value,`.
func
stateBeginString
(
s
*
scanner
,
c
int
)
int
{
if
c
<=
' '
&&
isSpace
(
rune
(
c
))
{
return
scanSkipSpace
}
if
c
==
'"'
{
s
.
step
=
stateInString
return
scanBeginLiteral
}
return
s
.
error
(
c
,
"looking for beginning of object key string"
)
}
// stateEndValue is the state after completing a value,
// such as after reading `{}` or `true` or `["x"`.
func
stateEndValue
(
s
*
scanner
,
c
int
)
int
{
n
:=
len
(
s
.
parseState
)
if
n
==
0
{
// Completed top-level before the current byte.
s
.
step
=
stateEndTop
s
.
endTop
=
true
return
stateEndTop
(
s
,
c
)
}
if
c
<=
' '
&&
isSpace
(
rune
(
c
))
{
s
.
step
=
stateEndValue
return
scanSkipSpace
}
ps
:=
s
.
parseState
[
n
-
1
]
switch
ps
{
case
parseObjectKey
:
if
c
==
':'
{
s
.
parseState
[
n
-
1
]
=
parseObjectValue
s
.
step
=
stateBeginValue
return
scanObjectKey
}
return
s
.
error
(
c
,
"after object key"
)
case
parseObjectValue
:
if
c
==
','
{
s
.
parseState
[
n
-
1
]
=
parseObjectKey
s
.
step
=
stateBeginString
return
scanObjectValue
}
if
c
==
'}'
{
s
.
popParseState
()
return
scanEndObject
}
return
s
.
error
(
c
,
"after object key:value pair"
)
case
parseArrayValue
:
if
c
==
','
{
s
.
step
=
stateBeginValue
return
scanArrayValue
}
if
c
==
']'
{
s
.
popParseState
()
return
scanEndArray
}
return
s
.
error
(
c
,
"after array element"
)
}
return
s
.
error
(
c
,
""
)
}
// stateEndTop is the state after finishing the top-level value,
// such as after reading `{}` or `[1,2,3]`.
// Only space characters should be seen now.
func
stateEndTop
(
s
*
scanner
,
c
int
)
int
{
if
c
!=
' '
&&
c
!=
'\t'
&&
c
!=
'\r'
&&
c
!=
'\n'
{
// Complain about non-space byte on next call.
s
.
error
(
c
,
"after top-level value"
)
}
return
scanEnd
}
// stateInString is the state after reading `"`.
func
stateInString
(
s
*
scanner
,
c
int
)
int
{
if
c
==
'"'
{
s
.
step
=
stateEndValue
return
scanContinue
}
if
c
==
'\\'
{
s
.
step
=
stateInStringEsc
return
scanContinue
}
if
c
<
0x20
{
return
s
.
error
(
c
,
"in string literal"
)
}
return
scanContinue
}
// stateInStringEsc is the state after reading `"\` during a quoted string.
func
stateInStringEsc
(
s
*
scanner
,
c
int
)
int
{
switch
c
{
case
'b'
,
'f'
,
'n'
,
'r'
,
't'
,
'\\'
,
'/'
,
'"'
:
s
.
step
=
stateInString
return
scanContinue
}
if
c
==
'u'
{
s
.
step
=
stateInStringEscU
return
scanContinue
}
return
s
.
error
(
c
,
"in string escape code"
)
}
// stateInStringEscU is the state after reading `"\u` during a quoted string.
func
stateInStringEscU
(
s
*
scanner
,
c
int
)
int
{
if
'0'
<=
c
&&
c
<=
'9'
||
'a'
<=
c
&&
c
<=
'f'
||
'A'
<=
c
&&
c
<=
'F'
{
s
.
step
=
stateInStringEscU1
return
scanContinue
}
// numbers
return
s
.
error
(
c
,
"in
\\
u hexadecimal character escape"
)
}
// stateInStringEscU1 is the state after reading `"\u1` during a quoted string.
func
stateInStringEscU1
(
s
*
scanner
,
c
int
)
int
{
if
'0'
<=
c
&&
c
<=
'9'
||
'a'
<=
c
&&
c
<=
'f'
||
'A'
<=
c
&&
c
<=
'F'
{
s
.
step
=
stateInStringEscU12
return
scanContinue
}
// numbers
return
s
.
error
(
c
,
"in
\\
u hexadecimal character escape"
)
}
// stateInStringEscU12 is the state after reading `"\u12` during a quoted string.
func
stateInStringEscU12
(
s
*
scanner
,
c
int
)
int
{
if
'0'
<=
c
&&
c
<=
'9'
||
'a'
<=
c
&&
c
<=
'f'
||
'A'
<=
c
&&
c
<=
'F'
{
s
.
step
=
stateInStringEscU123
return
scanContinue
}
// numbers
return
s
.
error
(
c
,
"in
\\
u hexadecimal character escape"
)
}
// stateInStringEscU123 is the state after reading `"\u123` during a quoted string.
func
stateInStringEscU123
(
s
*
scanner
,
c
int
)
int
{
if
'0'
<=
c
&&
c
<=
'9'
||
'a'
<=
c
&&
c
<=
'f'
||
'A'
<=
c
&&
c
<=
'F'
{
s
.
step
=
stateInString
return
scanContinue
}
// numbers
return
s
.
error
(
c
,
"in
\\
u hexadecimal character escape"
)
}
// stateNeg is the state after reading `-` during a number.
func
stateNeg
(
s
*
scanner
,
c
int
)
int
{
if
c
==
'0'
{
s
.
step
=
state0
return
scanContinue
}
if
'1'
<=
c
&&
c
<=
'9'
{
s
.
step
=
state1
return
scanContinue
}
return
s
.
error
(
c
,
"in numeric literal"
)
}
// state1 is the state after reading a non-zero integer during a number,
// such as after reading `1` or `100` but not `0`.
func
state1
(
s
*
scanner
,
c
int
)
int
{
if
'0'
<=
c
&&
c
<=
'9'
{
s
.
step
=
state1
return
scanContinue
}
return
state0
(
s
,
c
)
}
// state0 is the state after reading `0` during a number.
func
state0
(
s
*
scanner
,
c
int
)
int
{
if
c
==
'.'
{
s
.
step
=
stateDot
return
scanContinue
}
if
c
==
'e'
||
c
==
'E'
{
s
.
step
=
stateE
return
scanContinue
}
return
stateEndValue
(
s
,
c
)
}
// stateDot is the state after reading the integer and decimal point in a number,
// such as after reading `1.`.
func
stateDot
(
s
*
scanner
,
c
int
)
int
{
if
'0'
<=
c
&&
c
<=
'9'
{
s
.
step
=
stateDot0
return
scanContinue
}
return
s
.
error
(
c
,
"after decimal point in numeric literal"
)
}
// stateDot0 is the state after reading the integer, decimal point, and subsequent
// digits of a number, such as after reading `3.14`.
func
stateDot0
(
s
*
scanner
,
c
int
)
int
{
if
'0'
<=
c
&&
c
<=
'9'
{
s
.
step
=
stateDot0
return
scanContinue
}
if
c
==
'e'
||
c
==
'E'
{
s
.
step
=
stateE
return
scanContinue
}
return
stateEndValue
(
s
,
c
)
}
// stateE is the state after reading the mantissa and e in a number,
// such as after reading `314e` or `0.314e`.
func
stateE
(
s
*
scanner
,
c
int
)
int
{
if
c
==
'+'
{
s
.
step
=
stateESign
return
scanContinue
}
if
c
==
'-'
{
s
.
step
=
stateESign
return
scanContinue
}
return
stateESign
(
s
,
c
)
}
// stateESign is the state after reading the mantissa, e, and sign in a number,
// such as after reading `314e-` or `0.314e+`.
func
stateESign
(
s
*
scanner
,
c
int
)
int
{
if
'0'
<=
c
&&
c
<=
'9'
{
s
.
step
=
stateE0
return
scanContinue
}
return
s
.
error
(
c
,
"in exponent of numeric literal"
)
}
// stateE0 is the state after reading the mantissa, e, optional sign,
// and at least one digit of the exponent in a number,
// such as after reading `314e-2` or `0.314e+1` or `3.14e0`.
func
stateE0
(
s
*
scanner
,
c
int
)
int
{
if
'0'
<=
c
&&
c
<=
'9'
{
s
.
step
=
stateE0
return
scanContinue
}
return
stateEndValue
(
s
,
c
)
}
// stateT is the state after reading `t`.
func
stateT
(
s
*
scanner
,
c
int
)
int
{
if
c
==
'r'
{
s
.
step
=
stateTr
return
scanContinue
}
return
s
.
error
(
c
,
"in literal true (expecting 'r')"
)
}
// stateTr is the state after reading `tr`.
func
stateTr
(
s
*
scanner
,
c
int
)
int
{
if
c
==
'u'
{
s
.
step
=
stateTru
return
scanContinue
}
return
s
.
error
(
c
,
"in literal true (expecting 'u')"
)
}
// stateTru is the state after reading `tru`.
func
stateTru
(
s
*
scanner
,
c
int
)
int
{
if
c
==
'e'
{
s
.
step
=
stateEndValue
return
scanContinue
}
return
s
.
error
(
c
,
"in literal true (expecting 'e')"
)
}
// stateF is the state after reading `f`.
func
stateF
(
s
*
scanner
,
c
int
)
int
{
if
c
==
'a'
{
s
.
step
=
stateFa
return
scanContinue
}
return
s
.
error
(
c
,
"in literal false (expecting 'a')"
)
}
// stateFa is the state after reading `fa`.
func
stateFa
(
s
*
scanner
,
c
int
)
int
{
if
c
==
'l'
{
s
.
step
=
stateFal
return
scanContinue
}
return
s
.
error
(
c
,
"in literal false (expecting 'l')"
)
}
// stateFal is the state after reading `fal`.
func
stateFal
(
s
*
scanner
,
c
int
)
int
{
if
c
==
's'
{
s
.
step
=
stateFals
return
scanContinue
}
return
s
.
error
(
c
,
"in literal false (expecting 's')"
)
}
// stateFals is the state after reading `fals`.
func
stateFals
(
s
*
scanner
,
c
int
)
int
{
if
c
==
'e'
{
s
.
step
=
stateEndValue
return
scanContinue
}
return
s
.
error
(
c
,
"in literal false (expecting 'e')"
)
}
// stateN is the state after reading `n`.
func
stateN
(
s
*
scanner
,
c
int
)
int
{
if
c
==
'u'
{
s
.
step
=
stateNu
return
scanContinue
}
return
s
.
error
(
c
,
"in literal null (expecting 'u')"
)
}
// stateNu is the state after reading `nu`.
func
stateNu
(
s
*
scanner
,
c
int
)
int
{
if
c
==
'l'
{
s
.
step
=
stateNul
return
scanContinue
}
return
s
.
error
(
c
,
"in literal null (expecting 'l')"
)
}
// stateNul is the state after reading `nul`.
func
stateNul
(
s
*
scanner
,
c
int
)
int
{
if
c
==
'l'
{
s
.
step
=
stateEndValue
return
scanContinue
}
return
s
.
error
(
c
,
"in literal null (expecting 'l')"
)
}
// stateError is the state after reaching a syntax error,
// such as after reading `[1}` or `5.1.2`.
func
stateError
(
s
*
scanner
,
c
int
)
int
{
return
scanError
}
// error records an error and switches to the error state.
func
(
s
*
scanner
)
error
(
c
int
,
context
string
)
int
{
s
.
step
=
stateError
s
.
err
=
&
SyntaxError
{
"invalid character "
+
quoteChar
(
c
)
+
" "
+
context
,
s
.
bytes
}
return
scanError
}
// quoteChar formats c as a quoted character literal
func
quoteChar
(
c
int
)
string
{
// special cases - different from quoted strings
if
c
==
'\'
'
{
return
`'\''`
}
if
c
==
'"'
{
return
`'"'`
}
// use quoted string with different quotation marks
s
:=
strconv
.
Quote
(
string
(
c
))
return
"'"
+
s
[
1
:
len
(
s
)
-
1
]
+
"'"
}
// undo causes the scanner to return scanCode from the next state transition.
// This gives callers a simple 1-byte undo mechanism.
func
(
s
*
scanner
)
undo
(
scanCode
int
)
{
if
s
.
redo
{
panic
(
"json: invalid use of scanner"
)
}
s
.
redoCode
=
scanCode
s
.
redoState
=
s
.
step
s
.
step
=
stateRedo
s
.
redo
=
true
}
// stateRedo helps implement the scanner's 1-byte undo.
func
stateRedo
(
s
*
scanner
,
c
int
)
int
{
s
.
redo
=
false
s
.
step
=
s
.
redoState
return
s
.
redoCode
}
vendor/github.com/CorgiMan/json2/stream.go
0 → 100644
浏览文件 @
ee667a09
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
json2
import
(
"bytes"
"errors"
"io"
)
// A Decoder reads and decodes JSON objects from an input stream.
type
Decoder
struct
{
r
io
.
Reader
buf
[]
byte
d
decodeState
scan
scanner
err
error
}
// NewDecoder returns a new decoder that reads from r.
//
// The decoder introduces its own buffering and may
// read data from r beyond the JSON values requested.
func
NewDecoder
(
r
io
.
Reader
)
*
Decoder
{
return
&
Decoder
{
r
:
r
}
}
// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
// Number instead of as a float64.
func
(
dec
*
Decoder
)
UseNumber
()
{
dec
.
d
.
useNumber
=
true
}
// Decode reads the next JSON-encoded value from its
// input and stores it in the value pointed to by v.
//
// See the documentation for Unmarshal for details about
// the conversion of JSON into a Go value.
func
(
dec
*
Decoder
)
Decode
(
v
interface
{})
error
{
if
dec
.
err
!=
nil
{
return
dec
.
err
}
n
,
err
:=
dec
.
readValue
()
if
err
!=
nil
{
return
err
}
// Don't save err from unmarshal into dec.err:
// the connection is still usable since we read a complete JSON
// object from it before the error happened.
dec
.
d
.
init
(
dec
.
buf
[
0
:
n
])
err
=
dec
.
d
.
unmarshal
(
v
)
// Slide rest of data down.
rest
:=
copy
(
dec
.
buf
,
dec
.
buf
[
n
:
])
dec
.
buf
=
dec
.
buf
[
0
:
rest
]
return
err
}
// Buffered returns a reader of the data remaining in the Decoder's
// buffer. The reader is valid until the next call to Decode.
func
(
dec
*
Decoder
)
Buffered
()
io
.
Reader
{
return
bytes
.
NewReader
(
dec
.
buf
)
}
// readValue reads a JSON value into dec.buf.
// It returns the length of the encoding.
func
(
dec
*
Decoder
)
readValue
()
(
int
,
error
)
{
dec
.
scan
.
reset
()
scanp
:=
0
var
err
error
Input
:
for
{
// Look in the buffer for a new value.
for
i
,
c
:=
range
dec
.
buf
[
scanp
:
]
{
dec
.
scan
.
bytes
++
v
:=
dec
.
scan
.
step
(
&
dec
.
scan
,
int
(
c
))
if
v
==
scanEnd
{
scanp
+=
i
break
Input
}
// scanEnd is delayed one byte.
// We might block trying to get that byte from src,
// so instead invent a space byte.
if
(
v
==
scanEndObject
||
v
==
scanEndArray
)
&&
dec
.
scan
.
step
(
&
dec
.
scan
,
' '
)
==
scanEnd
{
scanp
+=
i
+
1
break
Input
}
if
v
==
scanError
{
dec
.
err
=
dec
.
scan
.
err
return
0
,
dec
.
scan
.
err
}
}
scanp
=
len
(
dec
.
buf
)
// Did the last read have an error?
// Delayed until now to allow buffer scan.
if
err
!=
nil
{
if
err
==
io
.
EOF
{
if
dec
.
scan
.
step
(
&
dec
.
scan
,
' '
)
==
scanEnd
{
break
Input
}
if
nonSpace
(
dec
.
buf
)
{
err
=
io
.
ErrUnexpectedEOF
}
}
dec
.
err
=
err
return
0
,
err
}
// Make room to read more into the buffer.
const
minRead
=
512
if
cap
(
dec
.
buf
)
-
len
(
dec
.
buf
)
<
minRead
{
newBuf
:=
make
([]
byte
,
len
(
dec
.
buf
),
2
*
cap
(
dec
.
buf
)
+
minRead
)
copy
(
newBuf
,
dec
.
buf
)
dec
.
buf
=
newBuf
}
// Read. Delay error for next iteration (after scan).
var
n
int
n
,
err
=
dec
.
r
.
Read
(
dec
.
buf
[
len
(
dec
.
buf
)
:
cap
(
dec
.
buf
)])
dec
.
buf
=
dec
.
buf
[
0
:
len
(
dec
.
buf
)
+
n
]
}
return
scanp
,
nil
}
func
nonSpace
(
b
[]
byte
)
bool
{
for
_
,
c
:=
range
b
{
if
!
isSpace
(
rune
(
c
))
{
return
true
}
}
return
false
}
// An Encoder writes JSON objects to an output stream.
type
Encoder
struct
{
w
io
.
Writer
e
encodeState
err
error
}
// NewEncoder returns a new encoder that writes to w.
func
NewEncoder
(
w
io
.
Writer
)
*
Encoder
{
return
&
Encoder
{
w
:
w
}
}
// Encode writes the JSON encoding of v to the stream.
//
// See the documentation for Marshal for details about the
// conversion of Go values to JSON.
func
(
enc
*
Encoder
)
Encode
(
v
interface
{})
error
{
if
enc
.
err
!=
nil
{
return
enc
.
err
}
e
:=
newEncodeState
()
err
:=
e
.
marshal
(
v
)
if
err
!=
nil
{
return
err
}
// Terminate each value with a newline.
// This makes the output look a little nicer
// when debugging, and some kind of space
// is required if the encoded value was a number,
// so that the reader knows there aren't more
// digits coming.
e
.
WriteByte
(
'\n'
)
if
_
,
err
=
enc
.
w
.
Write
(
e
.
Bytes
());
err
!=
nil
{
enc
.
err
=
err
}
putEncodeState
(
e
)
return
err
}
// RawMessage is a raw encoded JSON object.
// It implements Marshaler and Unmarshaler and can
// be used to delay JSON decoding or precompute a JSON encoding.
type
RawMessage
[]
byte
// MarshalJSON returns *m as the JSON encoding of m.
func
(
m
*
RawMessage
)
MarshalJSON
()
([]
byte
,
error
)
{
return
*
m
,
nil
}
// UnmarshalJSON sets *m to a copy of data.
func
(
m
*
RawMessage
)
UnmarshalJSON
(
data
[]
byte
)
error
{
if
m
==
nil
{
return
errors
.
New
(
"json.RawMessage: UnmarshalJSON on nil pointer"
)
}
*
m
=
append
((
*
m
)[
0
:
0
],
data
...
)
return
nil
}
var
_
Marshaler
=
(
*
RawMessage
)(
nil
)
var
_
Unmarshaler
=
(
*
RawMessage
)(
nil
)
vendor/github.com/CorgiMan/json2/tags.go
0 → 100644
浏览文件 @
ee667a09
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
json2
import
(
"strings"
)
// tagOptions is the string following a comma in a struct field's "json"
// tag, or the empty string. It does not include the leading comma.
type
tagOptions
string
// parseTag splits a struct field's json tag into its name and
// comma-separated options.
func
parseTag
(
tag
string
)
(
string
,
tagOptions
)
{
if
idx
:=
strings
.
Index
(
tag
,
","
);
idx
!=
-
1
{
return
tag
[
:
idx
],
tagOptions
(
tag
[
idx
+
1
:
])
}
return
tag
,
tagOptions
(
""
)
}
// Contains reports whether a comma-separated list of options
// contains a particular substr flag. substr must be surrounded by a
// string boundary or commas.
func
(
o
tagOptions
)
Contains
(
optionName
string
)
bool
{
if
len
(
o
)
==
0
{
return
false
}
s
:=
string
(
o
)
for
s
!=
""
{
var
next
string
i
:=
strings
.
Index
(
s
,
","
)
if
i
>=
0
{
s
,
next
=
s
[
:
i
],
s
[
i
+
1
:
]
}
if
s
==
optionName
{
return
true
}
s
=
next
}
return
false
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录