summaryrefslogtreecommitdiff
path: root/vendor/github.com/goccy/go-json/internal/encoder/encoder.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/goccy/go-json/internal/encoder/encoder.go')
-rw-r--r--vendor/github.com/goccy/go-json/internal/encoder/encoder.go134
1 files changed, 76 insertions, 58 deletions
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/encoder.go b/vendor/github.com/goccy/go-json/internal/encoder/encoder.go
index ef6b910ad..b7fa99a96 100644
--- a/vendor/github.com/goccy/go-json/internal/encoder/encoder.go
+++ b/vendor/github.com/goccy/go-json/internal/encoder/encoder.go
@@ -17,14 +17,6 @@ import (
"github.com/goccy/go-json/internal/runtime"
)
-type Option int
-
-const (
- HTMLEscapeOption Option = 1 << iota
- IndentOption
- UnorderedMapOption
-)
-
func (t OpType) IsMultipleOpHead() bool {
switch t {
case OpStructHead:
@@ -102,9 +94,13 @@ func (t OpType) IsMultipleOpField() bool {
}
type OpcodeSet struct {
- Type *runtime.Type
- Code *Opcode
- CodeLength int
+ Type *runtime.Type
+ NoescapeKeyCode *Opcode
+ EscapeKeyCode *Opcode
+ InterfaceNoescapeKeyCode *Opcode
+ InterfaceEscapeKeyCode *Opcode
+ CodeLength int
+ EndCode *Opcode
}
type CompiledCode struct {
@@ -276,7 +272,7 @@ func MapIterNext(it unsafe.Pointer)
//go:noescape
func MapLen(m unsafe.Pointer) int
-func AppendByteSlice(b []byte, src []byte) []byte {
+func AppendByteSlice(_ *RuntimeContext, b []byte, src []byte) []byte {
if src == nil {
return append(b, `null`...)
}
@@ -294,7 +290,7 @@ func AppendByteSlice(b []byte, src []byte) []byte {
return append(append(b, buf...), '"')
}
-func AppendFloat32(b []byte, v float32) []byte {
+func AppendFloat32(_ *RuntimeContext, b []byte, v float32) []byte {
f64 := float64(v)
abs := math.Abs(f64)
fmt := byte('f')
@@ -308,7 +304,7 @@ func AppendFloat32(b []byte, v float32) []byte {
return strconv.AppendFloat(b, f64, fmt, -1, 32)
}
-func AppendFloat64(b []byte, v float64) []byte {
+func AppendFloat64(_ *RuntimeContext, b []byte, v float64) []byte {
abs := math.Abs(v)
fmt := byte('f')
// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
@@ -320,7 +316,7 @@ func AppendFloat64(b []byte, v float64) []byte {
return strconv.AppendFloat(b, v, fmt, -1, 64)
}
-func AppendBool(b []byte, v bool) []byte {
+func AppendBool(_ *RuntimeContext, b []byte, v bool) []byte {
if v {
return append(b, "true"...)
}
@@ -347,7 +343,7 @@ var (
}
)
-func AppendNumber(b []byte, n json.Number) ([]byte, error) {
+func AppendNumber(_ *RuntimeContext, b []byte, n json.Number) ([]byte, error) {
if len(n) == 0 {
return append(b, '0'), nil
}
@@ -360,9 +356,9 @@ func AppendNumber(b []byte, n json.Number) ([]byte, error) {
return b, nil
}
-func AppendMarshalJSON(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}, escape bool) ([]byte, error) {
+func AppendMarshalJSON(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) {
rv := reflect.ValueOf(v) // convert by dynamic interface type
- if code.AddrForMarshaler {
+ if (code.Flags & AddrForMarshalerFlags) != 0 {
if rv.CanAddr() {
rv = rv.Addr()
} else {
@@ -372,17 +368,31 @@ func AppendMarshalJSON(ctx *RuntimeContext, code *Opcode, b []byte, v interface{
}
}
v = rv.Interface()
- marshaler, ok := v.(json.Marshaler)
- if !ok {
- return AppendNull(b), nil
- }
- bb, err := marshaler.MarshalJSON()
- if err != nil {
- return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ var bb []byte
+ if (code.Flags & MarshalerContextFlags) != 0 {
+ marshaler, ok := v.(marshalerContext)
+ if !ok {
+ return AppendNull(ctx, b), nil
+ }
+ b, err := marshaler.MarshalJSON(ctx.Option.Context)
+ if err != nil {
+ return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ }
+ bb = b
+ } else {
+ marshaler, ok := v.(json.Marshaler)
+ if !ok {
+ return AppendNull(ctx, b), nil
+ }
+ b, err := marshaler.MarshalJSON()
+ if err != nil {
+ return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ }
+ bb = b
}
marshalBuf := ctx.MarshalBuf[:0]
marshalBuf = append(append(marshalBuf, bb...), nul)
- compactedBuf, err := compact(b, marshalBuf, escape)
+ compactedBuf, err := compact(b, marshalBuf, (ctx.Option.Flag&HTMLEscapeOption) != 0)
if err != nil {
return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
}
@@ -390,9 +400,9 @@ func AppendMarshalJSON(ctx *RuntimeContext, code *Opcode, b []byte, v interface{
return compactedBuf, nil
}
-func AppendMarshalJSONIndent(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}, escape bool) ([]byte, error) {
+func AppendMarshalJSONIndent(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) {
rv := reflect.ValueOf(v) // convert by dynamic interface type
- if code.AddrForMarshaler {
+ if (code.Flags & AddrForMarshalerFlags) != 0 {
if rv.CanAddr() {
rv = rv.Addr()
} else {
@@ -402,22 +412,36 @@ func AppendMarshalJSONIndent(ctx *RuntimeContext, code *Opcode, b []byte, v inte
}
}
v = rv.Interface()
- marshaler, ok := v.(json.Marshaler)
- if !ok {
- return AppendNull(b), nil
- }
- bb, err := marshaler.MarshalJSON()
- if err != nil {
- return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ var bb []byte
+ if (code.Flags & MarshalerContextFlags) != 0 {
+ marshaler, ok := v.(marshalerContext)
+ if !ok {
+ return AppendNull(ctx, b), nil
+ }
+ b, err := marshaler.MarshalJSON(ctx.Option.Context)
+ if err != nil {
+ return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ }
+ bb = b
+ } else {
+ marshaler, ok := v.(json.Marshaler)
+ if !ok {
+ return AppendNull(ctx, b), nil
+ }
+ b, err := marshaler.MarshalJSON()
+ if err != nil {
+ return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ }
+ bb = b
}
marshalBuf := ctx.MarshalBuf[:0]
marshalBuf = append(append(marshalBuf, bb...), nul)
indentedBuf, err := doIndent(
b,
marshalBuf,
- string(ctx.Prefix)+strings.Repeat(string(ctx.IndentStr), ctx.BaseIndent+code.Indent),
+ string(ctx.Prefix)+strings.Repeat(string(ctx.IndentStr), int(ctx.BaseIndent+code.Indent)),
string(ctx.IndentStr),
- escape,
+ (ctx.Option.Flag&HTMLEscapeOption) != 0,
)
if err != nil {
return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
@@ -426,9 +450,9 @@ func AppendMarshalJSONIndent(ctx *RuntimeContext, code *Opcode, b []byte, v inte
return indentedBuf, nil
}
-func AppendMarshalText(code *Opcode, b []byte, v interface{}, escape bool) ([]byte, error) {
+func AppendMarshalText(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) {
rv := reflect.ValueOf(v) // convert by dynamic interface type
- if code.AddrForMarshaler {
+ if (code.Flags & AddrForMarshalerFlags) != 0 {
if rv.CanAddr() {
rv = rv.Addr()
} else {
@@ -440,21 +464,18 @@ func AppendMarshalText(code *Opcode, b []byte, v interface{}, escape bool) ([]by
v = rv.Interface()
marshaler, ok := v.(encoding.TextMarshaler)
if !ok {
- return AppendNull(b), nil
+ return AppendNull(ctx, b), nil
}
bytes, err := marshaler.MarshalText()
if err != nil {
return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
}
- if escape {
- return AppendEscapedString(b, *(*string)(unsafe.Pointer(&bytes))), nil
- }
- return AppendString(b, *(*string)(unsafe.Pointer(&bytes))), nil
+ return AppendString(ctx, b, *(*string)(unsafe.Pointer(&bytes))), nil
}
-func AppendMarshalTextIndent(code *Opcode, b []byte, v interface{}, escape bool) ([]byte, error) {
+func AppendMarshalTextIndent(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) {
rv := reflect.ValueOf(v) // convert by dynamic interface type
- if code.AddrForMarshaler {
+ if (code.Flags & AddrForMarshalerFlags) != 0 {
if rv.CanAddr() {
rv = rv.Addr()
} else {
@@ -466,31 +487,28 @@ func AppendMarshalTextIndent(code *Opcode, b []byte, v interface{}, escape bool)
v = rv.Interface()
marshaler, ok := v.(encoding.TextMarshaler)
if !ok {
- return AppendNull(b), nil
+ return AppendNull(ctx, b), nil
}
bytes, err := marshaler.MarshalText()
if err != nil {
return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
}
- if escape {
- return AppendEscapedString(b, *(*string)(unsafe.Pointer(&bytes))), nil
- }
- return AppendString(b, *(*string)(unsafe.Pointer(&bytes))), nil
+ return AppendString(ctx, b, *(*string)(unsafe.Pointer(&bytes))), nil
}
-func AppendNull(b []byte) []byte {
+func AppendNull(_ *RuntimeContext, b []byte) []byte {
return append(b, "null"...)
}
-func AppendComma(b []byte) []byte {
+func AppendComma(_ *RuntimeContext, b []byte) []byte {
return append(b, ',')
}
-func AppendCommaIndent(b []byte) []byte {
+func AppendCommaIndent(_ *RuntimeContext, b []byte) []byte {
return append(b, ',', '\n')
}
-func AppendStructEnd(b []byte) []byte {
+func AppendStructEnd(_ *RuntimeContext, b []byte) []byte {
return append(b, '}', ',')
}
@@ -498,16 +516,16 @@ func AppendStructEndIndent(ctx *RuntimeContext, code *Opcode, b []byte) []byte {
b = append(b, '\n')
b = append(b, ctx.Prefix...)
indentNum := ctx.BaseIndent + code.Indent - 1
- for i := 0; i < indentNum; i++ {
+ for i := uint32(0); i < indentNum; i++ {
b = append(b, ctx.IndentStr...)
}
return append(b, '}', ',', '\n')
}
-func AppendIndent(ctx *RuntimeContext, b []byte, indent int) []byte {
+func AppendIndent(ctx *RuntimeContext, b []byte, indent uint32) []byte {
b = append(b, ctx.Prefix...)
indentNum := ctx.BaseIndent + indent
- for i := 0; i < indentNum; i++ {
+ for i := uint32(0); i < indentNum; i++ {
b = append(b, ctx.IndentStr...)
}
return b