mirror of https://github.com/goccy/go-json.git
Add special operation for opStructFieldHead and opStructField
This commit is contained in:
parent
93ce3f8bd2
commit
9ba13f68ff
|
@ -435,6 +435,26 @@ func (e *Encoder) typeToHeaderType(op opType) opType {
|
|||
return opStructFieldHeadString
|
||||
case opBool:
|
||||
return opStructFieldHeadBool
|
||||
case opMapHead:
|
||||
return opStructFieldHeadMap
|
||||
case opMapHeadLoad:
|
||||
return opStructFieldHeadMapLoad
|
||||
case opMapHeadIndent:
|
||||
return opStructFieldHeadMapIndent
|
||||
case opMapHeadLoadIndent:
|
||||
return opStructFieldHeadMapLoadIndent
|
||||
case opArrayHead:
|
||||
return opStructFieldHeadArray
|
||||
case opArrayHeadIndent:
|
||||
return opStructFieldHeadArrayIndent
|
||||
case opSliceHead:
|
||||
return opStructFieldHeadSlice
|
||||
case opSliceHeadIndent:
|
||||
return opStructFieldHeadSliceIndent
|
||||
case opStructFieldHead:
|
||||
return opStructFieldHeadStruct
|
||||
case opStructFieldHeadIndent:
|
||||
return opStructFieldHeadStructIndent
|
||||
case opMarshalJSON:
|
||||
return opStructFieldHeadMarshalJSON
|
||||
case opMarshalText:
|
||||
|
@ -473,6 +493,26 @@ func (e *Encoder) typeToFieldType(op opType) opType {
|
|||
return opStructFieldString
|
||||
case opBool:
|
||||
return opStructFieldBool
|
||||
case opMapHead:
|
||||
return opStructFieldMap
|
||||
case opMapHeadLoad:
|
||||
return opStructFieldMapLoad
|
||||
case opMapHeadIndent:
|
||||
return opStructFieldMapIndent
|
||||
case opMapHeadLoadIndent:
|
||||
return opStructFieldMapLoadIndent
|
||||
case opArrayHead:
|
||||
return opStructFieldArray
|
||||
case opArrayHeadIndent:
|
||||
return opStructFieldArrayIndent
|
||||
case opSliceHead:
|
||||
return opStructFieldSlice
|
||||
case opSliceHeadIndent:
|
||||
return opStructFieldSliceIndent
|
||||
case opStructFieldHead:
|
||||
return opStructFieldStruct
|
||||
case opStructFieldHeadIndent:
|
||||
return opStructFieldStructIndent
|
||||
case opMarshalJSON:
|
||||
return opStructFieldMarshalJSON
|
||||
case opMarshalText:
|
||||
|
@ -541,10 +581,30 @@ func (e *Encoder) structHeader(fieldCode *structFieldCode, valueCode *opcode, ta
|
|||
fieldCode.op = op
|
||||
switch op {
|
||||
case opStructFieldHead,
|
||||
opStructFieldHeadSlice,
|
||||
opStructFieldHeadArray,
|
||||
opStructFieldHeadMap,
|
||||
opStructFieldHeadMapLoad,
|
||||
opStructFieldHeadStruct,
|
||||
opStructFieldHeadOmitEmpty,
|
||||
opStructFieldHeadOmitEmptySlice,
|
||||
opStructFieldHeadOmitEmptyArray,
|
||||
opStructFieldHeadOmitEmptyMap,
|
||||
opStructFieldHeadOmitEmptyMapLoad,
|
||||
opStructFieldHeadOmitEmptyStruct,
|
||||
opStructFieldHeadStringTag,
|
||||
opStructFieldHeadIndent,
|
||||
opStructFieldHeadSliceIndent,
|
||||
opStructFieldHeadArrayIndent,
|
||||
opStructFieldHeadMapIndent,
|
||||
opStructFieldHeadMapLoadIndent,
|
||||
opStructFieldHeadStructIndent,
|
||||
opStructFieldHeadOmitEmptyIndent,
|
||||
opStructFieldHeadOmitEmptySliceIndent,
|
||||
opStructFieldHeadOmitEmptyArrayIndent,
|
||||
opStructFieldHeadOmitEmptyMapIndent,
|
||||
opStructFieldHeadOmitEmptyMapLoadIndent,
|
||||
opStructFieldHeadOmitEmptyStructIndent,
|
||||
opStructFieldHeadStringTagIndent:
|
||||
return valueCode.beforeLastCode()
|
||||
}
|
||||
|
@ -557,10 +617,30 @@ func (e *Encoder) structField(fieldCode *structFieldCode, valueCode *opcode, tag
|
|||
fieldCode.op = op
|
||||
switch op {
|
||||
case opStructField,
|
||||
opStructFieldSlice,
|
||||
opStructFieldArray,
|
||||
opStructFieldMap,
|
||||
opStructFieldMapLoad,
|
||||
opStructFieldStruct,
|
||||
opStructFieldOmitEmpty,
|
||||
opStructFieldOmitEmptySlice,
|
||||
opStructFieldOmitEmptyArray,
|
||||
opStructFieldOmitEmptyMap,
|
||||
opStructFieldOmitEmptyMapLoad,
|
||||
opStructFieldOmitEmptyStruct,
|
||||
opStructFieldStringTag,
|
||||
opStructFieldIndent,
|
||||
opStructFieldSliceIndent,
|
||||
opStructFieldArrayIndent,
|
||||
opStructFieldMapIndent,
|
||||
opStructFieldMapLoadIndent,
|
||||
opStructFieldStructIndent,
|
||||
opStructFieldOmitEmptyIndent,
|
||||
opStructFieldOmitEmptySliceIndent,
|
||||
opStructFieldOmitEmptyArrayIndent,
|
||||
opStructFieldOmitEmptyMapIndent,
|
||||
opStructFieldOmitEmptyMapLoadIndent,
|
||||
opStructFieldOmitEmptyStructIndent,
|
||||
opStructFieldStringTagIndent:
|
||||
return valueCode.beforeLastCode()
|
||||
}
|
||||
|
|
379
encode_vm.go
379
encode_vm.go
|
@ -1093,6 +1093,78 @@ func (e *Encoder) run(code *opcode) error {
|
|||
field.nextField.ptr = ptr
|
||||
code = field.next
|
||||
}
|
||||
case opStructFieldPtrHeadArray:
|
||||
code.ptr = e.ptrToPtr(code.ptr)
|
||||
fallthrough
|
||||
case opStructFieldHeadArray:
|
||||
c := code.toStructFieldCode()
|
||||
ptr := c.ptr + c.offset
|
||||
if ptr == 0 {
|
||||
if code.op == opStructFieldPtrHeadArray {
|
||||
e.encodeNull()
|
||||
} else {
|
||||
e.encodeBytes([]byte{'[', ']'})
|
||||
}
|
||||
code = c.end
|
||||
} else {
|
||||
e.encodeByte('{')
|
||||
if !c.anonymousKey {
|
||||
e.encodeBytes(c.key)
|
||||
}
|
||||
code = c.next
|
||||
code.ptr = ptr
|
||||
c.nextField.ptr = ptr
|
||||
}
|
||||
case opStructFieldPtrAnonymousHeadArray:
|
||||
code.ptr = e.ptrToPtr(code.ptr)
|
||||
fallthrough
|
||||
case opStructFieldAnonymousHeadArray:
|
||||
c := code.toStructFieldCode()
|
||||
ptr := c.ptr + c.offset
|
||||
if ptr == 0 {
|
||||
code = c.end
|
||||
} else {
|
||||
e.encodeBytes(c.key)
|
||||
code.ptr = ptr
|
||||
c.nextField.ptr = ptr
|
||||
code = c.next
|
||||
}
|
||||
case opStructFieldPtrHeadSlice:
|
||||
code.ptr = e.ptrToPtr(code.ptr)
|
||||
fallthrough
|
||||
case opStructFieldHeadSlice:
|
||||
c := code.toStructFieldCode()
|
||||
ptr := c.ptr + c.offset
|
||||
if ptr == 0 {
|
||||
if code.op == opStructFieldPtrHeadSlice {
|
||||
e.encodeNull()
|
||||
} else {
|
||||
e.encodeBytes([]byte{'[', ']'})
|
||||
}
|
||||
code = c.end
|
||||
} else {
|
||||
e.encodeByte('{')
|
||||
if !c.anonymousKey {
|
||||
e.encodeBytes(c.key)
|
||||
}
|
||||
code = c.next
|
||||
code.ptr = ptr
|
||||
c.nextField.ptr = ptr
|
||||
}
|
||||
case opStructFieldPtrAnonymousHeadSlice:
|
||||
code.ptr = e.ptrToPtr(code.ptr)
|
||||
fallthrough
|
||||
case opStructFieldAnonymousHeadSlice:
|
||||
c := code.toStructFieldCode()
|
||||
ptr := c.ptr + c.offset
|
||||
if ptr == 0 {
|
||||
code = c.end
|
||||
} else {
|
||||
e.encodeBytes(c.key)
|
||||
code.ptr = ptr
|
||||
c.nextField.ptr = ptr
|
||||
code = c.next
|
||||
}
|
||||
case opStructFieldPtrHeadMarshalJSON:
|
||||
code.ptr = e.ptrToPtr(code.ptr)
|
||||
fallthrough
|
||||
|
@ -4150,6 +4222,51 @@ func (e *Encoder) run(code *opcode) error {
|
|||
}
|
||||
e.encodeString(*(*string)(unsafe.Pointer(&bytes)))
|
||||
code = code.next
|
||||
case opStructFieldArray:
|
||||
if e.buf[len(e.buf)-1] != '{' {
|
||||
e.encodeByte(',')
|
||||
}
|
||||
c := code.toStructFieldCode()
|
||||
c.nextField.ptr = c.ptr
|
||||
code = code.next
|
||||
code.ptr = c.ptr + c.offset
|
||||
e.encodeBytes(c.key)
|
||||
case opStructFieldSlice:
|
||||
if e.buf[len(e.buf)-1] != '{' {
|
||||
e.encodeByte(',')
|
||||
}
|
||||
c := code.toStructFieldCode()
|
||||
c.nextField.ptr = c.ptr
|
||||
code = code.next
|
||||
code.ptr = c.ptr + c.offset
|
||||
e.encodeBytes(c.key)
|
||||
case opStructFieldMap:
|
||||
if e.buf[len(e.buf)-1] != '{' {
|
||||
e.encodeByte(',')
|
||||
}
|
||||
c := code.toStructFieldCode()
|
||||
e.encodeBytes(c.key)
|
||||
code = code.next
|
||||
code.ptr = c.ptr + c.offset
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldMapLoad:
|
||||
if e.buf[len(e.buf)-1] != '{' {
|
||||
e.encodeByte(',')
|
||||
}
|
||||
c := code.toStructFieldCode()
|
||||
e.encodeBytes(c.key)
|
||||
code = code.next
|
||||
code.ptr = c.ptr + c.offset
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldStruct:
|
||||
if e.buf[len(e.buf)-1] != '{' {
|
||||
e.encodeByte(',')
|
||||
}
|
||||
c := code.toStructFieldCode()
|
||||
e.encodeBytes(c.key)
|
||||
code = code.next
|
||||
code.ptr = c.ptr + c.offset
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldIndent:
|
||||
c := code.toStructFieldCode()
|
||||
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
|
||||
|
@ -4363,6 +4480,111 @@ func (e *Encoder) run(code *opcode) error {
|
|||
e.encodeBytes(buf.Bytes())
|
||||
code = code.next
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldArrayIndent:
|
||||
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
|
||||
e.encodeBytes([]byte{',', '\n'})
|
||||
}
|
||||
c := code.toStructFieldCode()
|
||||
e.encodeIndent(c.indent)
|
||||
e.encodeBytes(c.key)
|
||||
e.encodeByte(' ')
|
||||
p := c.ptr + c.offset
|
||||
header := (*reflect.SliceHeader)(unsafe.Pointer(p))
|
||||
if p == 0 || header.Data == 0 {
|
||||
e.encodeNull()
|
||||
code = c.nextField
|
||||
} else {
|
||||
code = code.next
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldSliceIndent:
|
||||
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
|
||||
e.encodeBytes([]byte{',', '\n'})
|
||||
}
|
||||
c := code.toStructFieldCode()
|
||||
e.encodeIndent(c.indent)
|
||||
e.encodeBytes(c.key)
|
||||
e.encodeByte(' ')
|
||||
p := c.ptr + c.offset
|
||||
header := (*reflect.SliceHeader)(unsafe.Pointer(p))
|
||||
if p == 0 || header.Data == 0 {
|
||||
e.encodeNull()
|
||||
code = c.nextField
|
||||
} else {
|
||||
code = code.next
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldMapIndent:
|
||||
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
|
||||
e.encodeBytes([]byte{',', '\n'})
|
||||
}
|
||||
c := code.toStructFieldCode()
|
||||
e.encodeIndent(c.indent)
|
||||
e.encodeBytes(c.key)
|
||||
e.encodeByte(' ')
|
||||
p := c.ptr + c.offset
|
||||
if p == 0 {
|
||||
e.encodeNull()
|
||||
code = c.nextField
|
||||
} else {
|
||||
mlen := maplen(unsafe.Pointer(p))
|
||||
if mlen == 0 {
|
||||
e.encodeBytes([]byte{'{', '}'})
|
||||
mapCode := code.next
|
||||
mapHeadCode := mapCode.toMapHeadCode()
|
||||
code = mapHeadCode.end.next
|
||||
} else {
|
||||
code = code.next
|
||||
}
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldMapLoadIndent:
|
||||
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
|
||||
e.encodeBytes([]byte{',', '\n'})
|
||||
}
|
||||
c := code.toStructFieldCode()
|
||||
e.encodeIndent(c.indent)
|
||||
e.encodeBytes(c.key)
|
||||
e.encodeByte(' ')
|
||||
p := c.ptr + c.offset
|
||||
if p == 0 {
|
||||
e.encodeNull()
|
||||
code = c.nextField
|
||||
} else {
|
||||
p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p)))
|
||||
mlen := maplen(unsafe.Pointer(p))
|
||||
if mlen == 0 {
|
||||
e.encodeBytes([]byte{'{', '}'})
|
||||
code = c.nextField
|
||||
} else {
|
||||
code = code.next
|
||||
}
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldStructIndent:
|
||||
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
|
||||
e.encodeBytes([]byte{',', '\n'})
|
||||
}
|
||||
c := code.toStructFieldCode()
|
||||
p := c.ptr + c.offset
|
||||
e.encodeIndent(c.indent)
|
||||
e.encodeBytes(c.key)
|
||||
e.encodeByte(' ')
|
||||
if p == 0 {
|
||||
e.encodeBytes([]byte{'{', '}'})
|
||||
code = c.nextField
|
||||
} else {
|
||||
headCode := c.next.toStructFieldCode()
|
||||
if headCode.next == headCode.end {
|
||||
// not exists fields
|
||||
e.encodeBytes([]byte{'{', '}'})
|
||||
code = c.nextField
|
||||
} else {
|
||||
code = code.next
|
||||
code.ptr = p
|
||||
}
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldOmitEmpty:
|
||||
c := code.toStructFieldCode()
|
||||
p := c.ptr + c.offset
|
||||
|
@ -4612,6 +4834,67 @@ func (e *Encoder) run(code *opcode) error {
|
|||
}
|
||||
code = code.next
|
||||
code.ptr = c.ptr
|
||||
case opStructFieldOmitEmptyArray:
|
||||
c := code.toStructFieldCode()
|
||||
p := c.ptr + c.offset
|
||||
header := (*reflect.SliceHeader)(unsafe.Pointer(p))
|
||||
if p == 0 || header.Data == 0 {
|
||||
code = c.nextField
|
||||
} else {
|
||||
if e.buf[len(e.buf)-1] != '{' {
|
||||
e.encodeByte(',')
|
||||
}
|
||||
code = code.next
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldOmitEmptySlice:
|
||||
c := code.toStructFieldCode()
|
||||
p := c.ptr + c.offset
|
||||
header := (*reflect.SliceHeader)(unsafe.Pointer(p))
|
||||
if p == 0 || header.Data == 0 {
|
||||
code = c.nextField
|
||||
} else {
|
||||
if e.buf[len(e.buf)-1] != '{' {
|
||||
e.encodeByte(',')
|
||||
}
|
||||
code = code.next
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldOmitEmptyMap:
|
||||
c := code.toStructFieldCode()
|
||||
p := c.ptr + c.offset
|
||||
if p == 0 {
|
||||
code = c.nextField
|
||||
} else {
|
||||
mlen := maplen(unsafe.Pointer(p))
|
||||
if mlen == 0 {
|
||||
code = c.nextField
|
||||
} else {
|
||||
if e.buf[len(e.buf)-1] != '{' {
|
||||
e.encodeByte(',')
|
||||
}
|
||||
code = code.next
|
||||
}
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldOmitEmptyMapLoad:
|
||||
c := code.toStructFieldCode()
|
||||
p := c.ptr + c.offset
|
||||
if p == 0 {
|
||||
code = c.nextField
|
||||
} else {
|
||||
p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p)))
|
||||
mlen := maplen(unsafe.Pointer(p))
|
||||
if mlen == 0 {
|
||||
code = c.nextField
|
||||
} else {
|
||||
if e.buf[len(e.buf)-1] != '{' {
|
||||
e.encodeByte(',')
|
||||
}
|
||||
code = code.next
|
||||
}
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldOmitEmptyIndent:
|
||||
c := code.toStructFieldCode()
|
||||
p := c.ptr + c.offset
|
||||
|
@ -4847,6 +5130,102 @@ func (e *Encoder) run(code *opcode) error {
|
|||
}
|
||||
code = code.next
|
||||
code.ptr = c.ptr
|
||||
case opStructFieldOmitEmptyArrayIndent:
|
||||
c := code.toStructFieldCode()
|
||||
p := c.ptr + c.offset
|
||||
header := (*reflect.SliceHeader)(unsafe.Pointer(p))
|
||||
if p == 0 || header.Data == 0 {
|
||||
code = c.nextField
|
||||
} else {
|
||||
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
|
||||
e.encodeBytes([]byte{',', '\n'})
|
||||
}
|
||||
e.encodeIndent(c.indent)
|
||||
e.encodeBytes(c.key)
|
||||
e.encodeByte(' ')
|
||||
code = code.next
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldOmitEmptySliceIndent:
|
||||
c := code.toStructFieldCode()
|
||||
p := c.ptr + c.offset
|
||||
header := (*reflect.SliceHeader)(unsafe.Pointer(p))
|
||||
if p == 0 || header.Data == 0 {
|
||||
code = c.nextField
|
||||
} else {
|
||||
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
|
||||
e.encodeBytes([]byte{',', '\n'})
|
||||
}
|
||||
e.encodeIndent(c.indent)
|
||||
e.encodeBytes(c.key)
|
||||
e.encodeByte(' ')
|
||||
code = code.next
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldOmitEmptyMapIndent:
|
||||
c := code.toStructFieldCode()
|
||||
p := c.ptr + c.offset
|
||||
if p == 0 {
|
||||
code = c.nextField
|
||||
} else {
|
||||
mlen := maplen(unsafe.Pointer(p))
|
||||
if mlen == 0 {
|
||||
code = c.nextField
|
||||
} else {
|
||||
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
|
||||
e.encodeBytes([]byte{',', '\n'})
|
||||
}
|
||||
e.encodeIndent(c.indent)
|
||||
e.encodeBytes(c.key)
|
||||
e.encodeByte(' ')
|
||||
code = code.next
|
||||
}
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldOmitEmptyMapLoadIndent:
|
||||
c := code.toStructFieldCode()
|
||||
p := c.ptr + c.offset
|
||||
if p == 0 {
|
||||
code = c.nextField
|
||||
} else {
|
||||
p = uintptr(*(*unsafe.Pointer)(unsafe.Pointer(p)))
|
||||
mlen := maplen(unsafe.Pointer(p))
|
||||
if mlen == 0 {
|
||||
code = c.nextField
|
||||
} else {
|
||||
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
|
||||
e.encodeBytes([]byte{',', '\n'})
|
||||
}
|
||||
e.encodeIndent(c.indent)
|
||||
e.encodeBytes(c.key)
|
||||
e.encodeByte(' ')
|
||||
code = code.next
|
||||
}
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldOmitEmptyStructIndent:
|
||||
c := code.toStructFieldCode()
|
||||
p := c.ptr + c.offset
|
||||
if p == 0 {
|
||||
code = c.nextField
|
||||
} else {
|
||||
if e.buf[len(e.buf)-2] != '{' || e.buf[len(e.buf)-1] == '}' {
|
||||
e.encodeBytes([]byte{',', '\n'})
|
||||
}
|
||||
e.encodeIndent(c.indent)
|
||||
e.encodeBytes(c.key)
|
||||
e.encodeByte(' ')
|
||||
headCode := c.next.toStructFieldCode()
|
||||
if headCode.next == headCode.end {
|
||||
// not exists fields
|
||||
e.encodeBytes([]byte{'{', '}'})
|
||||
code = c.nextField
|
||||
} else {
|
||||
code = code.next
|
||||
code.ptr = p
|
||||
}
|
||||
}
|
||||
c.nextField.ptr = c.ptr
|
||||
case opStructFieldStringTag:
|
||||
c := code.toStructFieldCode()
|
||||
p := c.ptr + c.offset
|
||||
|
|
Loading…
Reference in New Issue