summaryrefslogtreecommitdiff
path: root/vendor/github.com/bytedance/sonic/ast/search.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/bytedance/sonic/ast/search.go')
-rw-r--r--vendor/github.com/bytedance/sonic/ast/search.go50
1 files changed, 50 insertions, 0 deletions
diff --git a/vendor/github.com/bytedance/sonic/ast/search.go b/vendor/github.com/bytedance/sonic/ast/search.go
index bb6fceaa7..7108e7ea6 100644
--- a/vendor/github.com/bytedance/sonic/ast/search.go
+++ b/vendor/github.com/bytedance/sonic/ast/search.go
@@ -16,6 +16,11 @@
package ast
+import (
+ `github.com/bytedance/sonic/internal/rt`
+ `github.com/bytedance/sonic/internal/native/types`
+)
+
type Searcher struct {
parser Parser
}
@@ -28,3 +33,48 @@ func NewSearcher(str string) *Searcher {
},
}
}
+
+// GetByPathCopy search in depth from top json and returns a **Copied** json node at the path location
+func (self *Searcher) GetByPathCopy(path ...interface{}) (Node, error) {
+ return self.getByPath(true, path...)
+}
+
+// GetByPathNoCopy search in depth from top json and returns a **Referenced** json node at the path location
+//
+// WARN: this search directly refer partial json from top json, which has faster speed,
+// may consumes more memory.
+func (self *Searcher) GetByPath(path ...interface{}) (Node, error) {
+ return self.getByPath(false, path...)
+}
+
+func (self *Searcher) getByPath(copystring bool, path ...interface{}) (Node, error) {
+ var err types.ParsingError
+ var start int
+
+ self.parser.p = 0
+ start, err = self.parser.getByPath(path...)
+ if err != 0 {
+ // for compatibility with old version
+ if err == types.ERR_NOT_FOUND {
+ return Node{}, ErrNotExist
+ }
+ if err == types.ERR_UNSUPPORT_TYPE {
+ panic("path must be either int(>=0) or string")
+ }
+ return Node{}, self.parser.syntaxError(err)
+ }
+
+ t := switchRawType(self.parser.s[start])
+ if t == _V_NONE {
+ return Node{}, self.parser.ExportError(err)
+ }
+
+ // copy string to reducing memory usage
+ var raw string
+ if copystring {
+ raw = rt.Mem2Str([]byte(self.parser.s[start:self.parser.p]))
+ } else {
+ raw = self.parser.s[start:self.parser.p]
+ }
+ return newRawNode(raw, t), nil
+}