Skip to content

Commit

Permalink
Merge pull request #27 from shamaton/not_using_unsafe
Browse files Browse the repository at this point in the history
Not using unsafe
  • Loading branch information
shamaton authored Aug 5, 2021
2 parents e325f82 + 48efb60 commit a5e4750
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 16 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ go get -u github.com/shamaton/msgpack
package main

import (
"github.com/shamaton/msgpack"
"github.com/shamaton/msgpack/v2"
)

func main() {
Expand Down
4 changes: 2 additions & 2 deletions internal/decoding/decoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func (d *decoder) decode(rv reflect.Value, offset int) (int, error) {
if err != nil {
return 0, err
}
bs, offset := d.asStringByte(offset, l, k)
bs, offset := d.asStringByteByLength(offset, l, k)
rv.SetBytes(bs)
return offset, nil
}
Expand Down Expand Up @@ -201,7 +201,7 @@ func (d *decoder) decode(rv reflect.Value, offset int) (int, error) {
if l > rv.Len() {
return 0, fmt.Errorf("%v len is %d, but msgpack has %d elements", rv.Type(), rv.Len(), l)
}
bs, offset := d.asStringByte(offset, l, k)
bs, offset := d.asStringByteByLength(offset, l, k)
for i, b := range bs {
rv.Index(i).SetUint(uint64(b))
}
Expand Down
18 changes: 13 additions & 5 deletions internal/decoding/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package decoding
import (
"encoding/binary"
"reflect"
"unsafe"

"github.com/shamaton/msgpack/v2/def"
)
Expand Down Expand Up @@ -42,15 +41,24 @@ func (d *decoder) stringByteLength(offset int, k reflect.Kind) (int, int, error)
}

func (d *decoder) asString(offset int, k reflect.Kind) (string, int, error) {
l, offset, err := d.stringByteLength(offset, k)
bs, offset, err := d.asStringByte(offset, k)
if err != nil {
return emptyString, 0, err
}
bs, offset := d.asStringByte(offset, l, k)
return *(*string)(unsafe.Pointer(&bs)), offset, nil
return string(bs), offset, nil
}

func (d *decoder) asStringByte(offset int, k reflect.Kind) ([]byte, int, error) {
l, offset, err := d.stringByteLength(offset, k)
if err != nil {
return emptyBytes, 0, err
}

b, o := d.asStringByteByLength(offset, l, k)
return b, o, nil
}

func (d *decoder) asStringByte(offset int, l int, k reflect.Kind) ([]byte, int) {
func (d *decoder) asStringByteByLength(offset int, l int, k reflect.Kind) ([]byte, int) {
if l < 1 {
return emptyBytes, offset
}
Expand Down
36 changes: 28 additions & 8 deletions internal/decoding/struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import (
)

type structCacheTypeMap struct {
m map[string]int
keys [][]byte
indexes []int
}

type structCacheTypeArray struct {
Expand Down Expand Up @@ -95,28 +96,47 @@ func (d *decoder) setStructFromMap(rv reflect.Value, offset int, k reflect.Kind)
return 0, err
}

// find or create reference
var sctm *structCacheTypeMap
cache, cacheFind := mapSCTM.Load(rv.Type())
if !cacheFind {
sctm = &structCacheTypeMap{m: map[string]int{}}
sctm = &structCacheTypeMap{}
for i := 0; i < rv.NumField(); i++ {
if ok, name := d.CheckField(rv.Type().Field(i)); ok {
sctm.m[name] = i
sctm.keys = append(sctm.keys, []byte(name))
sctm.indexes = append(sctm.indexes, i)
}
}
mapSCTM.Store(rv.Type(), sctm)
} else {
sctm = cache.(*structCacheTypeMap)
}
// set value if string correct

for i := 0; i < l; i++ {
key, o2, err := d.asString(o, k)
dataKey, o2, err := d.asStringByte(o, k)
if err != nil {
return 0, err
}
if _, ok := sctm.m[key]; ok {
o2, err = d.decode(rv.Field(sctm.m[key]), o2)

fieldIndex := -1
for keyIndex, keyBytes := range sctm.keys {
if len(keyBytes) != len(dataKey) {
continue
}

fieldIndex = sctm.indexes[keyIndex]
for dataIndex := range dataKey {
if dataKey[dataIndex] != keyBytes[dataIndex] {
fieldIndex = -1
break
}
}
if fieldIndex >= 0 {
break
}
}

if fieldIndex >= 0 {
o2, err = d.decode(rv.Field(fieldIndex), o2)
if err != nil {
return 0, err
}
Expand Down

0 comments on commit a5e4750

Please sign in to comment.