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:
parent
32877b6d27
commit
cfa4fe1736
4 changed files with 50 additions and 34 deletions
18
api.go
18
api.go
|
|
@ -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
|
||||
|
|
@ -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
compat.go
18
compat.go
|
|
@ -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)
|
||||
|
|
@ -55,7 +55,7 @@ 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, "", "")
|
||||
}
|
||||
|
|
@ -63,13 +63,13 @@ func (cfg *frozenConfig) Marshal(val interface{}) ([]byte, error) {
|
|||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ func (cfg *frozenConfig) MarshalIndent(val interface{}, prefix, indent string) (
|
|||
}
|
||||
|
||||
// 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 {
|
||||
|
|
@ -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)
|
||||
|
|
@ -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()
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
sonic.go
33
sonic.go
|
|
@ -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`
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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...)
|
||||
}
|
||||
Loading…
Reference in a new issue