2
0
Fork 0
mirror of https://github.com/ii64/sonic.git synced 2026-06-21 00:46:43 +08:00

feat: add Get() API on not-amd64 envs (#350)

This commit is contained in:
Yi Duan 2023-01-13 11:34:20 +08:00 committed by GitHub
parent 32877b6d27
commit cfa4fe1736
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 34 deletions

18
api.go
View file

@ -18,6 +18,8 @@ package sonic
import ( import (
`io` `io`
`github.com/bytedance/sonic/ast`
) )
// Config is a combination of sonic/encoder.Options and sonic/decoder.Options // Config is a combination of sonic/encoder.Options and sonic/decoder.Options
@ -161,3 +163,19 @@ func Unmarshal(buf []byte, val interface{}) error {
func UnmarshalString(buf string, val interface{}) error { func UnmarshalString(buf string, val interface{}) error {
return ConfigDefault.UnmarshalFromString(buf, val) 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...)
}

View file

@ -38,7 +38,7 @@ func (cfg Config) Froze() API {
return 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{}) w := bytes.NewBuffer([]byte{})
enc := json.NewEncoder(w) enc := json.NewEncoder(w)
enc.SetEscapeHTML(cfg.EscapeHTML) enc.SetEscapeHTML(cfg.EscapeHTML)
@ -55,7 +55,7 @@ func (cfg *frozenConfig) marshalOptions(val interface{}, prefix, indent string)
} }
// Marshal is implemented by sonic // Marshal is implemented by sonic
func (cfg *frozenConfig) Marshal(val interface{}) ([]byte, error) { func (cfg frozenConfig) Marshal(val interface{}) ([]byte, error) {
if !cfg.EscapeHTML { if !cfg.EscapeHTML {
return cfg.marshalOptions(val, "", "") return cfg.marshalOptions(val, "", "")
} }
@ -63,13 +63,13 @@ func (cfg *frozenConfig) Marshal(val interface{}) ([]byte, error) {
} }
// MarshalToString is implemented by sonic // 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) out, err := cfg.Marshal(val)
return string(out), err return string(out), err
} }
// MarshalIndent is implemented by sonic // 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 { if !cfg.EscapeHTML {
return cfg.marshalOptions(val, prefix, indent) return cfg.marshalOptions(val, prefix, indent)
} }
@ -77,7 +77,7 @@ func (cfg *frozenConfig) MarshalIndent(val interface{}, prefix, indent string) (
} }
// UnmarshalFromString is implemented by sonic // 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) r := bytes.NewBufferString(buf)
dec := json.NewDecoder(r) dec := json.NewDecoder(r)
if cfg.UseNumber { if cfg.UseNumber {
@ -90,12 +90,12 @@ func (cfg *frozenConfig) UnmarshalFromString(buf string, val interface{}) error
} }
// Unmarshal is implemented by sonic // 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) return cfg.UnmarshalFromString(string(buf), val)
} }
// NewEncoder is implemented by sonic // 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) enc := json.NewEncoder(writer)
if !cfg.EscapeHTML { if !cfg.EscapeHTML {
enc.SetEscapeHTML(cfg.EscapeHTML) enc.SetEscapeHTML(cfg.EscapeHTML)
@ -104,7 +104,7 @@ func (cfg *frozenConfig) NewEncoder(writer io.Writer) Encoder {
} }
// NewDecoder is implemented by sonic // 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) dec := json.NewDecoder(reader)
if cfg.UseNumber { if cfg.UseNumber {
dec.UseNumber() dec.UseNumber()
@ -116,7 +116,7 @@ func (cfg *frozenConfig) NewDecoder(reader io.Reader) Decoder {
} }
// Valid is implemented by sonic // Valid is implemented by sonic
func (cfg *frozenConfig) Valid(data []byte) bool { func (cfg frozenConfig) Valid(data []byte) bool {
return json.Valid(data) return json.Valid(data)
} }

View file

@ -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)
}
}

View file

@ -23,7 +23,6 @@ import (
`io` `io`
`reflect` `reflect`
`github.com/bytedance/sonic/ast`
`github.com/bytedance/sonic/decoder` `github.com/bytedance/sonic/decoder`
`github.com/bytedance/sonic/encoder` `github.com/bytedance/sonic/encoder`
`github.com/bytedance/sonic/option` `github.com/bytedance/sonic/option`
@ -99,23 +98,23 @@ func (cfg Config) Froze() API {
} }
// Marshal is implemented by sonic // 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) return encoder.Encode(val, cfg.encoderOpts)
} }
// MarshalToString is implemented by sonic // 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) buf, err := encoder.Encode(val, cfg.encoderOpts)
return rt.Mem2Str(buf), err return rt.Mem2Str(buf), err
} }
// MarshalIndent is implemented by sonic // 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) return encoder.EncodeIndented(val, prefix, indent, cfg.encoderOpts)
} }
// UnmarshalFromString is implemented by sonic // 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 := decoder.NewDecoder(buf)
dec.SetOptions(cfg.decoderOpts) dec.SetOptions(cfg.decoderOpts)
err := dec.Decode(val) err := dec.Decode(val)
@ -129,26 +128,26 @@ func (cfg *frozenConfig) UnmarshalFromString(buf string, val interface{}) error
} }
// Unmarshal is implemented by sonic // 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) return cfg.UnmarshalFromString(string(buf), val)
} }
// NewEncoder is implemented by sonic // 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 := encoder.NewStreamEncoder(writer)
enc.Opts = cfg.encoderOpts enc.Opts = cfg.encoderOpts
return enc return enc
} }
// NewDecoder is implemented by sonic // 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 := decoder.NewStreamDecoder(reader)
dec.SetOptions(cfg.decoderOpts) dec.SetOptions(cfg.decoderOpts)
return dec return dec
} }
// Valid is implemented by sonic // Valid is implemented by sonic
func (cfg *frozenConfig) Valid(data []byte) bool { func (cfg frozenConfig) Valid(data []byte) bool {
ok, _ := encoder.Valid(data) ok, _ := encoder.Valid(data)
return ok return ok
} }
@ -179,19 +178,3 @@ func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
} }
return nil 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...)
}