github.com/ontio/ontology@v1.14.4/vm/neovm/types/neovm_value.go (about) 1 /* 2 * Copyright (C) 2018 The ontology Authors 3 * This file is part of The ontology library. 4 * 5 * The ontology is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * The ontology is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with The ontology. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 package types 20 21 import ( 22 "bytes" 23 "fmt" 24 "io" 25 "math" 26 "math/big" 27 "reflect" 28 "sort" 29 30 "github.com/ontio/ontology/common" 31 "github.com/ontio/ontology/common/log" 32 "github.com/ontio/ontology/vm/crossvm_codec" 33 "github.com/ontio/ontology/vm/neovm/constants" 34 "github.com/ontio/ontology/vm/neovm/errors" 35 ) 36 37 const ( 38 bytearrayType byte = 0x00 39 boolType byte = 0x01 40 integerType byte = 0x02 41 bigintType byte = 0x03 42 interopType byte = 0x40 43 arrayType byte = 0x80 44 structType byte = 0x81 45 mapType byte = 0x82 46 ) 47 48 const ( 49 MAX_COUNT = 1024 50 MAX_NOTIFY_LENGTH = 64 * 1024 //64Kb 51 ) 52 53 type VmValue struct { 54 valType byte 55 integer int64 56 bigInt *big.Int 57 byteArray []byte 58 structval *StructValue 59 array *ArrayValue 60 mapval *MapValue 61 interop InteropValue 62 } 63 64 func VmValueFromInt64(val int64) VmValue { 65 return VmValue{valType: integerType, integer: val} 66 } 67 68 func VmValueFromBytes(val []byte) (result VmValue, err error) { 69 if len(val) > constants.MAX_BYTEARRAY_SIZE { 70 err = errors.ERR_OVER_MAX_ITEM_SIZE 71 return 72 } 73 result.valType = bytearrayType 74 result.byteArray = val 75 return 76 } 77 78 func VmValueFromBool(val bool) VmValue { 79 if val { 80 return VmValue{valType: boolType, integer: 1} 81 } else { 82 return VmValue{valType: boolType, integer: 0} 83 } 84 } 85 86 func VmValueFromUint64(val uint64) VmValue { 87 if val <= math.MaxInt64 { 88 return VmValueFromInt64(int64(val)) 89 } 90 91 b := big.NewInt(0) 92 b.SetUint64(val) 93 return VmValue{valType: bigintType, bigInt: b} 94 } 95 96 func VmValueFromBigInt(val *big.Int) (result VmValue, err error) { 97 value, e := IntValFromBigInt(val) 98 if e != nil { 99 err = e 100 return 101 } 102 103 return VmValueFromIntValue(value), nil 104 } 105 106 func VmValueFromArrayVal(array *ArrayValue) VmValue { 107 return VmValue{valType: arrayType, array: array} 108 } 109 110 func VmValueFromStructVal(val *StructValue) VmValue { 111 return VmValue{valType: structType, structval: val} 112 } 113 114 func VmValueFromInteropValue(val InteropValue) VmValue { 115 return VmValue{valType: interopType, interop: val} 116 } 117 func VmValueFromMapValue(val *MapValue) VmValue { 118 return VmValue{valType: mapType, mapval: val} 119 } 120 121 func NewMapVmValue() VmValue { 122 return VmValue{valType: mapType, mapval: NewMapValue()} 123 } 124 125 func VmValueFromIntValue(val IntValue) VmValue { 126 if val.isbig { 127 return VmValue{valType: bigintType, bigInt: val.bigint} 128 } else { 129 return VmValue{valType: integerType, integer: val.integer} 130 } 131 } 132 133 func (self *VmValue) AsBytes() ([]byte, error) { 134 switch self.valType { 135 case boolType: 136 if self.integer == 0 { 137 return []byte{0}, nil 138 } else { 139 return []byte{1}, nil 140 } 141 case integerType: 142 return common.BigIntToNeoBytes(big.NewInt(self.integer)), nil 143 case bigintType: 144 return common.BigIntToNeoBytes(self.bigInt), nil 145 case bytearrayType: 146 return self.byteArray, nil 147 case arrayType, mapType, structType, interopType: 148 return nil, errors.ERR_BAD_TYPE 149 default: 150 panic("unreachable!") 151 } 152 } 153 154 func (self *VmValue) BuildParamToNative(sink *common.ZeroCopySink) error { 155 b, err := self.CircularRefAndDepthDetection() 156 if err != nil { 157 return err 158 } 159 if b { 160 return fmt.Errorf("runtime serialize: can not serialize circular reference data") 161 } 162 return self.buildParamToNative(sink) 163 } 164 165 func (self *VmValue) buildParamToNative(sink *common.ZeroCopySink) error { 166 switch self.valType { 167 case bytearrayType: 168 sink.WriteVarBytes(self.byteArray) 169 case boolType: 170 b, err := self.AsBool() 171 if err != nil { 172 return err 173 } 174 sink.WriteBool(b) 175 case integerType, bigintType: 176 bs, err := self.AsBytes() 177 if err != nil { 178 return err 179 } 180 sink.WriteVarBytes(bs) 181 case arrayType: 182 sink.WriteVarBytes(common.BigIntToNeoBytes(big.NewInt(int64(len(self.array.Data))))) 183 for _, v := range self.array.Data { 184 err := v.BuildParamToNative(sink) 185 if err != nil { 186 return err 187 } 188 } 189 case structType: 190 for _, v := range self.structval.Data { 191 err := v.BuildParamToNative(sink) 192 if err != nil { 193 return err 194 } 195 } 196 case mapType: 197 //TODO 198 return errors.ERR_BAD_TYPE 199 case interopType: 200 return errors.ERR_BAD_TYPE 201 default: 202 panic("unreachable!") 203 } 204 return nil 205 } 206 func (self *VmValue) ConvertNeoVmValueHexString() (interface{}, error) { 207 var count int 208 var length int 209 res, err := self.convertNeoVmValueHexString(&count, &length) 210 if err != nil { 211 return nil, err 212 } 213 if length > MAX_NOTIFY_LENGTH { 214 return nil, fmt.Errorf("length over max parameters convert length") 215 } 216 return res, nil 217 } 218 219 func (self *VmValue) convertNeoVmValueHexString(count *int, length *int) (interface{}, error) { 220 if *count > MAX_COUNT { 221 return nil, fmt.Errorf("over max parameters convert length") 222 } 223 if *length > MAX_NOTIFY_LENGTH { 224 return nil, fmt.Errorf("length over max parameters convert length") 225 } 226 switch self.valType { 227 case boolType: 228 boo, err := self.AsBool() 229 if err != nil { 230 return nil, err 231 } 232 *length++ 233 if boo { 234 return common.ToHexString([]byte{1}), nil 235 } else { 236 return common.ToHexString([]byte{0}), nil 237 } 238 case bytearrayType: 239 *length += len(self.byteArray) 240 return common.ToHexString(self.byteArray), nil 241 case integerType: 242 var bs []byte 243 if self.integer == 0 { 244 bs = []byte{0} 245 } else { 246 bs = common.BigIntToNeoBytes(big.NewInt(self.integer)) 247 } 248 *length += len(bs) 249 return common.ToHexString(bs), nil 250 case bigintType: 251 var bs []byte 252 if self.bigInt.Sign() == 0 { 253 bs = []byte{0} 254 } else { 255 bs = common.BigIntToNeoBytes(self.bigInt) 256 } 257 *length += len(bs) 258 return common.ToHexString(bs), nil 259 case structType: 260 var sstr []interface{} 261 for i := 0; i < len(self.structval.Data); i++ { 262 *count++ 263 t, err := self.structval.Data[i].convertNeoVmValueHexString(count, length) 264 if err != nil { 265 return nil, err 266 } 267 sstr = append(sstr, t) 268 } 269 return sstr, nil 270 case arrayType: 271 var sstr []interface{} 272 for i := 0; i < len(self.array.Data); i++ { 273 *count++ 274 t, err := self.array.Data[i].convertNeoVmValueHexString(count, length) 275 if err != nil { 276 return nil, err 277 } 278 sstr = append(sstr, t) 279 } 280 return sstr, nil 281 case interopType: 282 bs := self.interop.Data.ToArray() 283 *length += len(bs) 284 return common.ToHexString(bs), nil 285 default: 286 log.Errorf("[ConvertTypes] Invalid Types!, %x", self.valType) 287 return nil, fmt.Errorf("[ConvertTypes] Invalid Types!, %x", self.valType) 288 } 289 } 290 func (self *VmValue) Deserialize(source *common.ZeroCopySource) error { 291 return self.deserialize(source, 0) 292 } 293 294 func (self *VmValue) deserialize(source *common.ZeroCopySource, depth int) error { 295 if depth > MAX_COUNT { 296 return fmt.Errorf("vmvalue depth over the uplimit") 297 } 298 t, eof := source.NextByte() 299 if eof { 300 return io.ErrUnexpectedEOF 301 } 302 switch t { 303 case boolType: 304 b, irregular, eof := source.NextBool() 305 if eof { 306 return io.ErrUnexpectedEOF 307 } 308 if irregular { 309 return common.ErrIrregularData 310 } 311 *self = VmValueFromBool(b) 312 case bytearrayType: 313 data, _, irregular, eof := source.NextVarBytes() 314 if eof { 315 return io.ErrUnexpectedEOF 316 } 317 if irregular { 318 return common.ErrIrregularData 319 } 320 value, err := VmValueFromBytes(data) 321 if err != nil { 322 return err 323 } 324 *self = value 325 case integerType: 326 data, _, irregular, eof := source.NextVarBytes() 327 if eof { 328 return io.ErrUnexpectedEOF 329 } 330 if irregular { 331 return common.ErrIrregularData 332 } 333 value, err := VmValueFromBigInt(common.BigIntFromNeoBytes(data)) 334 if err != nil { 335 return err 336 } 337 *self = value 338 case arrayType: 339 l, _, irregular, eof := source.NextVarUint() 340 if eof { 341 return io.ErrUnexpectedEOF 342 } 343 if irregular { 344 return common.ErrIrregularData 345 } 346 arr := new(ArrayValue) 347 for i := 0; i < int(l); i++ { 348 v := VmValue{} 349 err := v.deserialize(source, depth+1) 350 if err != nil { 351 return err 352 } 353 err = arr.Append(v) 354 if err != nil { 355 return err 356 } 357 } 358 *self = VmValueFromArrayVal(arr) 359 case mapType: 360 l, _, irregular, eof := source.NextVarUint() 361 if eof { 362 return io.ErrUnexpectedEOF 363 } 364 if irregular { 365 return common.ErrIrregularData 366 } 367 mapValue := NewMapValue() 368 for i := 0; i < int(l); i++ { 369 keyValue := VmValue{} 370 err := keyValue.deserialize(source, depth+1) 371 if err != nil { 372 return err 373 } 374 v := VmValue{} 375 err = v.deserialize(source, depth+1) 376 if err != nil { 377 return err 378 } 379 err = mapValue.Set(keyValue, v) 380 if err != nil { 381 return err 382 } 383 } 384 *self = VmValueFromMapValue(mapValue) 385 case structType: 386 l, _, irregular, eof := source.NextVarUint() 387 if eof { 388 return io.ErrUnexpectedEOF 389 } 390 if irregular { 391 return common.ErrIrregularData 392 } 393 structValue := NewStructValue() 394 for i := 0; i < int(l); i++ { 395 v := VmValue{} 396 err := v.deserialize(source, depth+1) 397 if err != nil { 398 return err 399 } 400 err = structValue.Append(v) 401 if err != nil { 402 return err 403 } 404 } 405 *self = VmValueFromStructVal(structValue) 406 default: 407 return errors.ERR_BAD_TYPE 408 } 409 return nil 410 } 411 412 func (self *VmValue) Serialize(sink *common.ZeroCopySink) error { 413 b, err := self.CircularRefAndDepthDetection() 414 if err != nil { 415 return err 416 } 417 if b { 418 return fmt.Errorf("runtime serialize: can not serialize circular reference data") 419 } 420 switch self.valType { 421 case boolType: 422 sink.WriteByte(boolType) 423 boo, err := self.AsBool() 424 if err != nil { 425 return err 426 } 427 sink.WriteBool(boo) 428 case bytearrayType: 429 sink.WriteByte(bytearrayType) 430 sink.WriteVarBytes(self.byteArray) 431 case bigintType: 432 sink.WriteByte(integerType) 433 sink.WriteVarBytes(common.BigIntToNeoBytes(self.bigInt)) 434 case integerType: 435 sink.WriteByte(integerType) 436 t := big.NewInt(self.integer) 437 sink.WriteVarBytes(common.BigIntToNeoBytes(t)) 438 case arrayType: 439 sink.WriteByte(arrayType) 440 sink.WriteVarUint(uint64(len(self.array.Data))) 441 for i := 0; i < len(self.array.Data); i++ { 442 err := self.array.Data[i].Serialize(sink) 443 if err != nil { 444 return err 445 } 446 447 } 448 case mapType: 449 sink.WriteByte(mapType) 450 sink.WriteVarUint(uint64(len(self.mapval.Data))) 451 keys := self.mapval.getMapSortedKey() 452 for _, key := range keys { 453 val := self.mapval.Data[key] 454 keyVal := val[0] 455 err = keyVal.Serialize(sink) 456 if err != nil { 457 return err 458 } 459 value := val[1] 460 err = value.Serialize(sink) 461 if err != nil { 462 return err 463 } 464 } 465 case structType: 466 sink.WriteByte(structType) 467 sink.WriteVarUint(uint64(len(self.structval.Data))) 468 for _, item := range self.structval.Data { 469 err := item.Serialize(sink) 470 if err != nil { 471 return err 472 } 473 } 474 case interopType: 475 return fmt.Errorf("not support type: interopType") 476 default: 477 panic("unreachable!") 478 } 479 if sink.Size() > constants.MAX_BYTEARRAY_SIZE { 480 return fmt.Errorf("runtime serialize: can not serialize length over the uplimit") 481 } 482 return nil 483 } 484 485 func (self *VmValue) CircularRefAndDepthDetection() (bool, error) { 486 return self.circularRefAndDepthDetection(make(map[uintptr]bool), 0) 487 } 488 489 func (self *VmValue) circularRefAndDepthDetection(visited map[uintptr]bool, depth int) (bool, error) { 490 if depth > MAX_STRUCT_DEPTH { 491 return true, nil 492 } 493 switch self.valType { 494 case arrayType: 495 arr, err := self.AsArrayValue() 496 if err != nil { 497 return true, err 498 } 499 if len(arr.Data) == 0 { 500 return false, nil 501 } 502 p := reflect.ValueOf(arr.Data).Pointer() 503 if visited[p] { 504 return true, nil 505 } 506 visited[p] = true 507 for _, v := range arr.Data { 508 return v.circularRefAndDepthDetection(visited, depth+1) 509 } 510 delete(visited, p) 511 return false, nil 512 case structType: 513 s, err := self.AsStructValue() 514 if err != nil { 515 return true, err 516 } 517 if len(s.Data) == 0 { 518 return false, nil 519 } 520 521 p := reflect.ValueOf(s.Data).Pointer() 522 if visited[p] { 523 return true, nil 524 } 525 visited[p] = true 526 527 for _, v := range s.Data { 528 return v.circularRefAndDepthDetection(visited, depth+1) 529 } 530 531 delete(visited, p) 532 return false, nil 533 case mapType: 534 mp, err := self.AsMapValue() 535 if err != nil { 536 return true, err 537 } 538 p := reflect.ValueOf(mp.Data).Pointer() 539 if visited[p] { 540 return true, nil 541 } 542 visited[p] = true 543 for _, v := range mp.Data { 544 return v[1].circularRefAndDepthDetection(visited, depth+1) 545 } 546 delete(visited, p) 547 return false, nil 548 default: 549 return false, nil 550 } 551 } 552 553 func (self *VmValue) AsInt64() (int64, error) { 554 val, err := self.AsIntValue() 555 if err != nil { 556 return 0, err 557 } 558 if val.isbig { 559 if !val.bigint.IsInt64() { 560 return 0, errors.ERR_INTEGER_UNDERFLOW 561 } 562 return val.bigint.Int64(), nil 563 } 564 565 return val.integer, nil 566 } 567 568 // urgly hack: only used in cmp opcode to lift the 32byte limit of integer 569 func (self *VmValue) AsBigInt() (*big.Int, error) { 570 switch self.valType { 571 case integerType, boolType: 572 return big.NewInt(self.integer), nil 573 case bigintType: 574 return self.bigInt, nil 575 case bytearrayType: 576 value := common.BigIntFromNeoBytes(self.byteArray) 577 return value, nil 578 case arrayType, mapType, structType, interopType: 579 return nil, errors.ERR_BAD_TYPE 580 default: 581 panic("unreachable!") 582 } 583 } 584 585 func (self *VmValue) AsIntValue() (IntValue, error) { 586 switch self.valType { 587 case integerType, boolType: 588 return IntValFromInt(self.integer), nil 589 case bigintType: 590 return IntValFromBigInt(self.bigInt) 591 case bytearrayType: 592 return IntValFromNeoBytes(self.byteArray) 593 case arrayType, mapType, structType, interopType: 594 return IntValue{}, errors.ERR_BAD_TYPE 595 default: 596 panic("unreachable!") 597 } 598 } 599 600 func (self *VmValue) AsBool() (bool, error) { 601 switch self.valType { 602 case integerType, boolType: 603 return self.integer != 0, nil 604 case bigintType: 605 return self.bigInt.Sign() != 0, nil 606 case bytearrayType: 607 for _, b := range self.byteArray { 608 if b != 0 { 609 return true, nil 610 } 611 } 612 return false, nil 613 case structType, mapType: 614 return true, nil 615 case arrayType: 616 return false, errors.ERR_BAD_TYPE 617 case interopType: 618 return self.interop != InteropValue{}, nil 619 default: 620 panic("unreachable!") 621 } 622 } 623 624 func (self *VmValue) AsMapValue() (*MapValue, error) { 625 switch self.valType { 626 case mapType: 627 return self.mapval, nil 628 default: 629 return nil, errors.ERR_BAD_TYPE 630 } 631 } 632 633 func (self *VmValue) AsStructValue() (*StructValue, error) { 634 switch self.valType { 635 case structType: 636 return self.structval, nil 637 default: 638 return nil, errors.ERR_BAD_TYPE 639 } 640 } 641 642 func (self *VmValue) AsArrayValue() (*ArrayValue, error) { 643 switch self.valType { 644 case arrayType: 645 return self.array, nil 646 default: 647 return nil, errors.ERR_BAD_TYPE 648 } 649 } 650 651 func (self *VmValue) AsInteropValue() (InteropValue, error) { 652 switch self.valType { 653 case interopType: 654 return self.interop, nil 655 default: 656 return InteropValue{}, errors.ERR_BAD_TYPE 657 } 658 } 659 660 func (self *VmValue) Equals(other VmValue) bool { 661 v1, e1 := self.AsBytes() 662 v2, e2 := other.AsBytes() 663 if e1 == nil && e2 == nil { // both are primitive type 664 return bytes.Equal(v1, v2) 665 } 666 667 // here more than one are compound type 668 if self.valType != other.valType { 669 return false 670 } 671 672 switch self.valType { 673 case mapType: 674 return self.mapval == other.mapval 675 case structType: 676 // todo: fix inconsistence 677 return reflect.DeepEqual(self.structval, other.structval) 678 case arrayType: 679 return self.array == other.array 680 case interopType: 681 return self.interop.Equals(other.interop) 682 default: 683 panic("unreachable!") 684 } 685 } 686 687 func (self *VmValue) GetType() byte { 688 switch self.valType { 689 case integerType, bigintType: 690 return IntegerType 691 default: 692 return self.valType 693 } 694 } 695 696 func (self *VmValue) GetMapKey() (string, error) { 697 val, err := self.AsBytes() 698 if err != nil { 699 return "", err 700 } 701 return string(val), nil 702 } 703 704 //only for debug/testing 705 func (self *VmValue) Stringify() (string, error) { 706 b, err := self.CircularRefAndDepthDetection() 707 if err != nil { 708 return "", fmt.Errorf("error: %v", err) 709 } 710 if b { 711 return "", fmt.Errorf("error: can not serialize circular reference data") 712 } 713 return self.stringify(), nil 714 } 715 func (self *VmValue) stringify() string { 716 switch self.valType { 717 case boolType, bytearrayType, bigintType, integerType: 718 bs, _ := self.AsBytes() 719 if len(bs) == 0 { 720 bs = []byte{0} 721 } 722 return fmt.Sprintf("bytes(hex:%x)", bs) 723 case arrayType: 724 data := "" 725 for _, v := range self.array.Data { 726 data += v.stringify() + ", " 727 } 728 return fmt.Sprintf("array[%d]{%s}", len(self.array.Data), data) 729 case mapType: 730 keys := self.mapval.getMapSortedKey() 731 data := "" 732 for _, key := range keys { 733 v := self.mapval.Data[key][1] 734 data += fmt.Sprintf("%x: %s,", key, v.stringify()) 735 } 736 return fmt.Sprintf("map[%d]{%s}", len(self.mapval.Data), data) 737 case interopType: 738 ty := reflect.TypeOf(self.interop.Data).String() 739 return fmt.Sprintf("interop{type:%s}", ty) 740 case structType: 741 data := "" 742 for _, v := range self.structval.Data { 743 data += v.stringify() + ", " 744 } 745 return fmt.Sprintf("struct[%d]{%s}", len(self.structval.Data), data) 746 default: 747 panic("unreachable!") 748 } 749 return "" 750 } 751 752 //only for debug/testing 753 func (self *VmValue) Dump() string { 754 b, err := self.CircularRefAndDepthDetection() 755 if err != nil { 756 return fmt.Sprintf("error: %v", err) 757 } 758 if b { 759 return "error: can not serialize circular reference data" 760 } 761 return self.dump() 762 } 763 764 func (self *VmValue) dump() string { 765 switch self.valType { 766 case boolType: 767 bs, _ := self.AsBool() 768 return fmt.Sprintf("bool(%v)", bs) 769 case integerType: 770 return fmt.Sprintf("int(%d)", self.integer) 771 case bigintType: 772 return fmt.Sprintf("bigint(0x%x)", self.bigInt) 773 case bytearrayType: 774 return fmt.Sprintf("string(\"%s\")", self.byteArray) 775 case arrayType: 776 data := "" 777 for _, v := range self.array.Data { 778 data += v.dump() + ", " 779 } 780 return fmt.Sprintf("array[%d]{%s}", len(self.array.Data), data) 781 case mapType: 782 var unsortKey []string 783 for k := range self.mapval.Data { 784 unsortKey = append(unsortKey, k) 785 } 786 sort.Strings(unsortKey) 787 data := "" 788 for _, key := range unsortKey { 789 v := self.mapval.Data[key][1] 790 k := self.mapval.Data[key][0] 791 data += fmt.Sprintf("%s: %s,", k.dump(), v.dump()) 792 } 793 return fmt.Sprintf("map[%d]{%s}", len(self.mapval.Data), data) 794 case structType: 795 data := "" 796 for _, v := range self.structval.Data { 797 data += v.dump() + ", " 798 } 799 return fmt.Sprintf("struct[%d]{%s}", len(self.structval.Data), data) 800 case interopType: 801 return fmt.Sprintf("interop[%x]", self.interop.Data) 802 default: 803 panic("unreachable!") 804 } 805 return "" 806 } 807 808 //encode the neovm return vmval 809 //transform neovm contract result to encoded byte array 810 func BuildResultFromNeo(item VmValue, bf *common.ZeroCopySink) error { 811 if len(bf.Bytes()) > crossvm_codec.MAX_PARAM_LENGTH { 812 return fmt.Errorf("parameter buf is too long") 813 } 814 switch item.valType { 815 case bytearrayType: 816 bs := item.byteArray 817 crossvm_codec.EncodeBytes(bf, bs) 818 case integerType: 819 val := common.I128FromInt64(item.integer) 820 crossvm_codec.EncodeInt128(bf, val) 821 case bigintType: 822 val := item.bigInt 823 err := crossvm_codec.EncodeBigInt(bf, val) 824 if err != nil { 825 return err 826 } 827 case boolType: 828 val, err := item.AsBool() 829 if err != nil { 830 return err 831 } 832 crossvm_codec.EncodeBool(bf, val) 833 case arrayType: 834 val := item.array 835 if val == nil { 836 return fmt.Errorf("get array error") 837 } 838 bf.WriteByte(crossvm_codec.ListType) 839 bf.WriteUint32(uint32(len(val.Data))) 840 for _, si := range val.Data { 841 err := BuildResultFromNeo(si, bf) 842 if err != nil { 843 return err 844 } 845 } 846 847 default: 848 return fmt.Errorf("not a supported return type") 849 } 850 return nil 851 }