Manage option flags as bit variable

This commit is contained in:
Masaaki Goshima 2021-06-01 13:40:15 +09:00
parent 611b1aaf1e
commit 4e2a9c06ef
15 changed files with 57 additions and 60 deletions

View File

@ -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
}

View File

@ -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)

View File

@ -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)

View File

@ -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}

View File

@ -1,12 +1,18 @@
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
ColorScheme *ColorScheme
Flag OptionFlag
ColorScheme *ColorScheme
}
type EncodeFormat struct {

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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
}
}