Skip to content

Commit

Permalink
map key decoder
Browse files Browse the repository at this point in the history
  • Loading branch information
zerosnake0 committed Dec 30, 2019
1 parent 731a493 commit 0a8afe3
Show file tree
Hide file tree
Showing 12 changed files with 376 additions and 84 deletions.
7 changes: 7 additions & 0 deletions errors_decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,10 @@ type UnknownFieldError string
func (e UnknownFieldError) Error() string {
return fmt.Sprintf("unknown field %q", string(e))
}

// BadQuotedString
type BadQuotedStringError string

func (e BadQuotedStringError) Error() string {
return fmt.Sprintf("bad quoted string %q", string(e))
}
18 changes: 11 additions & 7 deletions iterator_int16.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,9 @@ func (it *Iterator) readUint16(c byte) (ret uint16, err error) {
}
}

func (it *Iterator) ReadInt16() (int16, error) {
c, _, err := it.nextToken()
if err != nil {
return 0, err
}
it.head += 1
func (it *Iterator) readInt16(c byte) (int16, error) {
if c == '-' {
c, err = it.nextByte()
c, err := it.nextByte()
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -97,3 +92,12 @@ func (it *Iterator) ReadInt16() (int16, error) {
return int16(v), nil
}
}

func (it *Iterator) ReadInt16() (int16, error) {
c, _, err := it.nextToken()
if err != nil {
return 0, err
}
it.head += 1
return it.readInt16(c)
}
18 changes: 11 additions & 7 deletions iterator_int32.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,9 @@ func (it *Iterator) readUint32(c byte) (ret uint32, err error) {
}
}

func (it *Iterator) ReadInt32() (int32, error) {
c, _, err := it.nextToken()
if err != nil {
return 0, err
}
it.head += 1
func (it *Iterator) readInt32(c byte) (int32, error) {
if c == '-' {
c, err = it.nextByte()
c, err := it.nextByte()
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -97,3 +92,12 @@ func (it *Iterator) ReadInt32() (int32, error) {
return int32(v), nil
}
}

func (it *Iterator) ReadInt32() (int32, error) {
c, _, err := it.nextToken()
if err != nil {
return 0, err
}
it.head += 1
return it.readInt32(c)
}
18 changes: 11 additions & 7 deletions iterator_int64.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,9 @@ func (it *Iterator) readUint64(c byte) (ret uint64, err error) {
}
}

func (it *Iterator) ReadInt64() (int64, error) {
c, _, err := it.nextToken()
if err != nil {
return 0, err
}
it.head += 1
func (it *Iterator) readInt64(c byte) (int64, error) {
if c == '-' {
c, err = it.nextByte()
c, err := it.nextByte()
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -98,3 +93,12 @@ func (it *Iterator) ReadInt64() (int64, error) {
return int64(v), nil
}
}

func (it *Iterator) ReadInt64() (int64, error) {
c, _, err := it.nextToken()
if err != nil {
return 0, err
}
it.head += 1
return it.readInt64(c)
}
31 changes: 16 additions & 15 deletions val_decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,30 +64,31 @@ func init() {
mapDecoderKind((*float64)(nil), (*float64Decoder)(nil))

// object key decoders
mapKeyDecoder((*string)(nil), (*stringKeyDecoder)(nil))
mapKeyDecoder((*string)(nil), (*stringDecoder)(nil))
if strconv.IntSize == 32 {
mapKeyDecoder((*int)(nil), (*int32KeyDecoder)(nil))
mapKeyDecoder((*uint)(nil), (*uint32KeyDecoder)(nil))
mapKeyDecoder((*int)(nil), (*int32Decoder)(nil))
mapKeyDecoder((*uint)(nil), (*uint32Decoder)(nil))
} else {
mapKeyDecoder((*int)(nil), (*int64KeyDecoder)(nil))
mapKeyDecoder((*uint)(nil), (*uint64KeyDecoder)(nil))
mapKeyDecoder((*int)(nil), (*int64Decoder)(nil))
mapKeyDecoder((*uint)(nil), (*uint64Decoder)(nil))
}
mapKeyDecoder((*int8)(nil), (*int8KeyDecoder)(nil))
mapKeyDecoder((*int16)(nil), (*int16KeyDecoder)(nil))
mapKeyDecoder((*int32)(nil), (*int32KeyDecoder)(nil))
mapKeyDecoder((*int64)(nil), (*int64KeyDecoder)(nil))
mapKeyDecoder((*uint8)(nil), (*uint8KeyDecoder)(nil))
mapKeyDecoder((*uint16)(nil), (*uint16KeyDecoder)(nil))
mapKeyDecoder((*uint32)(nil), (*uint32KeyDecoder)(nil))
mapKeyDecoder((*uint64)(nil), (*uint64KeyDecoder)(nil))
mapKeyDecoder((*int8)(nil), (*int8Decoder)(nil))
mapKeyDecoder((*int16)(nil), (*int16Decoder)(nil))
mapKeyDecoder((*int32)(nil), (*int32Decoder)(nil))
mapKeyDecoder((*int64)(nil), (*int64Decoder)(nil))
mapKeyDecoder((*uint8)(nil), (*uint8Decoder)(nil))
mapKeyDecoder((*uint16)(nil), (*uint16Decoder)(nil))
mapKeyDecoder((*uint32)(nil), (*uint32Decoder)(nil))
mapKeyDecoder((*uint64)(nil), (*uint64Decoder)(nil))
if unsafe.Sizeof(uintptr(0)) == 4 {
mapKeyDecoder((*uintptr)(nil), (*uint32KeyDecoder)(nil))
mapKeyDecoder((*uintptr)(nil), (*uint32Decoder)(nil))
} else {
mapKeyDecoder((*uintptr)(nil), (*uint64KeyDecoder)(nil))
mapKeyDecoder((*uintptr)(nil), (*uint64Decoder)(nil))
}
}

type DecOpts struct {
MapKey bool
Quoted bool
}

Expand Down
43 changes: 40 additions & 3 deletions val_decoder_native.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jzon

import (
"io"
"unsafe"
)

Expand Down Expand Up @@ -40,7 +41,7 @@ func (*boolDecoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) error {
type stringDecoder struct {
}

func (*stringDecoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) error {
func (*stringDecoder) Decode(ptr unsafe.Pointer, it *Iterator, opts *DecOpts) error {
c, _, err := it.nextToken()
if err != nil {
return err
Expand All @@ -52,8 +53,44 @@ func (*stringDecoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) error
if err != nil {
return err
}
*(*string)(ptr) = s
return nil
quoted := (opts != nil) && opts.Quoted
if !quoted {
*(*string)(ptr) = s
return nil
}
l := len(s)
if l < 2 {
// TODO: custom error
return BadQuotedStringError(s)
}
switch s[0] {
case 'n':
if s != "null" {
return BadQuotedStringError(s)
}
return nil
case '"':
if s[l-1] != '"' {
return BadQuotedStringError(s)
}
// borrow another iterator
subIt := it.decoder.NewIterator()
defer it.decoder.ReturnIterator(subIt)
subIt.ResetBytes(localStringToBytes(s))
subStr, err := subIt.ReadString()
if err != nil {
return BadQuotedStringError(s)
}
// check eof
_, _, err = subIt.nextToken()
if err != io.EOF {
return BadQuotedStringError(s)
}
*(*string)(ptr) = subStr
return nil
default:
return BadQuotedStringError(s)
}
case 'n':
it.head += 1
return it.expectBytes("ull")
Expand Down
80 changes: 73 additions & 7 deletions val_decoder_native_int.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func (*int8Decoder) Decode(ptr unsafe.Pointer, it *Iterator, opts *DecOpts) erro
it.head += 1
return it.expectBytes("ull")
}
quoted := (opts != nil) && opts.Quoted
quoted := (opts != nil) && (opts.Quoted || opts.MapKey)
if quoted {
if c != '"' {
return UnexpectedByteError{got: c, exp: '"'}
Expand Down Expand Up @@ -51,7 +51,7 @@ func (*int8Decoder) Decode(ptr unsafe.Pointer, it *Iterator, opts *DecOpts) erro
type int16Decoder struct {
}

func (*int16Decoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) error {
func (*int16Decoder) Decode(ptr unsafe.Pointer, it *Iterator, opts *DecOpts) error {
c, _, err := it.nextToken()
if err != nil {
return err
Expand All @@ -60,10 +60,32 @@ func (*int16Decoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) error
it.head += 1
return it.expectBytes("ull")
}
i, err := it.ReadInt16()
quoted := (opts != nil) && (opts.Quoted || opts.MapKey)
if quoted {
if c != '"' {
return UnexpectedByteError{got: c, exp: '"'}
}
it.head += 1
c, err = it.nextByte()
if err != nil {
return err
}
}
it.head += 1
i, err := it.readInt16(c)
if err != nil {
return err
}
if quoted {
c, err = it.nextByte()
if err != nil {
return err
}
if c != '"' {
return UnexpectedByteError{got: c, exp: '"'}
}
it.head += 1
}
*(*int16)(ptr) = i
return nil
}
Expand All @@ -72,7 +94,7 @@ func (*int16Decoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) error
type int32Decoder struct {
}

func (*int32Decoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) error {
func (*int32Decoder) Decode(ptr unsafe.Pointer, it *Iterator, opts *DecOpts) error {
c, _, err := it.nextToken()
if err != nil {
return err
Expand All @@ -81,10 +103,32 @@ func (*int32Decoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) error
it.head += 1
return it.expectBytes("ull")
}
i, err := it.ReadInt32()
quoted := (opts != nil) && (opts.Quoted || opts.MapKey)
if quoted {
if c != '"' {
return UnexpectedByteError{got: c, exp: '"'}
}
it.head += 1
c, err = it.nextByte()
if err != nil {
return err
}
}
it.head += 1
i, err := it.readInt32(c)
if err != nil {
return err
}
if quoted {
c, err = it.nextByte()
if err != nil {
return err
}
if c != '"' {
return UnexpectedByteError{got: c, exp: '"'}
}
it.head += 1
}
*(*int32)(ptr) = i
return nil
}
Expand All @@ -93,7 +137,7 @@ func (*int32Decoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) error
type int64Decoder struct {
}

func (*int64Decoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) error {
func (*int64Decoder) Decode(ptr unsafe.Pointer, it *Iterator, opts *DecOpts) error {
c, _, err := it.nextToken()
if err != nil {
return err
Expand All @@ -102,10 +146,32 @@ func (*int64Decoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) error
it.head += 1
return it.expectBytes("ull")
}
i, err := it.ReadInt64()
quoted := (opts != nil) && (opts.Quoted || opts.MapKey)
if quoted {
if c != '"' {
return UnexpectedByteError{got: c, exp: '"'}
}
it.head += 1
c, err = it.nextByte()
if err != nil {
return err
}
}
it.head += 1
i, err := it.readInt64(c)
if err != nil {
return err
}
if quoted {
c, err = it.nextByte()
if err != nil {
return err
}
if c != '"' {
return UnexpectedByteError{got: c, exp: '"'}
}
it.head += 1
}
*(*int64)(ptr) = i
return nil
}
7 changes: 6 additions & 1 deletion val_decoder_native_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ func (dec *mapDecoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) erro
}
for {
key := unsafe_New(dec.keyRType)
if err = dec.keyDec.Decode(key, it, nil); err != nil {
opt := DecOpts{
MapKey: true,
}
if err = dec.keyDec.Decode(key, it, &opt); err != nil {
return err
}
c, _, err = it.nextToken()
Expand Down Expand Up @@ -118,6 +121,7 @@ func (dec *mapDecoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) erro
}
}

/*
// key decoders
type stringKeyDecoder struct {
}
Expand Down Expand Up @@ -276,3 +280,4 @@ func (*uint64KeyDecoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) er
*(*uint64)(ptr) = i
return nil
}
*/
Loading

0 comments on commit 0a8afe3

Please sign in to comment.