Skip to content

Commit

Permalink
[+] feat: Support GetBytes(), SetBytes(), Bytes()
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew-M-C committed Apr 21, 2021
1 parent 51d1f9e commit 33803d2
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 23 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Coverage file
cover.html
3 changes: 0 additions & 3 deletions append.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,6 @@ func (apd *Append) InTheBeginning(params ...interface{}) (*V, error) {
if nil == v || v.valueType == jsonparser.NotExist {
return nil, ErrValueUninitialized
}
if nil == c || c.valueType == jsonparser.NotExist {
return nil, ErrValueUninitialized
}

// this is the last iteration
paramCount := len(params)
Expand Down
14 changes: 14 additions & 0 deletions get.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,20 @@ func (v *V) getInCurrValue(param interface{}) (*V, error) {
}
}

// GetBytes is similar with v, err := Get(...); v.Bytes(). But if error occurs or Base64 decode error, returns error.
//
// GetBytes 类似于 v, err := Get(...); v.Bytes(),但如果查询中发生错误,或者 base64 解码错误,则返回错误。
func (v *V) GetBytes(firstParam interface{}, otherParams ...interface{}) ([]byte, error) {
ret, err := v.Get(firstParam, otherParams...)
if err != nil {
return nil, err
}
if ret.valueType != jsonparser.String {
return nil, ErrTypeNotMatch
}
return b64.DecodeString(ret.valueStr)
}

