github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/proto/generic/value.go (about) 1 package generic 2 3 import ( 4 "fmt" 5 "sync" 6 "unsafe" 7 8 "github.com/cloudwego/dynamicgo/internal/rt" 9 "github.com/cloudwego/dynamicgo/meta" 10 "github.com/cloudwego/dynamicgo/proto" 11 "github.com/cloudwego/dynamicgo/proto/binary" 12 "github.com/cloudwego/dynamicgo/proto/protowire" 13 ) 14 15 const defaultBytesSize = 64 16 17 type Value struct { 18 Node 19 Desc *proto.TypeDescriptor 20 IsRoot bool 21 } 22 23 var ( 24 pnsPool = sync.Pool{ 25 New: func() interface{} { 26 return &pnSlice{ 27 a: make([]PathNode, 0, DefaultNodeSliceCap), 28 } 29 }, 30 } 31 bytesPool = sync.Pool{ 32 New: func() interface{} { 33 return make([]byte, 0, defaultBytesSize) 34 }, 35 } 36 ) 37 38 func NewBytesFromPool() []byte { 39 return bytesPool.Get().([]byte) 40 } 41 42 func FreeBytesToPool(b []byte) { 43 b = b[:0] 44 bytesPool.Put(b) 45 } 46 47 func NewRootValue(desc *proto.TypeDescriptor, src []byte) Value { 48 return Value{ 49 Node: NewNode(proto.MESSAGE, src), 50 Desc: desc, 51 IsRoot: true, 52 } 53 } 54 55 // only for basic Node 56 func NewValue(desc *proto.TypeDescriptor, src []byte) Value { 57 return Value{ 58 Node: NewNode(desc.Type(), src), 59 Desc: desc, 60 } 61 } 62 63 // only for LIST/MAP parent Node 64 func NewComplexValue(desc *proto.TypeDescriptor, src []byte) Value { 65 t := desc.Type() 66 et := proto.UNKNOWN 67 kt := proto.UNKNOWN 68 if t == proto.LIST { 69 et = desc.Elem().Type() 70 } else if t == proto.MAP { 71 t = proto.MAP 72 et = desc.Elem().Type() 73 kt = desc.Key().Type() 74 } else { 75 panic("only used for list/map node") 76 } 77 78 return Value{ 79 Node: NewComplexNode(t, et, kt, src), 80 Desc: desc, 81 } 82 } 83 84 85 // NewValueFromNode copy both Node and TypeDescriptor from another Value. 86 func (self Value) Fork() Value { 87 ret := self 88 ret.Node = self.Node.Fork() 89 return ret 90 } 91 92 93 func (self Value) sliceWithDesc(s int, e int, desc *proto.TypeDescriptor) Value { 94 node := self.sliceNodeWithDesc(s, e, desc) 95 return Value{Node: node, Desc: desc} 96 } 97 98 // searchFieldId in MESSAGE Node 99 // if id is found, return the field tag position, otherwise return the end of p.Buf 100 func searchFieldId(p *binary.BinaryProtocol, id proto.FieldNumber, messageLen int) (int, error) { 101 start := p.Read 102 for p.Read < start+messageLen { 103 fieldNumber, wireType, tagLen, err := p.ConsumeTagWithoutMove() 104 if err != nil { 105 return 0, err 106 } 107 108 if fieldNumber == id { 109 return p.Read, nil 110 } 111 p.Read += tagLen 112 113 if err := p.Skip(wireType, false); err != nil { 114 return 0, errNode(meta.ErrRead, "searchFieldId: skip field error.", err) 115 } 116 } 117 return p.Read, errNotFound 118 } 119 120 // searchIndex in LIST Node 121 // packed: if idx is found, return the element[V] value start position, otherwise return the end of p.Buf 122 // unpacked: if idx is found, return the element[TLV] tag position, otherwise return the end of p.Buf 123 func searchIndex(p *binary.BinaryProtocol, idx int, elementWireType proto.WireType, isPacked bool, fieldNumber proto.FieldNumber) (int, error) { 124 // packed list 125 cnt := 0 126 result := p.Read 127 if isPacked { 128 // read length 129 length, err := p.ReadLength() 130 if err != nil { 131 return 0, err 132 } 133 // read list 134 start := p.Read 135 for p.Read < start+length && cnt < idx { 136 if err := p.Skip(elementWireType, false); err != nil { 137 return 0, errNode(meta.ErrRead, "searchIndex: skip packed list element error.", err) 138 } 139 cnt++ 140 } 141 result = p.Read 142 } else { 143 // normal Type : [tag][(length)][value][tag][(length)][value][tag][(length)][value].... 144 for p.Read < len(p.Buf) && cnt < idx { 145 // don't move p.Read and judge whether readList completely 146 if err := p.Skip(elementWireType, false); err != nil { 147 return 0, errNode(meta.ErrRead, "searchIndex: skip unpacked list element error.", err) 148 } 149 cnt++ 150 if p.Read < len(p.Buf) { 151 // don't move p.Read and judge whether readList completely 152 elementFieldNumber, _, n, err := p.ConsumeTagWithoutMove() 153 if err != nil { 154 return 0, err 155 } 156 if elementFieldNumber != fieldNumber { 157 break 158 } 159 if cnt < idx { 160 p.Read += n 161 } 162 result = p.Read + n 163 } 164 } 165 166 } 167 168 if cnt < idx { 169 return p.Read, errNotFound 170 } 171 172 return result, nil 173 } 174 175 // searchIntKey in MAP Node 176 // if key is found, return the value tag position, otherwise return the end of p.Buf 177 func searchIntKey(p *binary.BinaryProtocol, key int, keyType proto.Type, mapFieldNumber proto.FieldNumber) (int, error) { 178 exist := false 179 start := p.Read 180 for p.Read < len(p.Buf) { 181 if _, err := p.ReadLength(); err != nil { 182 return 0, wrapError(meta.ErrRead, "searchIntKey: read pair length failed", nil) 183 } 184 185 if _, _, _, keyTagErr := p.ConsumeTag(); keyTagErr != nil { 186 return 0, wrapError(meta.ErrRead, "searchIntKey: read key tag failed", nil) 187 } 188 189 k, err := p.ReadInt(keyType) 190 if err != nil { 191 return 0, wrapError(meta.ErrRead, "searchIntKey: can not read map key", nil) 192 } 193 194 if k == key { 195 exist = true 196 start = p.Read // p.Read will point to value tag 197 break 198 } 199 200 _, valueWireType, _, valueTagErr := p.ConsumeTag() 201 if valueTagErr != nil { 202 return 0, wrapError(meta.ErrRead, "searchIntKey: read value tag failed", nil) 203 } 204 205 // if key not match, skip value 206 if err := p.Skip(valueWireType, false); err != nil { 207 return 0, errNode(meta.ErrRead, "searchIntKey: searchIntKey: can not read value.", err) 208 } 209 210 if p.Read >= len(p.Buf) { 211 break 212 } 213 214 // don't move p.Read and judge whether readList completely 215 elementFieldNumber, _, n, err := p.ConsumeTagWithoutMove() 216 if err != nil { 217 return 0, err 218 } 219 if elementFieldNumber != mapFieldNumber { 220 break 221 } 222 p.Read += n 223 } 224 if !exist { 225 return p.Read, errNotFound 226 } 227 return start, nil 228 } 229 230 // searchStrKey in MAP Node 231 // if key is found, return the value tag position, otherwise return the end of p.Buf 232 func searchStrKey(p *binary.BinaryProtocol, key string, keyType proto.Type, mapFieldNumber proto.FieldNumber) (int, error) { 233 exist := false 234 start := p.Read 235 236 for p.Read < len(p.Buf) { 237 if _, err := p.ReadLength(); err != nil { 238 return 0, wrapError(meta.ErrRead, "searchStrKey: read pair length failed", nil) 239 } 240 241 if _, _, _, keyTagErr := p.ConsumeTag(); keyTagErr != nil { 242 return 0, wrapError(meta.ErrRead, "searchStrKey: read key tag failed", nil) 243 } 244 245 k, err := p.ReadString(false) 246 if err != nil { 247 return 0, wrapError(meta.ErrRead, "searchStrKey: can not read map key", nil) 248 } 249 250 if k == key { 251 exist = true 252 start = p.Read // p.Read will point to value tag 253 break 254 } 255 256 _, valueWireType, _, valueTagErr := p.ConsumeTag() 257 if valueTagErr != nil { 258 return 0, wrapError(meta.ErrRead, "searchStrKey: read value tag failed", nil) 259 } 260 261 // if key not match, skip value 262 if err := p.Skip(valueWireType, false); err != nil { 263 return 0, errNode(meta.ErrRead, "searchStrKey: searchStrKey: can not read value.", err) 264 } 265 266 if p.Read >= len(p.Buf) { 267 break 268 } 269 270 // don't move p.Read and judge whether readList completely 271 elementFieldNumber, _, n, err := p.ConsumeTagWithoutMove() 272 if err != nil { 273 return 0, err 274 } 275 if elementFieldNumber != mapFieldNumber { 276 break 277 } 278 p.Read += n 279 } 280 if !exist { 281 return p.Read, errNotFound 282 } 283 return start, nil 284 } 285 286 func (self Value) GetByPath(pathes ...Path) Value { 287 value, _ := self.getByPath(pathes...) 288 return value 289 } 290 291 func (self Value) GetByPathWithAddress(pathes ...Path) (Value, []int) { 292 return self.getByPath(pathes...) 293 } 294 295 // inner use 296 func (self Value) getByPath(pathes ...Path) (Value, []int) { 297 address := make([]int, len(pathes)) 298 start := 0 299 var err error 300 tt := self.t 301 kt := self.kt 302 et := self.et 303 size := 0 304 desc := self.Desc 305 isRoot := self.IsRoot 306 if len(pathes) == 0 { 307 return self, address 308 } 309 310 if self.Error() != "" { 311 return self, address 312 } 313 314 p := binary.BinaryProtocol{ 315 Buf: self.raw(), 316 } 317 318 if !isRoot { 319 if self.t == proto.LIST || self.t == proto.MAP { 320 p.ConsumeTag() 321 } 322 } 323 324 for i, path := range pathes { 325 switch path.t { 326 case PathFieldId: 327 id := path.id() 328 messageLen := 0 329 if isRoot { 330 messageLen = len(p.Buf) 331 isRoot = false 332 } else { 333 Len, err := p.ReadLength() 334 if err != nil { 335 return errValue(meta.ErrRead, "GetByPath: read field length failed.", err), address 336 } 337 messageLen += Len 338 } 339 340 fd := desc.Message().ByNumber(id) 341 if fd != nil { 342 desc = fd.Type() 343 tt = desc.Type() 344 } 345 346 start, err = searchFieldId(&p, id, messageLen) 347 if err == errNotFound { 348 tt = proto.MESSAGE 349 } 350 case PathFieldName: 351 name := path.str() 352 messageLen := 0 353 if isRoot { 354 messageLen = len(p.Buf) 355 isRoot = false 356 } else { 357 Len, err := p.ReadLength() 358 if err != nil { 359 return errValue(meta.ErrRead, "GetByPath: read field length failed.", err), address 360 } 361 messageLen += Len 362 } 363 364 fd := desc.Message().ByName(name) 365 if fd == nil { 366 return errValue(meta.ErrUnknownField, fmt.Sprintf("field name '%s' is not defined in IDL", name), nil), address 367 } 368 369 desc = fd.Type() 370 tt = desc.Type() 371 start, err = searchFieldId(&p, fd.Number(), messageLen) 372 if err == errNotFound { 373 tt = proto.MESSAGE 374 } 375 case PathIndex: 376 elementWireType := desc.Elem().WireType() 377 isPacked := desc.IsPacked() 378 start, err = searchIndex(&p, path.int(), elementWireType, isPacked, desc.BaseId()) 379 tt = desc.Elem().Type() 380 if err == errNotFound { 381 tt = proto.LIST 382 } 383 case PathStrKey: 384 mapFieldNumber := desc.BaseId() 385 start, err = searchStrKey(&p, path.str(), proto.STRING, mapFieldNumber) 386 tt = desc.Elem().Type() 387 valueDesc := desc.Elem() 388 desc = valueDesc 389 if err == errNotFound { 390 tt = proto.MAP 391 } 392 case PathIntKey: 393 keyType := desc.Key().Type() 394 mapFieldNumber := desc.BaseId() 395 start, err = searchIntKey(&p, path.int(), keyType, mapFieldNumber) 396 tt = desc.Elem().Type() 397 valueDesc := desc.Elem() 398 desc = valueDesc 399 if err == errNotFound { 400 tt = proto.MAP 401 } 402 default: 403 return errValue(meta.ErrUnsupportedType, fmt.Sprintf("invalid %dth path: %#v", i, p), nil), address 404 } 405 // after search function, p.Read will always point to the tag position except when packed list element 406 address[i] = start 407 408 if err != nil { 409 // the last one not foud, return start pointer for subsequently inserting operation on `SetByPath()` 410 if i == len(pathes)-1 && err == errNotFound { 411 return Value{errNotFoundLast(unsafe.Pointer(uintptr(self.v)+uintptr(start)), tt), nil, false}, address 412 } 413 en := err.(Node) 414 return errValue(en.ErrCode().Behavior(), "invalid value node.", err), address 415 } 416 // if not the last one, it must be a complex node, so need to skip tag 417 if i != len(pathes)-1 { 418 if _, _, _, err := p.ConsumeTag(); err != nil { 419 return errValue(meta.ErrRead, "invalid field tag failed.", err), address 420 } 421 } 422 423 } 424 425 // check the result node type to get the right slice bytes 426 switch tt { 427 case proto.MAP: 428 kt = desc.Key().Type() 429 et = desc.Elem().Type() 430 if s, err := p.SkipAllElements(desc.BaseId(), desc.IsPacked()); err != nil { 431 en := err.(Node) 432 return errValue(en.ErrCode().Behavior(), "invalid map node.", err), address 433 } else { 434 size = s 435 } 436 case proto.LIST: 437 et = desc.Elem().Type() 438 if s, err := p.SkipAllElements(desc.BaseId(), desc.IsPacked()); err != nil { 439 en := err.(Node) 440 return errValue(en.ErrCode().Behavior(), "invalid list node.", err), address 441 } else { 442 size = s 443 } 444 default: 445 // node condition: field element, list element, map value element 446 var skipType proto.WireType 447 448 // only packed list element no tag to skip 449 if desc.IsPacked() == false { 450 if _, _, _, err := p.ConsumeTag(); err != nil { 451 return errValue(meta.ErrRead, "invalid field tag.", err), address 452 } 453 start = p.Read 454 } 455 456 if desc.Type() != proto.LIST{ 457 skipType = desc.WireType() 458 } else { 459 skipType = desc.Elem().WireType() 460 desc = desc.Elem() 461 } 462 463 if err := p.Skip(skipType, false); err != nil { 464 return errValue(meta.ErrRead, "skip field error.", err), address 465 } 466 } 467 468 return wrapValue(self.Node.sliceComplex(start, p.Read, tt, kt, et, size), desc), address 469 } 470 471 // SetByPath searches longitudinally and sets a sub value at the given path from the value. 472 // exist tells whether the node is already exists. 473 func (self *Value) SetByPath(sub Node, path ...Path) (exist bool, err error) { 474 l := len(path) 475 if l == 0 { 476 if self.t != sub.t { 477 return false, errValue(meta.ErrDismatchType, "self node type is not equal to sub node type.", nil) 478 } 479 self.Node = sub // it means replace the root value ? 480 return true, nil 481 } 482 483 if err := self.Check(); err != nil { 484 return false, err 485 } 486 487 if self.Error() != "" { 488 return false, wrapError(meta.ErrInvalidParam, "given node is invalid.", sub) 489 } 490 491 // search source node by path 492 v, address := self.getByPath(path...) 493 if v.IsError() { 494 if !v.isErrNotFoundLast() { 495 return false, v 496 } 497 498 // find target node descriptor 499 targetPath := path[l-1] 500 desc, err := getDescByPath(self.Desc, path[:l-1]...) 501 // var fd *proto.FieldDescriptor 502 if err != nil { 503 return false, err 504 } 505 506 // exchange PathFieldName to create PathFieldId 507 if targetPath.t == PathFieldName { 508 f := desc.Message().ByName(targetPath.str()) 509 targetPath = NewPathFieldId(f.Number()) 510 desc = f.Type() 511 } 512 513 // set sub node bytes by path and descriptor to check whether the node need to append tag 514 if err := v.setNotFound(targetPath, &sub, desc); err != nil { 515 return false, err 516 } 517 } else { 518 exist = true 519 } 520 521 originLen := len(self.raw()) // root buf length 522 err = self.replace(v.Node, sub) // replace ErrorNode bytes by sub Node bytes 523 isPacked := path[l-1].t == PathIndex && sub.t.IsPacked() 524 self.updateByteLen(originLen, address, isPacked, path...) 525 return 526 } 527 528 // update parent node bytes length 529 func (self *Value) updateByteLen(originLen int, address []int, isPacked bool, path ...Path) { 530 afterLen := self.l 531 diffLen := afterLen - originLen 532 previousType := proto.UNKNOWN 533 534 for i := len(address) - 1; i >= 0; i-- { 535 // notice: when i == len(address) - 1, it do not change bytes length because it has been changed in replace function, just change previousType 536 pathType := path[i].t 537 addressPtr := address[i] 538 if previousType == proto.MESSAGE || (previousType == proto.LIST && isPacked) { 539 newBytes := NewBytesFromPool() 540 // tag 541 buf := rt.BytesFrom(rt.AddPtr(self.v, uintptr(addressPtr)), self.l-addressPtr, self.l-addressPtr) 542 _, tagOffset := protowire.ConsumeVarint(buf) 543 // length 544 length, lenOffset := protowire.ConsumeVarint(buf[tagOffset:]) 545 newLength := int(length) + diffLen 546 newBytes = protowire.AppendVarint(newBytes, uint64(newLength)) 547 // length == 0 means had been deleted all the data in the field 548 if newLength == 0 { 549 newBytes = newBytes[:0] 550 } 551 552 subLen := len(newBytes) - lenOffset 553 554 if subLen == 0 { 555 // no need to change length 556 copy(buf[tagOffset:tagOffset+lenOffset], newBytes) 557 continue 558 } 559 560 // split length 561 srcHead := rt.AddPtr(self.v, uintptr(addressPtr+tagOffset)) 562 if newLength == 0 { 563 // delete tag 564 srcHead = rt.AddPtr(self.v, uintptr(addressPtr)) 565 subLen -= tagOffset 566 } 567 568 srcTail := rt.AddPtr(self.v, uintptr(addressPtr+tagOffset+lenOffset)) 569 l0 := int(uintptr(srcHead) - uintptr(self.v)) 570 l1 := len(newBytes) 571 l2 := int(uintptr(self.v) + uintptr(self.l) - uintptr(srcTail)) 572 573 // copy three slices into new buffer 574 newBuf := make([]byte, l0+l1+l2) 575 copy(newBuf[:l0], rt.BytesFrom(self.v, l0, l0)) 576 copy(newBuf[l0:l0+l1], newBytes) 577 copy(newBuf[l0+l1:l0+l1+l2], rt.BytesFrom(srcTail, l2, l2)) 578 self.v = rt.GetBytePtr(newBuf) 579 self.l = int(len(newBuf)) 580 if isPacked { 581 isPacked = false 582 } 583 diffLen += subLen 584 FreeBytesToPool(newBytes) 585 } 586 587 if pathType == PathStrKey || pathType == PathIntKey { 588 previousType = proto.MAP 589 } else if pathType == PathIndex { 590 previousType = proto.LIST 591 } else { 592 previousType = proto.MESSAGE 593 } 594 } 595 } 596 597 // UnsetByPath searches longitudinally and unsets a sub value at the given path from the value. 598 func (self *Value) UnsetByPath(path ...Path) error { 599 l := len(path) 600 if l == 0 { 601 *self = Value{} 602 return nil 603 } 604 if err := self.Check(); err != nil { 605 return err 606 } 607 608 // search target node by path 609 var parentValue, address = self.getByPath(path[:l-1]...) 610 if parentValue.IsError() { 611 if parentValue.IsErrNotFound() { 612 print(address) 613 return nil 614 } 615 return parentValue 616 } 617 618 p := path[l-1] 619 var desc *proto.TypeDescriptor 620 var err error 621 622 desc, err = getDescByPath(self.Desc, path[:l-1]...) 623 if err != nil { 624 return err 625 } 626 isPacked := desc.IsPacked() 627 628 if p.t == PathFieldName { 629 f := desc.Message().ByName(p.str()) 630 p = NewPathFieldId(f.Number()) 631 } 632 633 ret, position := parentValue.findDeleteChild(p) 634 if ret.IsError() { 635 return ret 636 } 637 638 originLen := len(self.raw()) 639 if err := self.replace(ret, Node{t: ret.t}); err != nil { 640 return errValue(meta.ErrWrite, "replace node by empty node failed", err) 641 } 642 address = append(address, position) // must add one address align with path length 643 self.updateByteLen(originLen, address, isPacked, path...) 644 return nil 645 } 646 647 func (self *Value) findDeleteChild(path Path) (Node, int) { 648 tt := self.t // in fact, no need to judge which type 649 valueLen := self.l 650 exist := false 651 var start, end int 652 653 switch self.t { 654 case proto.MESSAGE: 655 it := self.iterFields() 656 // if not root node 657 if !self.IsRoot { 658 if l, err := it.p.ReadLength(); err != nil { 659 return errNode(meta.ErrRead, "", err), -1 660 } else { 661 valueLen = l 662 } 663 } 664 start = valueLen // start initial at the end of the message 665 end = 0 // end initial at the begin of the message 666 667 // previous has change PathFieldName to PathFieldId 668 if path.Type() != PathFieldId { 669 return errNode(meta.ErrDismatchType, "path type is not PathFieldId", nil), -1 670 } 671 672 messageStart := it.p.Read 673 id := path.id() 674 for it.p.Read < messageStart+valueLen { 675 fieldStart := it.p.Read 676 fieldNumber, wireType, _, tagErr := it.p.ConsumeTag() 677 if tagErr != nil { 678 return errNode(meta.ErrRead, "", tagErr), -1 679 } 680 if err := it.p.Skip(wireType, false); err != nil { 681 return errNode(meta.ErrRead, "", err), -1 682 } 683 fieldEnd := it.p.Read 684 // get all items of the same fieldNumber, find the min start and max end, because the fieldNumber may be repeated 685 if id == fieldNumber { 686 exist = true 687 if fieldStart < start { 688 start = fieldStart 689 } 690 if fieldEnd > end { 691 end = fieldEnd 692 } 693 } 694 } 695 if !exist { 696 return errNotFound, -1 697 } 698 case proto.LIST: 699 it := self.iterElems() 700 listIndex := 0 701 if path.Type() != PathIndex { 702 return errNode(meta.ErrDismatchType, "path type is not PathIndex", nil), -1 703 } 704 idx := path.int() 705 706 elemType := self.Desc.Elem().WireType() 707 size, err := self.Len() 708 if err != nil { 709 return errNode(meta.ErrRead, "", err), -1 710 } 711 712 // size = 0 maybe list in lazy load, need to check idx 713 if size > 0 && idx >= size { 714 return errNotFound, -1 715 } 716 // packed : [ListTag][ListLen][(l)v][(l)v][(l)v][(l)v]..... 717 if self.Desc.IsPacked() { 718 if _, _, _, err := it.p.ConsumeTag(); err != nil { 719 return errNode(meta.ErrRead, "", err), -1 720 } 721 722 if _, lengthErr := it.p.ReadLength(); lengthErr != nil { 723 return errNode(meta.ErrRead, "", lengthErr), -1 724 } 725 726 for it.p.Read < valueLen && listIndex <= idx { 727 start = it.p.Read 728 if err := it.p.Skip(elemType, false); err != nil { 729 return errNode(meta.ErrRead, "", err), -1 730 } 731 end = it.p.Read 732 listIndex++ 733 } 734 } else { 735 // unpacked : [tag][l][v][tag][l][v][tag][l][v][tag][l][v].... 736 for it.p.Read < valueLen && listIndex <= idx { 737 start = it.p.Read 738 if _, _, _, err := it.p.ConsumeTag(); err != nil { 739 return errNode(meta.ErrRead, "", err), -1 740 } 741 742 if err := it.p.Skip(elemType, false); err != nil { 743 return errNode(meta.ErrRead, "", err), -1 744 } 745 end = it.p.Read 746 listIndex++ 747 } 748 } 749 case proto.MAP: 750 it := self.iterPairs() 751 752 if self.kt == proto.STRING { 753 key := path.str() 754 for it.p.Read < valueLen { 755 start = it.p.Read 756 // pair 757 if _, _, _, err := it.p.ConsumeTag(); err != nil { 758 return errNode(meta.ErrRead, "", err), -1 759 } 760 if _, err := it.p.ReadLength(); err != nil { 761 return errNode(meta.ErrRead, "", err), -1 762 } 763 764 // key 765 if _, _, _, err := it.p.ConsumeTag(); err != nil { 766 return errNode(meta.ErrRead, "", err), -1 767 } 768 k, err := it.p.ReadString(false) 769 if err != nil { 770 return errNode(meta.ErrRead, "", err), -1 771 } 772 773 // value 774 _, valueWire, _, _ := it.p.ConsumeTag() 775 if err := it.p.Skip(valueWire, false); err != nil { 776 return errNode(meta.ErrRead, "", err), -1 777 } 778 end = it.p.Read 779 if k == key { 780 exist = true 781 break 782 } 783 } 784 } else if self.kt.IsInt() { 785 key := path.Int() 786 for it.p.Read < valueLen { 787 start = it.p.Read 788 789 if _, _, _, err := it.p.ConsumeTag(); err != nil { 790 return errNode(meta.ErrRead, "", err), -1 791 } 792 793 if _, err := it.p.ReadLength(); err != nil { 794 return errNode(meta.ErrRead, "", err), -1 795 } 796 797 // key 798 if _, _, _, err := it.p.ConsumeTag(); err != nil { 799 return errNode(meta.ErrRead, "", err), -1 800 } 801 802 k, err := it.p.ReadInt(self.kt) 803 if err != nil { 804 return errNode(meta.ErrRead, "", err), -1 805 } 806 807 //value 808 _, valueWire, _, _ := it.p.ConsumeTag() 809 if err := it.p.Skip(valueWire, false); err != nil { 810 return errNode(meta.ErrRead, "", err), -1 811 } 812 end = it.p.Read 813 if k == key { 814 exist = true 815 break 816 } 817 } 818 } 819 if !exist { 820 return errNotFound, -1 821 } 822 default: 823 return errNotFound, -1 824 } 825 return Node{ 826 t: tt, 827 v: rt.AddPtr(self.v, uintptr(start)), 828 l: end - start, 829 }, start 830 } 831 832 // MarshalTo marshals self value into a sub value descripted by the to descriptor, alse called as "Cutting". 833 // Usually, the to descriptor is a subset of self descriptor. 834 func (self Value) MarshalTo(to *proto.TypeDescriptor, opts *Options) ([]byte, error) { 835 var w = binary.NewBinaryProtocolBuffer() 836 var r = binary.BinaryProtocol{} 837 r.Buf = self.raw() 838 var from = self.Desc 839 messageLen := len(r.Buf) 840 if err := marshalTo(&r, w, from, to, opts, messageLen); err != nil { 841 return nil, err 842 } 843 ret := make([]byte, len(w.Buf)) 844 copy(ret, w.Buf) 845 binary.FreeBinaryProtocol(w) 846 return ret, nil 847 } 848 849 func marshalTo(read *binary.BinaryProtocol, write *binary.BinaryProtocol, from *proto.TypeDescriptor, to *proto.TypeDescriptor, opts *Options, massageLen int) error { 850 tail := read.Read + massageLen 851 for read.Read < tail { 852 fieldNumber, wireType, _, _ := read.ConsumeTag() 853 fromField := from.Message().ByNumber(fieldNumber) 854 855 if fromField == nil { 856 if opts.DisallowUnknown { 857 return wrapError(meta.ErrUnknownField, fmt.Sprintf("unknown field %d", fieldNumber), nil) 858 } else { 859 // if not set, skip to the next field 860 if err := read.Skip(wireType, opts.UseNativeSkip); err != nil { 861 return wrapError(meta.ErrRead, "", err) 862 } 863 continue 864 } 865 } 866 867 toField := to.Message().ByNumber(fieldNumber) 868 869 if toField == nil { 870 // if not set, skip to the next field 871 if err := read.Skip(wireType, opts.UseNativeSkip); err != nil { 872 return wrapError(meta.ErrRead, "", err) 873 } 874 continue 875 } 876 877 fromType := fromField.Kind() 878 toType := toField.Kind() 879 if fromType != toType { 880 return wrapError(meta.ErrDismatchType, "to descriptor dismatches from descriptor", nil) 881 } 882 883 // when FieldDescriptor.Kind() == MessageKind, it contained 3 conditions: message list, message map value, message; 884 if fromType == proto.MessageKind { 885 fromDesc := fromField.Type() 886 toDesc := toField.Type() 887 // message list 888 if fromDesc.Type() == proto.LIST{ 889 fromDesc = fromDesc.Elem() 890 toDesc = toDesc.Elem() 891 } 892 893 write.AppendTag(fieldNumber, wireType) 894 var pos int 895 subMessageLen, err := read.ReadLength() 896 if err != nil { 897 return wrapError(meta.ErrRead, "", err) 898 } 899 write.Buf, pos = binary.AppendSpeculativeLength(write.Buf) 900 marshalTo(read, write, fromDesc, toDesc, opts, subMessageLen) 901 write.Buf = binary.FinishSpeculativeLength(write.Buf, pos) 902 } else { 903 start := read.Read 904 if err := read.Skip(wireType, opts.UseNativeSkip); err != nil { 905 return wrapError(meta.ErrRead, "", err) 906 } 907 end := read.Read 908 value := read.Buf[start:end] 909 910 write.AppendTag(fieldNumber, wireType) 911 write.Buf = append(write.Buf, value...) 912 } 913 } 914 return nil 915 } 916 917 // GetByInt returns a sub node at the given key from a MAP value. 918 func (self Value) GetByStr(key string) (v Value) { 919 n := self.Node.GetByStr(key) 920 vd := self.Desc.Elem() 921 if n.IsError() { 922 return wrapValue(n, nil) 923 } 924 return wrapValue(n, vd) 925 } 926 927 // GetByInt returns a sub node at the given key from a MAP value. 928 func (self Value) GetByInt(key int) (v Value) { 929 n := self.Node.GetByInt(key) 930 vd := self.Desc.Elem() 931 if n.IsError() { 932 return wrapValue(n, nil) 933 } 934 return wrapValue(n, vd) 935 } 936 937 // Index returns a sub node at the given index from a LIST value. 938 func (self Value) Index(i int) (v Value) { 939 n := self.Node.Index(i) 940 if n.IsError() { 941 return wrapValue(n, nil) 942 } 943 v = wrapValue(n, self.Desc.Elem()) 944 return 945 } 946 947 // FieldByName returns a sub node at the given field name from a MESSAGE value. 948 func (self Value) FieldByName(name string) (v Value) { 949 if err := self.should("FieldByName", proto.MESSAGE); err != "" { 950 return errValue(meta.ErrUnsupportedType, err, nil) 951 } 952 953 it := self.iterFields() 954 if !self.IsRoot { 955 if _, err := it.p.ReadLength(); err != nil { 956 return errValue(meta.ErrRead, "", err) 957 } 958 } 959 960 f := self.Desc.Message().ByName(name) 961 if f == nil { 962 return errValue(meta.ErrUnknownField, fmt.Sprintf("field '%s' is not defined in IDL", name), nil) 963 } 964 965 // not found, try to scan the whole bytes 966 967 if it.Err != nil { 968 return errValue(meta.ErrRead, "", it.Err) 969 } 970 for it.HasNext() { 971 i, wt, s, e, tagPos := it.Next(UseNativeSkipForGet) 972 if i == f.Number() { 973 typDesc := f.Type() 974 if typDesc.IsMap() || typDesc.IsList() { 975 it.p.Read = tagPos 976 if _, err := it.p.SkipAllElements(i, typDesc.IsPacked()); err != nil { 977 return errValue(meta.ErrRead, "SkipAllElements in LIST/MAP failed", err) 978 } 979 s = tagPos 980 e = it.p.Read 981 982 v = self.sliceWithDesc(s, e, typDesc) 983 goto ret 984 } 985 986 t := proto.Kind2Wire[f.Kind()] 987 if wt != t { 988 v = errValue(meta.ErrDismatchType, fmt.Sprintf("field '%s' expects type %s, buf got type %s", string(f.Name()), t, wt), nil) 989 goto ret 990 } 991 v = self.sliceWithDesc(s, e, typDesc) 992 goto ret 993 } else if it.Err != nil { 994 v = errValue(meta.ErrRead, "", it.Err) 995 goto ret 996 } 997 } 998 999 v = errValue(meta.ErrNotFound, fmt.Sprintf("field '%s' is not found in this value", name), errNotFound) 1000 ret: 1001 // it.Recycle() 1002 return 1003 } 1004 1005 // Field returns a sub node at the given field id from a MESSAGE value. 1006 func (self Value) Field(id proto.FieldNumber) (v Value) { 1007 rootLayer := self.IsRoot 1008 msgDesc := self.Desc.Message() 1009 1010 n, d := self.Node.Field(id, rootLayer, msgDesc) 1011 1012 if n.IsError() { 1013 return wrapValue(n, nil) 1014 } 1015 return wrapValue(n, d.Type()) 1016 } 1017 1018 // GetMany searches transversely and returns all the sub nodes along with the given pathes. 1019 func (self Value) GetMany(pathes []PathNode, opts *Options) error { 1020 if len(pathes) == 0 { 1021 return nil 1022 } 1023 return self.getMany(pathes, opts.ClearDirtyValues, opts) 1024 } 1025 1026 func (self Value) getMany(pathes []PathNode, clearDirty bool, opts *Options) error { 1027 if clearDirty { 1028 for i := range pathes { 1029 pathes[i].Node = Node{} 1030 } 1031 } 1032 p := pathes[0] 1033 switch p.Path.t { 1034 case PathFieldId: 1035 return self.Fields(pathes, opts) 1036 case PathIndex: 1037 return self.Indexes(pathes, opts) 1038 case PathStrKey, PathIntKey, PathBinKey: 1039 return self.Gets(pathes, opts) 1040 default: 1041 return errValue(meta.ErrUnsupportedType, fmt.Sprintf("invalid path: %#v", p), nil) 1042 } 1043 } 1044 1045 func (self Value) Fields(ids []PathNode, opts *Options) error { 1046 rootLayer := self.IsRoot 1047 msgDesc := self.Desc.Message() 1048 1049 err := self.Node.Fields(ids, rootLayer, msgDesc, opts) 1050 return err 1051 } 1052 1053 // SetMany: set a list of sub nodes at the given pathes from the value. 1054 // root *Value: the root Node 1055 // self *Value: the current Node (maybe root Node) 1056 // address []int: the address from target Nodes to the root Node 1057 // path ...Path: the path from root Node to target Nodes 1058 func (self *Value) SetMany(pathes []PathNode, opts *Options, root *Value, address []int, path ...Path) (err error) { 1059 if len(pathes) == 0 { 1060 return nil 1061 } 1062 1063 if err := self.Check(); err != nil { 1064 return err 1065 } 1066 1067 // copy original pathes 1068 ps := pnsPool.Get().(*pnSlice) 1069 if cap(ps.a) < len(pathes) { 1070 ps.a = make([]PathNode, len(pathes)) 1071 } else { 1072 ps.a = ps.a[:len(pathes)] 1073 } 1074 copy(ps.a, pathes) 1075 ps.b = pathes 1076 originLen := len(self.raw()) // current buf length 1077 rootLen := len(root.raw()) // root buf length 1078 isPacked := self.Desc.IsPacked() 1079 1080 // get original values 1081 if err = self.getMany(ps.a, true, opts); err != nil { 1082 goto ret 1083 } 1084 1085 // handle not found values 1086 for i, a := range ps.a { 1087 if a.IsUnKnown() { 1088 var sp unsafe.Pointer 1089 if self.t.IsComplex() { 1090 sp = rt.AddPtr(self.v, uintptr(self.l)) 1091 } 1092 ps.a[i].Node = errNotFoundLast(sp, self.t) 1093 ps.a[i].Node.setNotFound(a.Path, &ps.b[i].Node, self.Desc) 1094 if self.t == proto.LIST || self.t == proto.MAP { 1095 self.size += 1 1096 } 1097 } 1098 } 1099 1100 // if current is not root node, update current Node length 1101 if !self.IsRoot { 1102 err = self.replaceMany(ps) 1103 if self.t == proto.LIST && isPacked { 1104 currentAdd := []int{0, -1} 1105 currentPath := []Path{NewPathIndex(-1), NewPathIndex(-1)} 1106 self.updateByteLen(originLen, currentAdd, isPacked, currentPath...) 1107 } else if self.t == proto.MESSAGE { 1108 buf := self.raw() 1109 _, lenOffset := protowire.ConsumeVarint(buf) 1110 byteLen := len(buf) - lenOffset 1111 newLen := protowire.AppendVarint(nil, uint64(byteLen)) 1112 // newLen + buf[lenOffset:] 1113 l0 := len(newLen) 1114 l1 := byteLen 1115 newBuf := make([]byte, l0+l1) 1116 copy(newBuf[:l0], newLen) 1117 copy(newBuf[l0:], buf[lenOffset:]) 1118 self.v = rt.GetBytePtr(newBuf) 1119 self.l = int(len(newBuf)) 1120 } 1121 } 1122 1123 // update root length 1124 err = root.replaceMany(ps) 1125 root.updateByteLen(rootLen, address, isPacked, path...) 1126 ret: 1127 ps.b = nil 1128 pnsPool.Put(ps) 1129 return 1130 }