...

Source file src/github.com/bytedance/sonic/ast/search.go

Documentation: github.com/bytedance/sonic/ast

     1  /*
     2   * Copyright 2021 ByteDance Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package ast
    18  
    19  import (
    20      `github.com/bytedance/sonic/internal/rt`
    21      `github.com/bytedance/sonic/internal/native/types`
    22  )
    23  
    24  type Searcher struct {
    25      parser Parser
    26  }
    27  
    28  func NewSearcher(str string) *Searcher {
    29      return &Searcher{
    30          parser: Parser{
    31              s:      str,
    32              noLazy: false,
    33          },
    34      }
    35  }
    36  
    37  // GetByPathCopy search in depth from top json and returns a **Copied** json node at the path location
    38  func (self *Searcher) GetByPathCopy(path ...interface{}) (Node, error) {
    39      return self.getByPath(true, path...)
    40  }
    41  
    42  // GetByPathNoCopy search in depth from top json and returns a **Referenced** json node at the path location
    43  //
    44  // WARN: this search directly refer partial json from top json, which has faster speed,
    45  // may consumes more memory.
    46  func (self *Searcher) GetByPath(path ...interface{}) (Node, error) {
    47      return self.getByPath(false, path...)
    48  }
    49  
    50  func (self *Searcher) getByPath(copystring bool, path ...interface{}) (Node, error) {
    51      var err types.ParsingError
    52      var start int
    53  
    54      self.parser.p = 0
    55      start, err = self.parser.getByPath(path...)
    56      if err != 0 {
    57          // for compatibility with old version
    58          if err == types.ERR_NOT_FOUND {
    59              return Node{}, ErrNotExist
    60          }
    61          if err == types.ERR_UNSUPPORT_TYPE {
    62              panic("path must be either int(>=0) or string")
    63          }
    64          return Node{}, self.parser.syntaxError(err)
    65      }
    66  
    67      t := switchRawType(self.parser.s[start])
    68      if t == _V_NONE {
    69          return Node{}, self.parser.ExportError(err)
    70      }
    71  
    72      // copy string to reducing memory usage
    73      var raw string
    74      if copystring {
    75          raw = rt.Mem2Str([]byte(self.parser.s[start:self.parser.p]))
    76      } else {
    77          raw = self.parser.s[start:self.parser.p]
    78      }
    79      return newRawNode(raw, t), nil
    80  }
    81  

View as plain text