Fix handling of comma as delimiter

This commit is contained in:
Masaaki Goshima 2020-11-16 19:10:46 +09:00
parent c2307ab6d7
commit 5ec3bca1cd
5 changed files with 810 additions and 483 deletions

View File

@ -102,6 +102,11 @@ func (e *Encoder) EncodeWithOption(v interface{}, opts ...EncodeOption) error {
if err := e.encode(v); err != nil { if err := e.encode(v); err != nil {
return err return err
} }
if e.enabledIndent {
e.buf = e.buf[:len(e.buf)-2]
} else {
e.buf = e.buf[:len(e.buf)-1]
}
e.buf = append(e.buf, '\n') e.buf = append(e.buf, '\n')
if _, err := e.w.Write(e.buf); err != nil { if _, err := e.w.Write(e.buf); err != nil {
return err return err
@ -147,16 +152,11 @@ func (e *Encoder) encodeForMarshal(v interface{}) ([]byte, error) {
return nil, err return nil, err
} }
if e.enabledIndent { if e.enabledIndent {
last := len(e.buf) - 1 copied := make([]byte, len(e.buf)-2)
if e.buf[last] == '\n' { copy(copied, e.buf)
last--
}
length := last + 1
copied := make([]byte, length)
copy(copied, e.buf[0:length])
return copied, nil return copied, nil
} }
copied := make([]byte, len(e.buf)) copied := make([]byte, len(e.buf)-1)
copy(copied, e.buf) copy(copied, e.buf)
return copied, nil return copied, nil
} }
@ -164,6 +164,11 @@ func (e *Encoder) encodeForMarshal(v interface{}) ([]byte, error) {
func (e *Encoder) encode(v interface{}) error { func (e *Encoder) encode(v interface{}) error {
if v == nil { if v == nil {
e.encodeNull() e.encodeNull()
if e.enabledIndent {
e.encodeBytes([]byte{',', '\n'})
} else {
e.encodeByte(',')
}
return nil return nil
} }
header := (*interfaceHeader)(unsafe.Pointer(&v)) header := (*interfaceHeader)(unsafe.Pointer(&v))

View File

@ -427,32 +427,60 @@ func (e *Encoder) typeToHeaderType(op opType) opType {
switch op { switch op {
case opInt: case opInt:
return opStructFieldHeadInt return opStructFieldHeadInt
case opIntIndent:
return opStructFieldHeadIntIndent
case opInt8: case opInt8:
return opStructFieldHeadInt8 return opStructFieldHeadInt8
case opInt8Indent:
return opStructFieldHeadInt8Indent
case opInt16: case opInt16:
return opStructFieldHeadInt16 return opStructFieldHeadInt16
case opInt16Indent:
return opStructFieldHeadInt16Indent
case opInt32: case opInt32:
return opStructFieldHeadInt32 return opStructFieldHeadInt32
case opInt32Indent:
return opStructFieldHeadInt32Indent
case opInt64: case opInt64:
return opStructFieldHeadInt64 return opStructFieldHeadInt64
case opInt64Indent:
return opStructFieldHeadInt64Indent
case opUint: case opUint:
return opStructFieldHeadUint return opStructFieldHeadUint
case opUintIndent:
return opStructFieldHeadUintIndent
case opUint8: case opUint8:
return opStructFieldHeadUint8 return opStructFieldHeadUint8
case opUint8Indent:
return opStructFieldHeadUint8Indent
case opUint16: case opUint16:
return opStructFieldHeadUint16 return opStructFieldHeadUint16
case opUint16Indent:
return opStructFieldHeadUint16Indent
case opUint32: case opUint32:
return opStructFieldHeadUint32 return opStructFieldHeadUint32
case opUint32Indent:
return opStructFieldHeadUint32Indent
case opUint64: case opUint64:
return opStructFieldHeadUint64 return opStructFieldHeadUint64
case opUint64Indent:
return opStructFieldHeadUint64Indent
case opFloat32: case opFloat32:
return opStructFieldHeadFloat32 return opStructFieldHeadFloat32
case opFloat32Indent:
return opStructFieldHeadFloat32Indent
case opFloat64: case opFloat64:
return opStructFieldHeadFloat64 return opStructFieldHeadFloat64
case opFloat64Indent:
return opStructFieldHeadFloat64Indent
case opString: case opString:
return opStructFieldHeadString return opStructFieldHeadString
case opStringIndent:
return opStructFieldHeadStringIndent
case opBool: case opBool:
return opStructFieldHeadBool return opStructFieldHeadBool
case opBoolIndent:
return opStructFieldHeadBoolIndent
case opMapHead: case opMapHead:
return opStructFieldHeadMap return opStructFieldHeadMap
case opMapHeadLoad: case opMapHeadLoad:
@ -475,8 +503,12 @@ func (e *Encoder) typeToHeaderType(op opType) opType {
return opStructFieldHeadStructIndent return opStructFieldHeadStructIndent
case opMarshalJSON: case opMarshalJSON:
return opStructFieldHeadMarshalJSON return opStructFieldHeadMarshalJSON
case opMarshalJSONIndent:
return opStructFieldHeadMarshalJSONIndent
case opMarshalText: case opMarshalText:
return opStructFieldHeadMarshalText return opStructFieldHeadMarshalText
case opMarshalTextIndent:
return opStructFieldHeadMarshalTextIndent
} }
return opStructFieldHead return opStructFieldHead
} }
@ -516,32 +548,60 @@ func (e *Encoder) typeToFieldType(code *opcode) opType {
} }
case opInt: case opInt:
return opStructFieldInt return opStructFieldInt
case opIntIndent:
return opStructFieldIntIndent
case opInt8: case opInt8:
return opStructFieldInt8 return opStructFieldInt8
case opInt8Indent:
return opStructFieldInt8Indent
case opInt16: case opInt16:
return opStructFieldInt16 return opStructFieldInt16
case opInt16Indent:
return opStructFieldInt16Indent
case opInt32: case opInt32:
return opStructFieldInt32 return opStructFieldInt32
case opInt32Indent:
return opStructFieldInt32Indent
case opInt64: case opInt64:
return opStructFieldInt64 return opStructFieldInt64
case opInt64Indent:
return opStructFieldInt64Indent
case opUint: case opUint:
return opStructFieldUint return opStructFieldUint
case opUintIndent:
return opStructFieldUintIndent
case opUint8: case opUint8:
return opStructFieldUint8 return opStructFieldUint8
case opUint8Indent:
return opStructFieldUint8Indent
case opUint16: case opUint16:
return opStructFieldUint16 return opStructFieldUint16
case opUint16Indent:
return opStructFieldUint16Indent
case opUint32: case opUint32:
return opStructFieldUint32 return opStructFieldUint32
case opUint32Indent:
return opStructFieldUint32Indent
case opUint64: case opUint64:
return opStructFieldUint64 return opStructFieldUint64
case opUint64Indent:
return opStructFieldUint64Indent
case opFloat32: case opFloat32:
return opStructFieldFloat32 return opStructFieldFloat32
case opFloat32Indent:
return opStructFieldFloat32Indent
case opFloat64: case opFloat64:
return opStructFieldFloat64 return opStructFieldFloat64
case opFloat64Indent:
return opStructFieldFloat64Indent
case opString: case opString:
return opStructFieldString return opStructFieldString
case opStringIndent:
return opStructFieldStringIndent
case opBool: case opBool:
return opStructFieldBool return opStructFieldBool
case opBoolIndent:
return opStructFieldBoolIndent
case opMapHead: case opMapHead:
return opStructFieldMap return opStructFieldMap
case opMapHeadLoad: case opMapHeadLoad:
@ -564,8 +624,12 @@ func (e *Encoder) typeToFieldType(code *opcode) opType {
return opStructFieldStructIndent return opStructFieldStructIndent
case opMarshalJSON: case opMarshalJSON:
return opStructFieldMarshalJSON return opStructFieldMarshalJSON
case opMarshalJSONIndent:
return opStructFieldMarshalJSONIndent
case opMarshalText: case opMarshalText:
return opStructFieldMarshalText return opStructFieldMarshalText
case opMarshalTextIndent:
return opStructFieldMarshalTextIndent
} }
return opStructField return opStructField
} }

View File

@ -53,6 +53,9 @@ func copyOpcode(code *opcode) *opcode {
} }
func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opcode { func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opcode {
if op != opEnd && ctx.withIndent {
op = op.toIndent()
}
return &opcode{ return &opcode{
op: op, op: op,
typ: ctx.typ, typ: ctx.typ,

File diff suppressed because it is too large Load Diff

View File

@ -394,7 +394,7 @@ func HTMLEscape(dst *bytes.Buffer, src []byte) {
enc := NewEncoder(dst) enc := NewEncoder(dst)
enc.SetEscapeHTML(true) enc.SetEscapeHTML(true)
enc.encode(v) enc.encode(v)
dst.Write(enc.buf) dst.Write(enc.buf[:len(enc.buf)-1]) // remove last ',' character
} }
// Valid reports whether data is a valid JSON encoding. // Valid reports whether data is a valid JSON encoding.