Skip to content

Commit

Permalink
feat: add Get() API on not-amd64 envs (#350)
Browse files Browse the repository at this point in the history
  • Loading branch information
AsterDY authored Jan 13, 2023
1 parent 32877b6 commit cfa4fe1
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 34 deletions.
18 changes: 18 additions & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package sonic

import (
`io`

`github.com/bytedance/sonic/ast`
)

// Config is a combination of sonic/encoder.Options and sonic/decoder.Options
Expand Down Expand Up @@ -161,3 +163,19 @@ func Unmarshal(buf []byte, val interface{}) error {
func UnmarshalString(buf string, val interface{}) error {
return ConfigDefault.UnmarshalFromString(buf, val)
}

// Get searches the given path json,
// and returns its representing ast.Node.
//
// Each path arg must be integer or string:
// - Integer means searching current node as array
// - String means searching current node as object
func Get(src []byte, path ...interface{}) (ast.Node, error) {
return GetFromString(string(src), path...)
}

// GetFromString is same with Get except src is string,
// which can reduce unnecessary memory copy.
func GetFromString(src string, path ...interface{}) (ast.Node, error) {
return ast.NewSearcher(src).GetByPath(path...)
}
18 changes: 9 additions & 9 deletions compat.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (cfg Config) Froze() API {
return api
}

func (cfg *frozenConfig) marshalOptions(val interface{}, prefix, indent string) ([]byte, error) {
func (cfg frozenConfig) marshalOptions(val interface{}, prefix, indent string) ([]byte, error) {
w := bytes.NewBuffer([]byte{})
enc := json.NewEncoder(w)
enc.SetEscapeHTML(cfg.EscapeHTML)
Expand All @@ -55,29 +55,29 @@ func (cfg *frozenConfig) marshalOptions(val interface{}, prefix, indent string)
}

// Marshal is implemented by sonic
func (cfg *frozenConfig) Marshal(val interface{}) ([]byte, error) {
func (cfg frozenConfig) Marshal(val interface{}) ([]byte, error) {
if !cfg.EscapeHTML {
return cfg.marshalOptions(val, "", "")
}
return json.Marshal(val)
}

// MarshalToString is implemented by sonic
func (cfg *frozenConfig) MarshalToString(val interface{}) (string, error) {
func (cfg frozenConfig) MarshalToString(val interface{}) (string, error) {
out, err := cfg.Marshal(val)
return string(out), err
}

// MarshalIndent is implemented by sonic
func (cfg *frozenConfig) MarshalIndent(val interface{}, prefix, indent string) ([]byte, error) {
func (cfg frozenConfig) MarshalIndent(val interface{}, prefix, indent string) ([]byte, error) {
if !cfg.EscapeHTML {
return cfg.marshalOptions(val, prefix, indent)
}
return json.MarshalIndent(val, prefix, indent)
}

// UnmarshalFromString is implemented by sonic
func (cfg *frozenConfig) UnmarshalFromString(buf string, val interface{}) error {
func (cfg frozenConfig) UnmarshalFromString(buf string, val interface{}) error {
r := bytes.NewBufferString(buf)
dec := json.NewDecoder(r)
if cfg.UseNumber {
Expand All @@ -90,12 +90,12 @@ func (cfg *frozenConfig) UnmarshalFromString(buf string, val interface{}) error
}

// Unmarshal is implemented by sonic
func (cfg *frozenConfig) Unmarshal(buf []byte, val interface{}) error {
func (cfg frozenConfig) Unmarshal(buf []byte, val interface{}) error {
return cfg.UnmarshalFromString(string(buf), val)
}

// NewEncoder is implemented by sonic
func (cfg *frozenConfig) NewEncoder(writer io.Writer) Encoder {
func (cfg frozenConfig) NewEncoder(writer io.Writer) Encoder {
enc := json.NewEncoder(writer)
if !cfg.EscapeHTML {
enc.SetEscapeHTML(cfg.EscapeHTML)
Expand All @@ -104,7 +104,7 @@ func (cfg *frozenConfig) NewEncoder(writer io.Writer) Encoder {
}

// NewDecoder is implemented by sonic
func (cfg *frozenConfig) NewDecoder(reader io.Reader) Decoder {
func (cfg frozenConfig) NewDecoder(reader io.Reader) Decoder {
dec := json.NewDecoder(reader)
if cfg.UseNumber {
dec.UseNumber()
Expand All @@ -116,7 +116,7 @@ func (cfg *frozenConfig) NewDecoder(reader io.Reader) Decoder {
}

// Valid is implemented by sonic
func (cfg *frozenConfig) Valid(data []byte) bool {
func (cfg frozenConfig) Valid(data []byte) bool {
return json.Valid(data)
}

Expand Down
15 changes: 15 additions & 0 deletions compat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,18 @@ func TestPretouch(t *testing.T) {
}
}

func TestGet(t *testing.T) {
var data = `{"a":"b"}`
r, err := GetFromString(data, "a")
if err != nil {
t.Fatal(err)
}
v, err := r.String()
if err != nil {
t.Fatal(err)
}
if v != "b" {
t.Fatal(v)
}
}

33 changes: 8 additions & 25 deletions sonic.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
`io`
`reflect`

`github.com/bytedance/sonic/ast`
`github.com/bytedance/sonic/decoder`
`github.com/bytedance/sonic/encoder`
`github.com/bytedance/sonic/option`
Expand Down Expand Up @@ -99,23 +98,23 @@ func (cfg Config) Froze() API {
}

// Marshal is implemented by sonic
func (cfg *frozenConfig) Marshal(val interface{}) ([]byte, error) {
func (cfg frozenConfig) Marshal(val interface{}) ([]byte, error) {
return encoder.Encode(val, cfg.encoderOpts)
}

// MarshalToString is implemented by sonic
func (cfg *frozenConfig) MarshalToString(val interface{}) (string, error) {
func (cfg frozenConfig) MarshalToString(val interface{}) (string, error) {
buf, err := encoder.Encode(val, cfg.encoderOpts)
return rt.Mem2Str(buf), err
}

// MarshalIndent is implemented by sonic
func (cfg *frozenConfig) MarshalIndent(val interface{}, prefix, indent string) ([]byte, error) {
func (cfg frozenConfig) MarshalIndent(val interface{}, prefix, indent string) ([]byte, error) {
return encoder.EncodeIndented(val, prefix, indent, cfg.encoderOpts)
}

// UnmarshalFromString is implemented by sonic
func (cfg *frozenConfig) UnmarshalFromString(buf string, val interface{}) error {
func (cfg frozenConfig) UnmarshalFromString(buf string, val interface{}) error {
dec := decoder.NewDecoder(buf)
dec.SetOptions(cfg.decoderOpts)
err := dec.Decode(val)
Expand All @@ -129,26 +128,26 @@ func (cfg *frozenConfig) UnmarshalFromString(buf string, val interface{}) error
}

// Unmarshal is implemented by sonic
func (cfg *frozenConfig) Unmarshal(buf []byte, val interface{}) error {
func (cfg frozenConfig) Unmarshal(buf []byte, val interface{}) error {
return cfg.UnmarshalFromString(string(buf), val)
}

// NewEncoder is implemented by sonic
func (cfg *frozenConfig) NewEncoder(writer io.Writer) Encoder {
func (cfg frozenConfig) NewEncoder(writer io.Writer) Encoder {
enc := encoder.NewStreamEncoder(writer)
enc.Opts = cfg.encoderOpts
return enc
}

// NewDecoder is implemented by sonic
func (cfg *frozenConfig) NewDecoder(reader io.Reader) Decoder {
func (cfg frozenConfig) NewDecoder(reader io.Reader) Decoder {
dec := decoder.NewStreamDecoder(reader)
dec.SetOptions(cfg.decoderOpts)
return dec
}

// Valid is implemented by sonic
func (cfg *frozenConfig) Valid(data []byte) bool {
func (cfg frozenConfig) Valid(data []byte) bool {
ok, _ := encoder.Valid(data)
return ok
}
Expand Down Expand Up @@ -179,19 +178,3 @@ func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
}
return nil
}

// Get searches the given path json,
// and returns its representing ast.Node.
//
// Each path arg must be integer or string:
// - Integer means searching current node as array
// - String means searching current node as object
func Get(src []byte, path ...interface{}) (ast.Node, error) {
return GetFromString(string(src), path...)
}

// GetFromString is same with Get except src is string,
// which can reduce unnecessary memory copy.
func GetFromString(src string, path ...interface{}) (ast.Node, error) {
return ast.NewSearcher(src).GetByPath(path...)
}

0 comments on commit cfa4fe1

Please sign in to comment.