github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/proto/generic/iter.go (about)

     1  package generic
     2  
     3  import (
     4  	"github.com/cloudwego/dynamicgo/meta"
     5  	"github.com/cloudwego/dynamicgo/proto"
     6  	"github.com/cloudwego/dynamicgo/proto/binary"
     7  )
     8  
     9  func (self Node) iterFields() (fi structIterator) {
    10  	fi.p.Buf = self.raw()
    11  	return
    12  }
    13  
    14  func (self Node) iterElems() (fi listIterator) {
    15  	buf := self.raw()
    16  	fi.p.Buf = buf
    17  	if _, wtyp, _, err := fi.p.ConsumeTagWithoutMove(); err != nil {
    18  		fi.Err = wrapError(meta.ErrRead, "ListIterator.iterElems: consume list tag error.", err)
    19  		return
    20  	} else {
    21  		if wtyp != proto.BytesType {
    22  			fi.Err = wrapError(meta.ErrUnsupportedType, "ListIterator.iterElems: wire type is not bytes.", nil)
    23  			return
    24  		}
    25  		
    26  		size, err := self.Len()
    27  		if err != nil {
    28  			fi.Err = wrapError(meta.ErrRead, "ListIterator.iterElems: get list size error.", err)
    29  			return
    30  		}
    31  		fi.size = size
    32  		fi.et = proto.Type(self.et)
    33  		kind := fi.et.TypeToKind()
    34  		fi.ewt = proto.Kind2Wire[kind]
    35  		fi.isPacked = self.et.IsPacked()
    36  	}
    37  	return
    38  }
    39  
    40  func (self Node) iterPairs() (fi mapIterator) {
    41  	fi.p.Buf = self.raw()
    42  	// fi = pairIteratorPool.Get().(*PairIterator)
    43  	if _, wtyp, _, err := fi.p.ConsumeTagWithoutMove(); err != nil {
    44  		fi.Err = wrapError(meta.ErrRead, "MapIterator.iterPairs: consume map tag error.", err)
    45  		return
    46  	} else {
    47  		if wtyp != proto.BytesType {
    48  			fi.Err = wrapError(meta.ErrUnsupportedType, "MapIterator.iterPairs: wire type is not bytes.", nil)
    49  		}
    50  
    51  		size, err := self.Len()
    52  		if err != nil {
    53  			fi.Err = wrapError(meta.ErrRead, "MapIterator.iterPairs: get map size error.", err)
    54  			return
    55  		}
    56  		fi.size = size
    57  		fi.vt = proto.Type(self.et)
    58  		fi.vwt = proto.Kind2Wire[fi.vt.TypeToKind()]
    59  		fi.kt = proto.Type(self.kt)
    60  		fi.kwt = proto.Kind2Wire[fi.kt.TypeToKind()]
    61  	}
    62  	return
    63  }
    64  
    65  type structIterator struct {
    66  	Err error
    67  	p   binary.BinaryProtocol
    68  }
    69  
    70  func (it structIterator) HasNext() bool {
    71  	return it.Err == nil && it.p.Left() > 0
    72  }
    73  
    74  // start:end containg the tag
    75  func (it *structIterator) Next(useNative bool) (id proto.FieldNumber, typ proto.WireType, start int, end int, tagPos int) {
    76  	tagPos = it.p.Read
    77  	fieldId, wireType, _, err := it.p.ConsumeTag()
    78  	if err != nil {
    79  		it.Err = wrapError(meta.ErrRead, "StructIterator.Next: consume field tag error.", err)
    80  		return
    81  	}
    82  
    83  	start = it.p.Read
    84  	typ = wireType
    85  	if err = it.p.Skip(wireType, useNative); err != nil {
    86  		it.Err = wrapError(meta.ErrRead, "StructIterator.Next: skip field data error.", err)
    87  		return
    88  	}
    89  	end = it.p.Read
    90  
    91  	id = fieldId
    92  	return
    93  }
    94  
    95  
    96  type listIterator struct {
    97  	Err  error
    98  	p    binary.BinaryProtocol
    99  	size int // elements count, when lazyload mode, the size is also 0, so we use k to count
   100  	k    int // count of elements that has been read
   101  	isPacked bool // list mode
   102  	et   proto.Type // element type
   103  	ewt  proto.WireType // element wire type
   104  }
   105  
   106  func (it listIterator) HasNext() bool {
   107  	return it.Err == nil && it.p.Left() > 0
   108  }
   109  
   110  func (it listIterator) IsPacked() bool {
   111  	return it.isPacked
   112  }
   113  
   114  func (it listIterator) Size() int {
   115  	return it.size
   116  }
   117  
   118  func (it listIterator) Pos() int {
   119  	return it.k
   120  }
   121  
   122  func (it listIterator) WireType() proto.WireType {
   123  	return it.ewt
   124  }
   125  
   126  // compatible for packed/unpacked list, get element value: (L)V or V without tag
   127  func (it *listIterator) Next(useNative bool) (start int, end int) {
   128  	if !it.isPacked {
   129  		if _, _, _, err := it.p.ConsumeTag(); err != nil {
   130  			it.Err = wrapError(meta.ErrRead, "ListIterator: consume list tag error.", err)
   131  			return
   132  		}
   133  	}
   134  
   135  	start = it.p.Read
   136  	if err := it.p.Skip(it.ewt, useNative); err != nil {
   137  		it.Err = wrapError(meta.ErrRead, "ListIterator: skip list element error.", err)
   138  		return
   139  	}
   140  	end = it.p.Read
   141  	it.k++
   142  	return
   143  }
   144  
   145  
   146  type mapIterator struct {
   147  	Err  error
   148  	p    binary.BinaryProtocol
   149  	size int // elements count
   150  	i    int // count of elements that has been read
   151  	kt   proto.Type // key type
   152  	kwt  proto.WireType // key wire type
   153  	vt   proto.Type // value type
   154  	vwt  proto.WireType // value wire type
   155  }
   156  
   157  
   158  func (it mapIterator) HasNext() bool {
   159  	return it.Err == nil && it.p.Left() > 0
   160  }
   161  
   162  func (it mapIterator) Size() int {
   163  	return it.size
   164  }
   165  
   166  func (it mapIterator) Pos() int {
   167  	return it.i
   168  }
   169  
   170  func (it *mapIterator) NextStr(useNative bool) (keyStart int, keyString string, start int, end int) {
   171  	// pair tag
   172  	if _, _, _, err := it.p.ConsumeTag(); err != nil {
   173  		it.Err = wrapError(meta.ErrRead, "MapIterator: consume pair tag error.", err)
   174  		return
   175  	}
   176  
   177  	if _, err := it.p.ReadLength(); err != nil {
   178  		it.Err = wrapError(meta.ErrRead, "MapIterator: consume pair length error.", err)
   179  		return
   180  	}
   181  	
   182  	// read key tag
   183  	keyStart = it.p.Read
   184  	var err error
   185  	if it.kt == proto.STRING {
   186  		_,kwType,_,err := it.p.ConsumeTag()
   187  		if err != nil {
   188  			it.Err = wrapError(meta.ErrRead, "MapIterator: consume key tag error.", err)
   189  			return
   190  		}
   191  
   192  		if kwType != it.kwt {
   193  			it.Err = wrapError(meta.ErrUnsupportedType, "MapIterator.nextStr: key type is not expected", nil)
   194  			return
   195  		}
   196  
   197  		keyString, err = it.p.ReadString(false)
   198  		if err != nil {
   199  			it.Err = wrapError(meta.ErrRead, "", err)
   200  			return
   201  		}
   202  	} else {
   203  		it.Err = wrapError(meta.ErrUnsupportedType, "MapIterator.nextStr: key type is not string.", nil)
   204  		return
   205  	}
   206  
   207  	// read value tag
   208  	_,ewType,_,err := it.p.ConsumeTag()
   209  	if err != nil {
   210  		it.Err = wrapError(meta.ErrRead, "", err)
   211  		return
   212  	}
   213  
   214  	if ewType != it.vwt {
   215  		it.Err = wrapError(meta.ErrUnsupportedType, "MapIterator.nextStr: value type is not expected", nil)
   216  		return
   217  	}
   218  
   219  	start = it.p.Read
   220  	
   221  	if err = it.p.Skip(it.vwt, useNative); err != nil {
   222  		it.Err = wrapError(meta.ErrRead, "", err)
   223  		return
   224  	}
   225  	end = it.p.Read
   226  	it.i++
   227  	return
   228  }
   229  
   230  
   231  func (it *mapIterator) NextInt(useNative bool) (keyStart int, keyInt int, start int, end int) {
   232  	if _, _, _, err := it.p.ConsumeTag(); err != nil {
   233  		it.Err = wrapError(meta.ErrRead, "", err)
   234  		return
   235  	}
   236  
   237  	if _, err := it.p.ReadLength(); err != nil {
   238  		it.Err = wrapError(meta.ErrRead, "", err)
   239  		return
   240  	}
   241  	
   242  	keyStart = it.p.Read
   243  	var err error
   244  	if it.kt.IsInt() {
   245  		// read key tag
   246  		_,kwType,_,err := it.p.ConsumeTag()
   247  		if err != nil {
   248  			it.Err = wrapError(meta.ErrRead, "", err)
   249  			return
   250  		}
   251  
   252  		if kwType != it.kwt {
   253  			it.Err = wrapError(meta.ErrUnsupportedType, "MapIterator.nextStr: key type is not expected", nil)
   254  			return
   255  		}
   256  
   257  		keyInt, err = it.p.ReadInt(it.kt)
   258  		if err != nil {
   259  			it.Err = wrapError(meta.ErrRead, "", err)
   260  			return
   261  		}
   262  
   263  	} else {
   264  		it.Err = wrapError(meta.ErrUnsupportedType, "MapIterator.nextStr: key type is not string", nil)
   265  		return
   266  	}
   267  
   268  	// read value tag
   269  	_,ewType,_,err := it.p.ConsumeTag()
   270  	if err != nil {
   271  		it.Err = wrapError(meta.ErrRead, "", err)
   272  		return
   273  	}
   274  
   275  	if ewType != it.vwt {
   276  		it.Err = wrapError(meta.ErrUnsupportedType, "MapIterator.nextStr: value type is not expected", nil)
   277  		return
   278  	}
   279  
   280  	start = it.p.Read
   281  	
   282  	if err = it.p.Skip(it.vwt, useNative); err != nil {
   283  		it.Err = wrapError(meta.ErrRead, "", err)
   284  		return
   285  	}
   286  	end = it.p.Read
   287  	it.i++
   288  	return
   289  }