forked from mirror/go-json
Pass all test cases
This commit is contained in:
parent
039bdf2791
commit
c2307ab6d7
|
@ -765,10 +765,10 @@ func (e *Encoder) anonymousStructFieldPairMap(typ *rtype, tags structTags, named
|
||||||
} else if op != f.op {
|
} else if op != f.op {
|
||||||
if existsKey {
|
if existsKey {
|
||||||
f.op = opStructFieldAnonymousHead
|
f.op = opStructFieldAnonymousHead
|
||||||
} else {
|
} else if named == "" {
|
||||||
f.op = op
|
f.op = op
|
||||||
}
|
}
|
||||||
} else if f.op == opStructEnd {
|
} else if named == "" && f.op == opStructEnd {
|
||||||
f.op = opStructAnonymousEnd
|
f.op = opStructAnonymousEnd
|
||||||
} else if existsKey {
|
} else if existsKey {
|
||||||
diff := f.nextField.displayIdx - f.displayIdx
|
diff := f.nextField.displayIdx - f.displayIdx
|
||||||
|
@ -808,9 +808,9 @@ func (e *Encoder) anonymousStructFieldPairMap(typ *rtype, tags structTags, named
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) optimizeConflictAnonymousFields(anonymousFields map[string][]structFieldPair) {
|
func (e *Encoder) optimizeConflictAnonymousFields(anonymousFields map[string][]structFieldPair) {
|
||||||
fmt.Printf("anonymousFields = %+v\n", anonymousFields)
|
//fmt.Printf("anonymousFields = %+v\n", anonymousFields)
|
||||||
removedFields := map[*opcode]struct{}{}
|
removedFields := map[*opcode]struct{}{}
|
||||||
for name, fieldPairs := range anonymousFields {
|
for _, fieldPairs := range anonymousFields {
|
||||||
if len(fieldPairs) == 1 {
|
if len(fieldPairs) == 1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -823,24 +823,24 @@ func (e *Encoder) optimizeConflictAnonymousFields(anonymousFields map[string][]s
|
||||||
if !fieldPair.linked {
|
if !fieldPair.linked {
|
||||||
if fieldPair.prevField == nil {
|
if fieldPair.prevField == nil {
|
||||||
// head operation
|
// head operation
|
||||||
fmt.Println("omit:", fieldPair.curField.displayKey)
|
//fmt.Println("omit:", fieldPair.curField.displayKey)
|
||||||
fieldPair.curField.op = opStructFieldAnonymousHead
|
fieldPair.curField.op = opStructFieldAnonymousHead
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("remove", name)
|
//fmt.Println("remove", name)
|
||||||
diff := fieldPair.curField.nextField.displayIdx - fieldPair.curField.displayIdx
|
diff := fieldPair.curField.nextField.displayIdx - fieldPair.curField.displayIdx
|
||||||
fmt.Println("link:", fieldPair.prevField.displayKey, "=>", fieldPair.curField.nextField.displayKey)
|
//fmt.Println("link:", fieldPair.prevField.displayKey, "=>", fieldPair.curField.nextField.displayKey)
|
||||||
fmt.Println("diff = ", diff)
|
//fmt.Println("diff = ", diff)
|
||||||
for i := 0; i < diff; i++ {
|
for i := 0; i < diff; i++ {
|
||||||
fieldPair.curField.nextField.decOpcodeIndex()
|
fieldPair.curField.nextField.decOpcodeIndex()
|
||||||
}
|
}
|
||||||
fmt.Println("cur.nextField")
|
//fmt.Println("cur.nextField")
|
||||||
fmt.Println(fieldPair.curField.nextField.dump())
|
//fmt.Println(fieldPair.curField.nextField.dump())
|
||||||
fmt.Println("===========")
|
//fmt.Println("===========")
|
||||||
removedFields[fieldPair.curField] = struct{}{}
|
removedFields[fieldPair.curField] = struct{}{}
|
||||||
linkPrevToNextField(fieldPair.curField, removedFields)
|
linkPrevToNextField(fieldPair.curField, removedFields)
|
||||||
fmt.Println("linked. prevField")
|
//fmt.Println("linked. prevField")
|
||||||
fmt.Println(fieldPair.prevField.dump())
|
//fmt.Println(fieldPair.prevField.dump())
|
||||||
fmt.Println("===========")
|
//fmt.Println("===========")
|
||||||
// tagggedPairs に入れた方にもこの結果を反映させないといけない
|
// tagggedPairs に入れた方にもこの結果を反映させないといけない
|
||||||
}
|
}
|
||||||
fieldPair.linked = true
|
fieldPair.linked = true
|
||||||
|
@ -854,13 +854,13 @@ func (e *Encoder) optimizeConflictAnonymousFields(anonymousFields map[string][]s
|
||||||
// head operation
|
// head operation
|
||||||
fieldPair.curField.op = opStructFieldAnonymousHead
|
fieldPair.curField.op = opStructFieldAnonymousHead
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("TAGGED PAIRS REMOVE")
|
//fmt.Println("TAGGED PAIRS REMOVE")
|
||||||
fmt.Println("remove", name)
|
//fmt.Println("remove", name)
|
||||||
fmt.Println("removedFields = ", removedFields)
|
//fmt.Println("removedFields = ", removedFields)
|
||||||
fmt.Printf("prev = %p cur = %p next = %p\n", fieldPair.curField.prevField, fieldPair.curField, fieldPair.curField.nextField)
|
//fmt.Printf("prev = %p cur = %p next = %p\n", fieldPair.curField.prevField, fieldPair.curField, fieldPair.curField.nextField)
|
||||||
diff := fieldPair.curField.nextField.displayIdx - fieldPair.curField.displayIdx
|
diff := fieldPair.curField.nextField.displayIdx - fieldPair.curField.displayIdx
|
||||||
fmt.Println("link:", fieldPair.prevField.displayKey, "=>", fieldPair.curField.nextField.displayKey)
|
//fmt.Println("link:", fieldPair.prevField.displayKey, "=>", fieldPair.curField.nextField.displayKey)
|
||||||
fmt.Println("diff = ", diff)
|
//fmt.Println("diff = ", diff)
|
||||||
removedFields[fieldPair.curField] = struct{}{}
|
removedFields[fieldPair.curField] = struct{}{}
|
||||||
for i := 0; i < diff; i++ {
|
for i := 0; i < diff; i++ {
|
||||||
fieldPair.curField.nextField.decOpcodeIndex()
|
fieldPair.curField.nextField.decOpcodeIndex()
|
||||||
|
@ -1035,23 +1035,23 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
||||||
|
|
||||||
head.end = structEndCode
|
head.end = structEndCode
|
||||||
code.next = structEndCode
|
code.next = structEndCode
|
||||||
|
/*
|
||||||
fmt.Println("head")
|
fmt.Println("head")
|
||||||
fmt.Println(head.dump())
|
fmt.Println(head.dump())
|
||||||
fmt.Println("===============")
|
fmt.Println("===============")
|
||||||
|
*/
|
||||||
e.optimizeConflictAnonymousFields(anonymousFields)
|
e.optimizeConflictAnonymousFields(anonymousFields)
|
||||||
|
/*
|
||||||
fmt.Println("remove conflicted key head")
|
fmt.Println("remove conflicted key head")
|
||||||
fmt.Println(head.dump())
|
fmt.Println(head.dump())
|
||||||
fmt.Println("===============")
|
fmt.Println("===============")
|
||||||
|
*/
|
||||||
e.optimizeAnonymousFields(head)
|
e.optimizeAnonymousFields(head)
|
||||||
|
/*
|
||||||
fmt.Println("optimized head")
|
fmt.Println("optimized head")
|
||||||
fmt.Println(head.dump())
|
fmt.Println(head.dump())
|
||||||
fmt.Println("===============")
|
fmt.Println("===============")
|
||||||
|
*/
|
||||||
ret := (*opcode)(unsafe.Pointer(head))
|
ret := (*opcode)(unsafe.Pointer(head))
|
||||||
compiled.code = ret
|
compiled.code = ret
|
||||||
|
|
||||||
|
|
13
encode_vm.go
13
encode_vm.go
|
@ -38,10 +38,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
|
||||||
seenPtr := map[uintptr]struct{}{}
|
seenPtr := map[uintptr]struct{}{}
|
||||||
ptrOffset := uintptr(0)
|
ptrOffset := uintptr(0)
|
||||||
ctxptr := ctx.ptr()
|
ctxptr := ctx.ptr()
|
||||||
fmt.Println(code.dump())
|
//fmt.Println(code.dump())
|
||||||
|
|
||||||
for {
|
for {
|
||||||
fmt.Printf("[%d]:[%s]\n", code.displayIdx, code.op)
|
//fmt.Printf("[%d]:[%s]\n", code.displayIdx, code.op)
|
||||||
switch code.op {
|
switch code.op {
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("failed to handle opcode. doesn't implement %s", code.op)
|
return fmt.Errorf("failed to handle opcode. doesn't implement %s", code.op)
|
||||||
|
@ -4195,7 +4195,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
|
||||||
code = code.next
|
code = code.next
|
||||||
}
|
}
|
||||||
case opStructField:
|
case opStructField:
|
||||||
if e.buf[len(e.buf)-1] != '{' {
|
if e.buf[len(e.buf)-1] != '{' && e.buf[len(e.buf)-1] != ',' {
|
||||||
e.encodeByte(',')
|
e.encodeByte(',')
|
||||||
}
|
}
|
||||||
if !code.anonymousKey {
|
if !code.anonymousKey {
|
||||||
|
@ -4218,7 +4218,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
|
||||||
}
|
}
|
||||||
code = code.next
|
code = code.next
|
||||||
case opStructFieldInt:
|
case opStructFieldInt:
|
||||||
if e.buf[len(e.buf)-1] != '{' {
|
if e.buf[len(e.buf)-1] != '{' && e.buf[len(e.buf)-1] != ',' {
|
||||||
e.encodeByte(',')
|
e.encodeByte(',')
|
||||||
}
|
}
|
||||||
ptr := load(ctxptr, code.headIdx)
|
ptr := load(ctxptr, code.headIdx)
|
||||||
|
@ -5900,7 +5900,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
|
||||||
e.encodeString(*(*string)(unsafe.Pointer(&bytes)))
|
e.encodeString(*(*string)(unsafe.Pointer(&bytes)))
|
||||||
code = code.next
|
code = code.next
|
||||||
case opStructEnd:
|
case opStructEnd:
|
||||||
|
last := len(e.buf) - 1
|
||||||
|
if e.buf[last] == ',' {
|
||||||
|
e.buf[last] = '}'
|
||||||
|
} else {
|
||||||
e.encodeByte('}')
|
e.encodeByte('}')
|
||||||
|
}
|
||||||
code = code.next
|
code = code.next
|
||||||
case opStructAnonymousEnd:
|
case opStructAnonymousEnd:
|
||||||
code = code.next
|
code = code.next
|
||||||
|
|
3
json.go
3
json.go
|
@ -317,6 +317,9 @@ func (n Number) Int64() (int64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n Number) MarshalJSON() ([]byte, error) {
|
func (n Number) MarshalJSON() ([]byte, error) {
|
||||||
|
if n == "" {
|
||||||
|
return []byte("0"), nil
|
||||||
|
}
|
||||||
if _, err := n.Float64(); err != nil {
|
if _, err := n.Float64(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue