forked from mirror/go-json
Manage option flags as bit variable
This commit is contained in:
parent
611b1aaf1e
commit
4e2a9c06ef
37
encode.go
37
encode.go
|
@ -43,9 +43,9 @@ func (e *Encoder) EncodeWithOption(v interface{}, optFuncs ...EncodeOptionFunc)
|
|||
}
|
||||
|
||||
func (e *Encoder) encodeWithOption(ctx *encoder.RuntimeContext, v interface{}, optFuncs ...EncodeOptionFunc) error {
|
||||
initOption(ctx.Option)
|
||||
ctx.Option.Flag = 0
|
||||
if e.enabledHTMLEscape {
|
||||
ctx.Option.HTMLEscape = true
|
||||
ctx.Option.Flag |= encoder.HTMLEscapeOption
|
||||
}
|
||||
for _, optFunc := range optFuncs {
|
||||
optFunc(ctx.Option)
|
||||
|
@ -97,8 +97,8 @@ func (e *Encoder) SetIndent(prefix, indent string) {
|
|||
func marshal(v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) {
|
||||
ctx := encoder.TakeRuntimeContext()
|
||||
|
||||
initOption(ctx.Option)
|
||||
ctx.Option.HTMLEscape = true
|
||||
ctx.Option.Flag = 0
|
||||
ctx.Option.Flag |= encoder.HTMLEscapeOption
|
||||
for _, optFunc := range optFuncs {
|
||||
optFunc(ctx.Option)
|
||||
}
|
||||
|
@ -124,8 +124,8 @@ func marshal(v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) {
|
|||
func marshalNoEscape(v interface{}) ([]byte, error) {
|
||||
ctx := encoder.TakeRuntimeContext()
|
||||
|
||||
initOption(ctx.Option)
|
||||
ctx.Option.HTMLEscape = true
|
||||
ctx.Option.Flag = 0
|
||||
ctx.Option.Flag |= encoder.HTMLEscapeOption
|
||||
|
||||
buf, err := encodeNoEscape(ctx, v)
|
||||
if err != nil {
|
||||
|
@ -148,9 +148,8 @@ func marshalNoEscape(v interface{}) ([]byte, error) {
|
|||
func marshalIndent(v interface{}, prefix, indent string, optFuncs ...EncodeOptionFunc) ([]byte, error) {
|
||||
ctx := encoder.TakeRuntimeContext()
|
||||
|
||||
initOption(ctx.Option)
|
||||
ctx.Option.HTMLEscape = true
|
||||
ctx.Option.Indent = true
|
||||
ctx.Option.Flag = 0
|
||||
ctx.Option.Flag |= (encoder.HTMLEscapeOption | encoder.IndentOption)
|
||||
for _, optFunc := range optFuncs {
|
||||
optFunc(ctx.Option)
|
||||
}
|
||||
|
@ -255,13 +254,13 @@ func encodeIndent(ctx *encoder.RuntimeContext, v interface{}, prefix, indent str
|
|||
}
|
||||
|
||||
func encodeRunCode(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
if ctx.Option.Debug {
|
||||
if ctx.Option.Colorize {
|
||||
if (ctx.Option.Flag & encoder.DebugOption) != 0 {
|
||||
if (ctx.Option.Flag & encoder.ColorizeOption) != 0 {
|
||||
return vm_color.DebugRun(ctx, b, codeSet)
|
||||
}
|
||||
return vm.DebugRun(ctx, b, codeSet)
|
||||
}
|
||||
if ctx.Option.Colorize {
|
||||
if (ctx.Option.Flag & encoder.ColorizeOption) != 0 {
|
||||
return vm_color.Run(ctx, b, codeSet)
|
||||
}
|
||||
return vm.Run(ctx, b, codeSet)
|
||||
|
@ -270,22 +269,14 @@ func encodeRunCode(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.Opcod
|
|||
func encodeRunIndentCode(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, prefix, indent string) ([]byte, error) {
|
||||
ctx.Prefix = []byte(prefix)
|
||||
ctx.IndentStr = []byte(indent)
|
||||
if ctx.Option.Debug {
|
||||
if ctx.Option.Colorize {
|
||||
if (ctx.Option.Flag & encoder.DebugOption) != 0 {
|
||||
if (ctx.Option.Flag & encoder.ColorizeOption) != 0 {
|
||||
return vm_color_indent.DebugRun(ctx, b, codeSet)
|
||||
}
|
||||
return vm_indent.DebugRun(ctx, b, codeSet)
|
||||
}
|
||||
if ctx.Option.Colorize {
|
||||
if (ctx.Option.Flag & encoder.ColorizeOption) != 0 {
|
||||
return vm_color_indent.Run(ctx, b, codeSet)
|
||||
}
|
||||
return vm_indent.Run(ctx, b, codeSet)
|
||||
}
|
||||
|
||||
func initOption(opt *EncodeOption) {
|
||||
opt.HTMLEscape = false
|
||||
opt.Indent = false
|
||||
opt.UnorderedMap = false
|
||||
opt.Debug = false
|
||||
opt.Colorize = false
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
ptrOffset := uintptr(0)
|
||||
ctxptr := ctx.Ptr()
|
||||
var code *encoder.Opcode
|
||||
if ctx.Option.HTMLEscape {
|
||||
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
|
||||
code = codeSet.EscapeKeyCode
|
||||
} else {
|
||||
code = codeSet.NoescapeKeyCode
|
||||
|
@ -370,7 +370,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
store(ctxptr, code.ElemIdx, 0)
|
||||
store(ctxptr, code.Length, uintptr(mlen))
|
||||
store(ctxptr, code.MapIter, uintptr(iter))
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
b = appendMapKeyIndent(ctx, code.Next, b)
|
||||
} else {
|
||||
mapCtx := encoder.NewMapContext(mlen)
|
||||
|
@ -385,7 +385,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
idx := load(ctxptr, code.ElemIdx)
|
||||
length := load(ctxptr, code.Length)
|
||||
idx++
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
if idx < length {
|
||||
b = appendMapKeyIndent(ctx, code, b)
|
||||
store(ctxptr, code.ElemIdx, idx)
|
||||
|
@ -414,7 +414,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
}
|
||||
}
|
||||
case encoder.OpMapValue:
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
b = appendColon(ctx, b)
|
||||
} else {
|
||||
ptr := load(ctxptr, code.End.MapPos)
|
||||
|
|
|
@ -1456,7 +1456,7 @@ func compileStruct(ctx *compileContext, isPtr bool) (*Opcode, error) {
|
|||
}
|
||||
var key string
|
||||
if ctx.escapeKey {
|
||||
rctx := &RuntimeContext{Option: &Option{HTMLEscape: true}}
|
||||
rctx := &RuntimeContext{Option: &Option{Flag: HTMLEscapeOption}}
|
||||
key = fmt.Sprintf(`%s:`, string(AppendString(rctx, []byte{}, tag.Key)))
|
||||
} else {
|
||||
key = fmt.Sprintf(`"%s":`, tag.Key)
|
||||
|
|
|
@ -375,7 +375,7 @@ func AppendMarshalJSON(ctx *RuntimeContext, code *Opcode, b []byte, v interface{
|
|||
}
|
||||
marshalBuf := ctx.MarshalBuf[:0]
|
||||
marshalBuf = append(append(marshalBuf, bb...), nul)
|
||||
compactedBuf, err := compact(b, marshalBuf, ctx.Option.HTMLEscape)
|
||||
compactedBuf, err := compact(b, marshalBuf, (ctx.Option.Flag&HTMLEscapeOption) != 0)
|
||||
if err != nil {
|
||||
return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
|
||||
}
|
||||
|
@ -410,7 +410,7 @@ func AppendMarshalJSONIndent(ctx *RuntimeContext, code *Opcode, b []byte, v inte
|
|||
marshalBuf,
|
||||
string(ctx.Prefix)+strings.Repeat(string(ctx.IndentStr), int(ctx.BaseIndent+code.Indent)),
|
||||
string(ctx.IndentStr),
|
||||
ctx.Option.HTMLEscape,
|
||||
(ctx.Option.Flag&HTMLEscapeOption) != 0,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
package encoder
|
||||
|
||||
type OptionFlag uint8
|
||||
|
||||
const (
|
||||
HTMLEscapeOption OptionFlag = 1 << iota
|
||||
IndentOption
|
||||
UnorderedMapOption
|
||||
DebugOption
|
||||
ColorizeOption
|
||||
)
|
||||
|
||||
type Option struct {
|
||||
HTMLEscape bool
|
||||
Indent bool
|
||||
UnorderedMap bool
|
||||
Debug bool
|
||||
Colorize bool
|
||||
Flag OptionFlag
|
||||
ColorScheme *ColorScheme
|
||||
}
|
||||
|
||||
|
|
|
@ -406,7 +406,7 @@ func stringToUint64Slice(s string) []uint64 {
|
|||
}
|
||||
|
||||
func AppendString(ctx *RuntimeContext, buf []byte, s string) []byte {
|
||||
if !ctx.Option.HTMLEscape {
|
||||
if ctx.Option.Flag&HTMLEscapeOption == 0 {
|
||||
return appendString(buf, s)
|
||||
}
|
||||
valLen := len(s)
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
defer func() {
|
||||
var code *encoder.Opcode
|
||||
if ctx.Option.HTMLEscape {
|
||||
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
|
||||
code = codeSet.EscapeKeyCode
|
||||
} else {
|
||||
code = codeSet.NoescapeKeyCode
|
||||
|
|
|
@ -14,7 +14,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
ptrOffset := uintptr(0)
|
||||
ctxptr := ctx.Ptr()
|
||||
var code *encoder.Opcode
|
||||
if ctx.Option.HTMLEscape {
|
||||
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
|
||||
code = codeSet.EscapeKeyCode
|
||||
} else {
|
||||
code = codeSet.NoescapeKeyCode
|
||||
|
@ -370,7 +370,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
store(ctxptr, code.ElemIdx, 0)
|
||||
store(ctxptr, code.Length, uintptr(mlen))
|
||||
store(ctxptr, code.MapIter, uintptr(iter))
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
b = appendMapKeyIndent(ctx, code.Next, b)
|
||||
} else {
|
||||
mapCtx := encoder.NewMapContext(mlen)
|
||||
|
@ -385,7 +385,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
idx := load(ctxptr, code.ElemIdx)
|
||||
length := load(ctxptr, code.Length)
|
||||
idx++
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
if idx < length {
|
||||
b = appendMapKeyIndent(ctx, code, b)
|
||||
store(ctxptr, code.ElemIdx, idx)
|
||||
|
@ -414,7 +414,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
}
|
||||
}
|
||||
case encoder.OpMapValue:
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
b = appendColon(ctx, b)
|
||||
} else {
|
||||
ptr := load(ctxptr, code.End.MapPos)
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
var code *encoder.Opcode
|
||||
if ctx.Option.HTMLEscape {
|
||||
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
|
||||
code = codeSet.EscapeKeyCode
|
||||
} else {
|
||||
code = codeSet.NoescapeKeyCode
|
||||
|
|
|
@ -14,7 +14,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
ptrOffset := uintptr(0)
|
||||
ctxptr := ctx.Ptr()
|
||||
var code *encoder.Opcode
|
||||
if ctx.Option.HTMLEscape {
|
||||
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
|
||||
code = codeSet.EscapeKeyCode
|
||||
} else {
|
||||
code = codeSet.NoescapeKeyCode
|
||||
|
@ -370,7 +370,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
store(ctxptr, code.ElemIdx, 0)
|
||||
store(ctxptr, code.Length, uintptr(mlen))
|
||||
store(ctxptr, code.MapIter, uintptr(iter))
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
b = appendMapKeyIndent(ctx, code.Next, b)
|
||||
} else {
|
||||
mapCtx := encoder.NewMapContext(mlen)
|
||||
|
@ -385,7 +385,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
idx := load(ctxptr, code.ElemIdx)
|
||||
length := load(ctxptr, code.Length)
|
||||
idx++
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
if idx < length {
|
||||
b = appendMapKeyIndent(ctx, code, b)
|
||||
store(ctxptr, code.ElemIdx, idx)
|
||||
|
@ -414,7 +414,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
}
|
||||
}
|
||||
case encoder.OpMapValue:
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
b = appendColon(ctx, b)
|
||||
} else {
|
||||
ptr := load(ctxptr, code.End.MapPos)
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
var code *encoder.Opcode
|
||||
if ctx.Option.HTMLEscape {
|
||||
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
|
||||
code = codeSet.EscapeKeyCode
|
||||
} else {
|
||||
code = codeSet.NoescapeKeyCode
|
||||
|
|
|
@ -14,7 +14,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
ptrOffset := uintptr(0)
|
||||
ctxptr := ctx.Ptr()
|
||||
var code *encoder.Opcode
|
||||
if ctx.Option.HTMLEscape {
|
||||
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
|
||||
code = codeSet.EscapeKeyCode
|
||||
} else {
|
||||
code = codeSet.NoescapeKeyCode
|
||||
|
@ -370,7 +370,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
store(ctxptr, code.ElemIdx, 0)
|
||||
store(ctxptr, code.Length, uintptr(mlen))
|
||||
store(ctxptr, code.MapIter, uintptr(iter))
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
b = appendMapKeyIndent(ctx, code.Next, b)
|
||||
} else {
|
||||
mapCtx := encoder.NewMapContext(mlen)
|
||||
|
@ -385,7 +385,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
idx := load(ctxptr, code.ElemIdx)
|
||||
length := load(ctxptr, code.Length)
|
||||
idx++
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
if idx < length {
|
||||
b = appendMapKeyIndent(ctx, code, b)
|
||||
store(ctxptr, code.ElemIdx, idx)
|
||||
|
@ -414,7 +414,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
}
|
||||
}
|
||||
case encoder.OpMapValue:
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
b = appendColon(ctx, b)
|
||||
} else {
|
||||
ptr := load(ctxptr, code.End.MapPos)
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
|
||||
var code *encoder.Opcode
|
||||
if ctx.Option.HTMLEscape {
|
||||
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
|
||||
code = codeSet.EscapeKeyCode
|
||||
} else {
|
||||
code = codeSet.NoescapeKeyCode
|
||||
|
|
|
@ -14,7 +14,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
ptrOffset := uintptr(0)
|
||||
ctxptr := ctx.Ptr()
|
||||
var code *encoder.Opcode
|
||||
if ctx.Option.HTMLEscape {
|
||||
if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
|
||||
code = codeSet.EscapeKeyCode
|
||||
} else {
|
||||
code = codeSet.NoescapeKeyCode
|
||||
|
@ -370,7 +370,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
store(ctxptr, code.ElemIdx, 0)
|
||||
store(ctxptr, code.Length, uintptr(mlen))
|
||||
store(ctxptr, code.MapIter, uintptr(iter))
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
b = appendMapKeyIndent(ctx, code.Next, b)
|
||||
} else {
|
||||
mapCtx := encoder.NewMapContext(mlen)
|
||||
|
@ -385,7 +385,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
idx := load(ctxptr, code.ElemIdx)
|
||||
length := load(ctxptr, code.Length)
|
||||
idx++
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
if idx < length {
|
||||
b = appendMapKeyIndent(ctx, code, b)
|
||||
store(ctxptr, code.ElemIdx, idx)
|
||||
|
@ -414,7 +414,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b
|
|||
}
|
||||
}
|
||||
case encoder.OpMapValue:
|
||||
if ctx.Option.UnorderedMap {
|
||||
if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
|
||||
b = appendColon(ctx, b)
|
||||
} else {
|
||||
ptr := load(ctxptr, code.End.MapPos)
|
||||
|
|
|
@ -10,19 +10,19 @@ type EncodeOptionFunc func(*EncodeOption)
|
|||
|
||||
func UnorderedMap() EncodeOptionFunc {
|
||||
return func(opt *EncodeOption) {
|
||||
opt.UnorderedMap = true
|
||||
opt.Flag |= encoder.UnorderedMapOption
|
||||
}
|
||||
}
|
||||
|
||||
func Debug() EncodeOptionFunc {
|
||||
return func(opt *EncodeOption) {
|
||||
opt.Debug = true
|
||||
opt.Flag |= encoder.DebugOption
|
||||
}
|
||||
}
|
||||
|
||||
func Colorize(scheme *ColorScheme) EncodeOptionFunc {
|
||||
return func(opt *EncodeOption) {
|
||||
opt.Colorize = true
|
||||
opt.Flag |= encoder.ColorizeOption
|
||||
opt.ColorScheme = scheme
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue