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 }