iterator.go raw

   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  	"fmt"
  21  
  22  	"github.com/bytedance/sonic/internal/caching"
  23  	"github.com/bytedance/sonic/internal/native/types"
  24  )
  25  
  26  type Pair struct {
  27      hash  uint64
  28      Key   string
  29      Value Node
  30  }
  31  
  32  func NewPair(key string, val Node) Pair {
  33      return Pair{
  34          hash: caching.StrHash(key),
  35          Key: key,
  36          Value: val,
  37      }
  38  }
  39  
  40  // Values returns iterator for array's children traversal
  41  func (self *Node) Values() (ListIterator, error) {
  42      if err := self.should(types.V_ARRAY); err != nil {
  43          return ListIterator{}, err
  44      }
  45      return self.values(), nil
  46  }
  47  
  48  func (self *Node) values() ListIterator {
  49      return ListIterator{Iterator{p: self}}
  50  }
  51  
  52  // Properties returns iterator for object's children traversal
  53  func (self *Node) Properties() (ObjectIterator, error) {
  54      if err := self.should(types.V_OBJECT); err != nil {
  55          return ObjectIterator{}, err
  56      }
  57      return self.properties(), nil
  58  }
  59  
  60  func (self *Node) properties() ObjectIterator {
  61      return ObjectIterator{Iterator{p: self}}
  62  }
  63  
  64  type Iterator struct {
  65      i int
  66      p *Node
  67  }
  68  
  69  func (self *Iterator) Pos() int {
  70      return self.i
  71  }
  72  
  73  func (self *Iterator) Len() int {
  74      return self.p.len()
  75  }
  76  
  77  // HasNext reports if it is the end of iteration or has error.
  78  func (self *Iterator) HasNext() bool {
  79      if !self.p.isLazy() {
  80          return self.p.Valid() && self.i < self.p.len()
  81      } else if self.p.t == _V_ARRAY_LAZY {
  82          return self.p.skipNextNode().Valid()
  83      } else if self.p.t == _V_OBJECT_LAZY {
  84          pair := self.p.skipNextPair()
  85          if pair == nil {
  86              return false
  87          }
  88          return pair.Value.Valid()
  89      }
  90      return false
  91  }
  92  
  93  // ListIterator is specialized iterator for V_ARRAY
  94  type ListIterator struct {
  95      Iterator
  96  }
  97  
  98  // ObjectIterator is specialized iterator for V_ARRAY
  99  type ObjectIterator struct {
 100      Iterator
 101  }
 102  
 103  func (self *ListIterator) next() *Node {
 104  next_start:
 105      if !self.HasNext() {
 106          return nil
 107      } else {
 108          n := self.p.nodeAt(self.i)
 109          self.i++
 110          if !n.Exists() {
 111              goto next_start
 112          }
 113          return n
 114      }
 115  }
 116  
 117  // Next scans through children of underlying V_ARRAY, 
 118  // copies each child to v, and returns .HasNext().
 119  func (self *ListIterator) Next(v *Node) bool {
 120      n := self.next()
 121      if n == nil {
 122          return false
 123      }
 124      *v = *n
 125      return true
 126  }
 127  
 128  func (self *ObjectIterator) next() *Pair {
 129  next_start:
 130      if !self.HasNext() {
 131          return nil
 132      } else {
 133          n := self.p.pairAt(self.i)
 134          self.i++
 135          if n == nil || !n.Value.Exists() {
 136              goto next_start
 137          }
 138          return n
 139      }
 140  }
 141  
 142  // Next scans through children of underlying V_OBJECT, 
 143  // copies each child to v, and returns .HasNext().
 144  func (self *ObjectIterator) Next(p *Pair) bool {
 145      n := self.next()
 146      if n == nil {
 147          return false
 148      }
 149      *p = *n
 150      return true
 151  }
 152  
 153  // Sequence represents scanning path of single-layer nodes.
 154  // Index indicates the value's order in both V_ARRAY and V_OBJECT json.
 155  // Key is the value's key (for V_OBJECT json only, otherwise it will be nil).
 156  type Sequence struct {
 157      Index int 
 158      Key *string
 159      // Level int
 160  }
 161  
 162  // String is string representation of one Sequence
 163  func (s Sequence) String() string {
 164      k := ""
 165      if s.Key != nil {
 166          k = *s.Key
 167      }
 168      return fmt.Sprintf("Sequence(%d, %q)", s.Index, k)
 169  }
 170  
 171  type Scanner func(path Sequence, node *Node) bool
 172  
 173  // ForEach scans one V_OBJECT node's children from JSON head to tail, 
 174  // and pass the Sequence and Node of corresponding JSON value.
 175  //
 176  // Especially, if the node is not V_ARRAY or V_OBJECT,
 177  // the node itself will be returned and Sequence.Index == -1.
 178  // 
 179  // NOTICE: A unsetted node WON'T trigger sc, but its index still counts into Path.Index
 180  func (self *Node) ForEach(sc Scanner) error {
 181      if err := self.checkRaw(); err != nil {
 182          return err
 183      }
 184      switch self.itype() {
 185      case types.V_ARRAY:
 186          iter, err := self.Values()
 187          if err != nil {
 188              return err
 189          }
 190          v := iter.next()
 191          for v != nil {
 192              if !sc(Sequence{iter.i-1, nil}, v) {
 193                  return nil
 194              }
 195              v = iter.next()
 196          }
 197      case types.V_OBJECT:
 198          iter, err := self.Properties()
 199          if err != nil {
 200              return err
 201          }
 202          v := iter.next()
 203          for v != nil {
 204              if !sc(Sequence{iter.i-1, &v.Key}, &v.Value) {
 205                  return nil
 206              }
 207              v = iter.next()
 208          }
 209      default:
 210          if self.Check() != nil {
 211              return self
 212          }
 213          sc(Sequence{-1, nil}, self)
 214      }
 215      return nil
 216  }
 217