// GetString is equalivent to v, err := Get(...); v.String(). If error occurs, returns "".
//
// GetString 等效于 v, err := Get(...); v.String()。如果发生错误,则返回 ""。
Expand Down
6 changes: 6 additions & 0 deletions get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ func TestMiscError(t *testing.T) {
shouldError(err)
err = v.GetNull("not exist")
shouldError(err)

// GetBytes
_, err = v.GetBytes("string")
shouldError(err)
_, err = v.GetBytes("array")
shouldError(err)
}

}
3 changes: 0 additions & 3 deletions insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,6 @@ func (ins *Insert) After(firstParam interface{}, otherParams ...interface{}) (*V
if nil == v || v.valueType == jsonparser.NotExist {
return nil, ErrValueUninitialized
}
if nil == c || c.valueType == jsonparser.NotExist {
return nil, ErrValueUninitialized
}

// this is the last iteration
paramCount := len(otherParams)
Expand Down
2 changes: 1 addition & 1 deletion insert_append_delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ func TestMiscDeleteError(t *testing.T) {

{
var err error
raw := `{"hello":"world","object":{"hello":"world","object":{"int":123456}},"array":[123456]}`
raw := `{"Hello":"world","object":{"hello":"world","object":{"int":123456}},"array":[123456]}`
v, _ := UnmarshalString(raw)

// param error
Expand Down
23 changes: 23 additions & 0 deletions jsonvalue.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ package jsonvalue
import (
"bytes"
"container/list"
"encoding/base64"
"fmt"
"reflect"
"strings"
Expand All @@ -45,6 +46,13 @@ import (
"github.com/buger/jsonparser"
)

var (
b64 = base64.StdEncoding
)

// test:
// go test -v -failfast -cover -coverprofile ./cover.out && go tool cover -html=./cover.out -o ./cover.html && open ./cover.html

// V is the main type of jsonvalue, representing a JSON value.
//
// V 是 jsonvalue 的主类型,表示一个 JSON 值。
Expand Down Expand Up @@ -646,6 +654,21 @@ func (v *V) Float32() float32 {
return float32(v.num.f64)
}

// Bytes returns represented binary data which is encoede as Base64 string. []byte{} would be returned if value is
// not a string type or base64 decode failed.
//
// Bytes 返回以 Base64 编码在 string 类型中的二进制数据。如果当前值不是字符串类型,或者是 base64 编码失败,则返回 []byte{}。
func (v *V) Bytes() []byte {
if v.valueType != jsonparser.String {
return []byte{}
}
b, err := b64.DecodeString(v.valueStr)
if err != nil {
return []byte{}
}
return b
}

// String returns represented string value or the description for the jsonvalue.V instance if it is not a string.
//
// String 返回 string 类型值。如果当前值不是字符串类型,则返回当前 *V 类型的描述说明。
Expand Down
8 changes: 8 additions & 0 deletions set.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ func (v *V) SetString(s string) *Set {
return v.Set(NewString(s))
}

// SetBytes is equivalent to Set(NewString(base64.StdEncoding.EncodeToString(b)))
//
// SetBytes 等效于 Set(NewString(base64.StdEncoding.EncodeToString(b)))
func (v *V) SetBytes(b []byte) *Set {
s := b64.EncodeToString(b)
return v.SetString(s)
}

// SetBool is equivalent to Set(jsonvalue.NewBool(b))
//
// SetBool 等效于 Set(jsonvalue.NewBool(b))
Expand Down
27 changes: 26 additions & 1 deletion set_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package jsonvalue

import (
"bytes"
"encoding/hex"
"testing"
)

Expand Down Expand Up @@ -176,12 +178,35 @@ func TestSetMisc(t *testing.T) {
checkErr()
check(a.IsArray() && a.Len() == 1)

topic = "GetBytes"
s := "1234567890"
data, _ := hex.DecodeString(s)
v.SetString(s).At("string")
v.SetBytes(data).At("bytes")
dataRead, err := v.GetBytes("bytes")
checkErr()
t.Logf("set data: %s", hex.EncodeToString(data))
t.Logf("Got data: %s", hex.EncodeToString(dataRead))
check(bytes.Equal(data, dataRead))
_, err = a.GetBytes("string")
check(err != nil)

topic = "Bytes"
child, _ := v.Get("string")
t.Logf("Get: %v", child)
check(len(child.Bytes()) == 0)
child, _ = v.Get("data")
t.Logf("Get: %v", child)
check(len(child.Bytes()) == 0)
child, _ = v.Get("bytes")
check(bytes.Equal(data, child.Bytes()))

topic = "SetString in array of a object"
a = NewArray()
a.AppendObject().InTheBeginning()
_, err = a.SetString("hello").At(0)
checkErr()
s, err := a.GetString(0)
s, err = a.GetString(0)
checkErr()
check(s == "hello")

Expand Down
26 changes: 11 additions & 15 deletions sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,44 +81,41 @@ func (v *sortArrayV) Swap(i, j int) {
//
// Key 是 KeyPath 类型的成员
type Key struct {
v interface{}
s string
i int
}

func intKey(i int) Key {
return Key{v: i}
return Key{i: i}
}

func stringKey(s string) Key {
return Key{v: s}
return Key{s: s}
}

// String returns string value of a key
//
// String 返回当前键值对的键的描述
func (k *Key) String() string {
if s, ok := k.v.(string); ok {
return s
if k.s != "" {
return k.s
}
if i, ok := k.v.(int); ok {
return strconv.Itoa(i)
}
return ""
return strconv.Itoa(k.i)
}

// IsString tells if current key is a string, which indicates a child of an object.
//
// IsString 判断当前的键是不是一个 string 类型,如果是的话,那么它是一个 object JSON 的子成员。
func (k *Key) IsString() bool {
_, ok := k.v.(string)
return ok
return k.s != ""
}

// Int returns int value of a key.
//
// Int 返回当前键值对的 int 值。
func (k *Key) Int() int {
if i, ok := k.v.(int); ok {
return i
if k.s == "" {
return k.i
}
return 0
}
Expand All @@ -127,8 +124,7 @@ func (k *Key) Int() int {
//
// IsInt 判断当前的键是不是一个整型类型,如果是的话,那么它是一个 array JSON 的子成员。
func (k *Key) IsInt() bool {
_, ok := k.v.(int)
return ok
return k.s == ""
}

// KeyPath identifies a full path of keys of object in jsonvalue.
Expand Down

0 comments on commit 33803d2

Please sign in to comment.