mirror of https://github.com/tidwall/gjson.git
bytes substring optimization
This commit is contained in:
parent
124a25db9e
commit
b39aa6075f
26
gjson.go
26
gjson.go
|
@ -2,6 +2,7 @@
|
|||
package gjson
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
|
||||
|
@ -1140,9 +1141,28 @@ func GetBytes(json []byte, path string) Result {
|
|||
if json != nil {
|
||||
// unsafe cast to string
|
||||
result = Get(*(*string)(unsafe.Pointer(&json)), path)
|
||||
// copy of string data for safety
|
||||
result.Raw = string(*(*[]byte)(unsafe.Pointer(&result.Raw)))
|
||||
result.Str = string(*(*[]byte)(unsafe.Pointer(&result.Str)))
|
||||
// copy of string data for safety.
|
||||
rawh := *(*reflect.SliceHeader)(unsafe.Pointer(&result.Raw))
|
||||
strh := *(*reflect.SliceHeader)(unsafe.Pointer(&result.Str))
|
||||
if strh.Data == 0 {
|
||||
if rawh.Data == 0 {
|
||||
result.Raw = ""
|
||||
} else {
|
||||
result.Raw = string(*(*[]byte)(unsafe.Pointer(&result.Raw)))
|
||||
}
|
||||
result.Str = ""
|
||||
} else if rawh.Data == 0 {
|
||||
result.Raw = ""
|
||||
result.Str = string(*(*[]byte)(unsafe.Pointer(&result.Str)))
|
||||
} else if strh.Data >= rawh.Data && strh.Len <= rawh.Len {
|
||||
// Str is a substring of Raw.
|
||||
result.Raw = string(*(*[]byte)(unsafe.Pointer(&result.Raw)))
|
||||
start := int(strh.Data - rawh.Data)
|
||||
result.Str = result.Raw[start : start+strh.Len]
|
||||
} else {
|
||||
result.Raw = string(*(*[]byte)(unsafe.Pointer(&result.Raw)))
|
||||
result.Str = string(*(*[]byte)(unsafe.Pointer(&result.Str)))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -128,11 +128,15 @@ var basicJSON = `{"age":100, "name":{"here":"B\\\"R"},
|
|||
var basicJSONB = []byte(basicJSON)
|
||||
|
||||
func TestByteSafety(t *testing.T) {
|
||||
jsonb := []byte(`{"name":"Janet"}`)
|
||||
jsonb := []byte(`{"name":"Janet","age":38}`)
|
||||
mtok := GetBytes(jsonb, "name")
|
||||
if mtok.String() != "Janet" {
|
||||
t.Fatalf("expected %v, got %v", "Jason", mtok.String())
|
||||
}
|
||||
mtok2 := GetBytes(jsonb, "age")
|
||||
if mtok2.Raw != "38" {
|
||||
t.Fatalf("expected %v, got %v", "Jason", mtok2.Raw)
|
||||
}
|
||||
jsonb[9] = 'T'
|
||||
jsonb[12] = 'd'
|
||||
jsonb[13] = 'y'
|
||||
|
|
Loading…
Reference in New Issue