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 (
|
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...)
|
||||||
|
}
|
||||||
18
compat.go
18
compat.go
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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`
|
`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...)
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue