git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/mmdb/decoder.go (about) 1 package mmdb 2 3 import ( 4 "encoding/binary" 5 "math" 6 "math/big" 7 "reflect" 8 "sync" 9 ) 10 11 type decoder struct { 12 buffer []byte 13 } 14 15 type dataType int 16 17 const ( 18 _Extended dataType = iota 19 _Pointer 20 _String 21 _Float64 22 _Bytes 23 _Uint16 24 _Uint32 25 _Map 26 _Int32 27 _Uint64 28 _Uint128 29 _Slice 30 // We don't use the next two. They are placeholders. See the spec 31 // for more details. 32 _Container //nolint: deadcode, varcheck // above 33 _Marker //nolint: deadcode, varcheck // above 34 _Bool 35 _Float32 36 ) 37 38 const ( 39 // This is the value used in libmaxminddb. 40 maximumDataStructureDepth = 512 41 ) 42 43 func (d *decoder) decode(offset uint, result reflect.Value, depth int) (uint, error) { 44 if depth > maximumDataStructureDepth { 45 return 0, newInvalidDatabaseError( 46 "exceeded maximum data structure depth; database is likely corrupt", 47 ) 48 } 49 typeNum, size, newOffset, err := d.decodeCtrlData(offset) 50 if err != nil { 51 return 0, err 52 } 53 54 if typeNum != _Pointer && result.Kind() == reflect.Uintptr { 55 result.Set(reflect.ValueOf(uintptr(offset))) 56 return d.nextValueOffset(offset, 1) 57 } 58 return d.decodeFromType(typeNum, size, newOffset, result, depth+1) 59 } 60 61 func (d *decoder) decodeToDeserializer( 62 offset uint, 63 dser deserializer, 64 depth int, 65 getNext bool, 66 ) (uint, error) { 67 if depth > maximumDataStructureDepth { 68 return 0, newInvalidDatabaseError( 69 "exceeded maximum data structure depth; database is likely corrupt", 70 ) 71 } 72 skip, err := dser.ShouldSkip(uintptr(offset)) 73 if err != nil { 74 return 0, err 75 } 76 if skip { 77 if getNext { 78 return d.nextValueOffset(offset, 1) 79 } 80 return 0, nil 81 } 82 83 typeNum, size, newOffset, err := d.decodeCtrlData(offset) 84 if err != nil { 85 return 0, err 86 } 87 88 return d.decodeFromTypeToDeserializer(typeNum, size, newOffset, dser, depth+1) 89 } 90 91 func (d *decoder) decodeCtrlData(offset uint) (dataType, uint, uint, error) { 92 newOffset := offset + 1 93 if offset >= uint(len(d.buffer)) { 94 return 0, 0, 0, newOffsetError() 95 } 96 ctrlByte := d.buffer[offset] 97 98 typeNum := dataType(ctrlByte >> 5) 99 if typeNum == _Extended { 100 if newOffset >= uint(len(d.buffer)) { 101 return 0, 0, 0, newOffsetError() 102 } 103 typeNum = dataType(d.buffer[newOffset] + 7) 104 newOffset++ 105 } 106 107 var size uint 108 size, newOffset, err := d.sizeFromCtrlByte(ctrlByte, newOffset, typeNum) 109 return typeNum, size, newOffset, err 110 } 111 112 func (d *decoder) sizeFromCtrlByte( 113 ctrlByte byte, 114 offset uint, 115 typeNum dataType, 116 ) (uint, uint, error) { 117 size := uint(ctrlByte & 0x1f) 118 if typeNum == _Extended { 119 return size, offset, nil 120 } 121 122 var bytesToRead uint 123 if size < 29 { 124 return size, offset, nil 125 } 126 127 bytesToRead = size - 28 128 newOffset := offset + bytesToRead 129 if newOffset > uint(len(d.buffer)) { 130 return 0, 0, newOffsetError() 131 } 132 if size == 29 { 133 return 29 + uint(d.buffer[offset]), offset + 1, nil 134 } 135 136 sizeBytes := d.buffer[offset:newOffset] 137 138 switch { 139 case size == 30: 140 size = 285 + uintFromBytes(0, sizeBytes) 141 case size > 30: 142 size = uintFromBytes(0, sizeBytes) + 65821 143 } 144 return size, newOffset, nil 145 } 146 147 func (d *decoder) decodeFromType( 148 dtype dataType, 149 size uint, 150 offset uint, 151 result reflect.Value, 152 depth int, 153 ) (uint, error) { 154 result = indirect(result) 155 156 // For these types, size has a special meaning 157 switch dtype { 158 case _Bool: 159 return unmarshalBool(size, offset, result) 160 case _Map: 161 return d.unmarshalMap(size, offset, result, depth) 162 case _Pointer: 163 return d.unmarshalPointer(size, offset, result, depth) 164 case _Slice: 165 return d.unmarshalSlice(size, offset, result, depth) 166 } 167 168 // For the remaining types, size is the byte size 169 if offset+size > uint(len(d.buffer)) { 170 return 0, newOffsetError() 171 } 172 switch dtype { 173 case _Bytes: 174 return d.unmarshalBytes(size, offset, result) 175 case _Float32: 176 return d.unmarshalFloat32(size, offset, result) 177 case _Float64: 178 return d.unmarshalFloat64(size, offset, result) 179 case _Int32: 180 return d.unmarshalInt32(size, offset, result) 181 case _String: 182 return d.unmarshalString(size, offset, result) 183 case _Uint16: 184 return d.unmarshalUint(size, offset, result, 16) 185 case _Uint32: 186 return d.unmarshalUint(size, offset, result, 32) 187 case _Uint64: 188 return d.unmarshalUint(size, offset, result, 64) 189 case _Uint128: 190 return d.unmarshalUint128(size, offset, result) 191 default: 192 return 0, newInvalidDatabaseError("unknown type: %d", dtype) 193 } 194 } 195 196 func (d *decoder) decodeFromTypeToDeserializer( 197 dtype dataType, 198 size uint, 199 offset uint, 200 dser deserializer, 201 depth int, 202 ) (uint, error) { 203 // For these types, size has a special meaning 204 switch dtype { 205 case _Bool: 206 v, offset := decodeBool(size, offset) 207 return offset, dser.Bool(v) 208 case _Map: 209 return d.decodeMapToDeserializer(size, offset, dser, depth) 210 case _Pointer: 211 pointer, newOffset, err := d.decodePointer(size, offset) 212 if err != nil { 213 return 0, err 214 } 215 _, err = d.decodeToDeserializer(pointer, dser, depth, false) 216 return newOffset, err 217 case _Slice: 218 return d.decodeSliceToDeserializer(size, offset, dser, depth) 219 } 220 221 // For the remaining types, size is the byte size 222 if offset+size > uint(len(d.buffer)) { 223 return 0, newOffsetError() 224 } 225 switch dtype { 226 case _Bytes: 227 v, offset := d.decodeBytes(size, offset) 228 return offset, dser.Bytes(v) 229 case _Float32: 230 v, offset := d.decodeFloat32(size, offset) 231 return offset, dser.Float32(v) 232 case _Float64: 233 v, offset := d.decodeFloat64(size, offset) 234 return offset, dser.Float64(v) 235 case _Int32: 236 v, offset := d.decodeInt(size, offset) 237 return offset, dser.Int32(int32(v)) 238 case _String: 239 v, offset := d.decodeString(size, offset) 240 return offset, dser.String(v) 241 case _Uint16: 242 v, offset := d.decodeUint(size, offset) 243 return offset, dser.Uint16(uint16(v)) 244 case _Uint32: 245 v, offset := d.decodeUint(size, offset) 246 return offset, dser.Uint32(uint32(v)) 247 case _Uint64: 248 v, offset := d.decodeUint(size, offset) 249 return offset, dser.Uint64(v) 250 case _Uint128: 251 v, offset := d.decodeUint128(size, offset) 252 return offset, dser.Uint128(v) 253 default: 254 return 0, newInvalidDatabaseError("unknown type: %d", dtype) 255 } 256 } 257 258 func unmarshalBool(size, offset uint, result reflect.Value) (uint, error) { 259 if size > 1 { 260 return 0, newInvalidDatabaseError( 261 "the MaxMind DB file's data section contains bad data (bool size of %v)", 262 size, 263 ) 264 } 265 value, newOffset := decodeBool(size, offset) 266 267 switch result.Kind() { 268 case reflect.Bool: 269 result.SetBool(value) 270 return newOffset, nil 271 case reflect.Interface: 272 if result.NumMethod() == 0 { 273 result.Set(reflect.ValueOf(value)) 274 return newOffset, nil 275 } 276 } 277 return newOffset, newUnmarshalTypeError(value, result.Type()) 278 } 279 280 // indirect follows pointers and create values as necessary. This is 281 // heavily based on encoding/json as my original version had a subtle 282 // bug. This method should be considered to be licensed under 283 // https://golang.org/LICENSE 284 func indirect(result reflect.Value) reflect.Value { 285 for { 286 // Load value from interface, but only if the result will be 287 // usefully addressable. 288 if result.Kind() == reflect.Interface && !result.IsNil() { 289 e := result.Elem() 290 if e.Kind() == reflect.Ptr && !e.IsNil() { 291 result = e 292 continue 293 } 294 } 295 296 if result.Kind() != reflect.Ptr { 297 break 298 } 299 300 if result.IsNil() { 301 result.Set(reflect.New(result.Type().Elem())) 302 } 303 304 result = result.Elem() 305 } 306 return result 307 } 308 309 var sliceType = reflect.TypeOf([]byte{}) 310 311 func (d *decoder) unmarshalBytes(size, offset uint, result reflect.Value) (uint, error) { 312 value, newOffset := d.decodeBytes(size, offset) 313 314 switch result.Kind() { 315 case reflect.Slice: 316 if result.Type() == sliceType { 317 result.SetBytes(value) 318 return newOffset, nil 319 } 320 case reflect.Interface: 321 if result.NumMethod() == 0 { 322 result.Set(reflect.ValueOf(value)) 323 return newOffset, nil 324 } 325 } 326 return newOffset, newUnmarshalTypeError(value, result.Type()) 327 } 328 329 func (d *decoder) unmarshalFloat32(size, offset uint, result reflect.Value) (uint, error) { 330 if size != 4 { 331 return 0, newInvalidDatabaseError( 332 "the MaxMind DB file's data section contains bad data (float32 size of %v)", 333 size, 334 ) 335 } 336 value, newOffset := d.decodeFloat32(size, offset) 337 338 switch result.Kind() { 339 case reflect.Float32, reflect.Float64: 340 result.SetFloat(float64(value)) 341 return newOffset, nil 342 case reflect.Interface: 343 if result.NumMethod() == 0 { 344 result.Set(reflect.ValueOf(value)) 345 return newOffset, nil 346 } 347 } 348 return newOffset, newUnmarshalTypeError(value, result.Type()) 349 } 350 351 func (d *decoder) unmarshalFloat64(size, offset uint, result reflect.Value) (uint, error) { 352 if size != 8 { 353 return 0, newInvalidDatabaseError( 354 "the MaxMind DB file's data section contains bad data (float 64 size of %v)", 355 size, 356 ) 357 } 358 value, newOffset := d.decodeFloat64(size, offset) 359 360 switch result.Kind() { 361 case reflect.Float32, reflect.Float64: 362 if result.OverflowFloat(value) { 363 return 0, newUnmarshalTypeError(value, result.Type()) 364 } 365 result.SetFloat(value) 366 return newOffset, nil 367 case reflect.Interface: 368 if result.NumMethod() == 0 { 369 result.Set(reflect.ValueOf(value)) 370 return newOffset, nil 371 } 372 } 373 return newOffset, newUnmarshalTypeError(value, result.Type()) 374 } 375 376 func (d *decoder) unmarshalInt32(size, offset uint, result reflect.Value) (uint, error) { 377 if size > 4 { 378 return 0, newInvalidDatabaseError( 379 "the MaxMind DB file's data section contains bad data (int32 size of %v)", 380 size, 381 ) 382 } 383 value, newOffset := d.decodeInt(size, offset) 384 385 switch result.Kind() { 386 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 387 n := int64(value) 388 if !result.OverflowInt(n) { 389 result.SetInt(n) 390 return newOffset, nil 391 } 392 case reflect.Uint, 393 reflect.Uint8, 394 reflect.Uint16, 395 reflect.Uint32, 396 reflect.Uint64, 397 reflect.Uintptr: 398 n := uint64(value) 399 if !result.OverflowUint(n) { 400 result.SetUint(n) 401 return newOffset, nil 402 } 403 case reflect.Interface: 404 if result.NumMethod() == 0 { 405 result.Set(reflect.ValueOf(value)) 406 return newOffset, nil 407 } 408 } 409 return newOffset, newUnmarshalTypeError(value, result.Type()) 410 } 411 412 func (d *decoder) unmarshalMap( 413 size uint, 414 offset uint, 415 result reflect.Value, 416 depth int, 417 ) (uint, error) { 418 result = indirect(result) 419 switch result.Kind() { 420 default: 421 return 0, newUnmarshalTypeError("map", result.Type()) 422 case reflect.Struct: 423 return d.decodeStruct(size, offset, result, depth) 424 case reflect.Map: 425 return d.decodeMap(size, offset, result, depth) 426 case reflect.Interface: 427 if result.NumMethod() == 0 { 428 rv := reflect.ValueOf(make(map[string]any, size)) 429 newOffset, err := d.decodeMap(size, offset, rv, depth) 430 result.Set(rv) 431 return newOffset, err 432 } 433 return 0, newUnmarshalTypeError("map", result.Type()) 434 } 435 } 436 437 func (d *decoder) unmarshalPointer( 438 size, offset uint, 439 result reflect.Value, 440 depth int, 441 ) (uint, error) { 442 pointer, newOffset, err := d.decodePointer(size, offset) 443 if err != nil { 444 return 0, err 445 } 446 _, err = d.decode(pointer, result, depth) 447 return newOffset, err 448 } 449 450 func (d *decoder) unmarshalSlice( 451 size uint, 452 offset uint, 453 result reflect.Value, 454 depth int, 455 ) (uint, error) { 456 switch result.Kind() { 457 case reflect.Slice: 458 return d.decodeSlice(size, offset, result, depth) 459 case reflect.Interface: 460 if result.NumMethod() == 0 { 461 a := []any{} 462 rv := reflect.ValueOf(&a).Elem() 463 newOffset, err := d.decodeSlice(size, offset, rv, depth) 464 result.Set(rv) 465 return newOffset, err 466 } 467 } 468 return 0, newUnmarshalTypeError("array", result.Type()) 469 } 470 471 func (d *decoder) unmarshalString(size, offset uint, result reflect.Value) (uint, error) { 472 value, newOffset := d.decodeString(size, offset) 473 474 switch result.Kind() { 475 case reflect.String: 476 result.SetString(value) 477 return newOffset, nil 478 case reflect.Interface: 479 if result.NumMethod() == 0 { 480 result.Set(reflect.ValueOf(value)) 481 return newOffset, nil 482 } 483 } 484 return newOffset, newUnmarshalTypeError(value, result.Type()) 485 } 486 487 func (d *decoder) unmarshalUint( 488 size, offset uint, 489 result reflect.Value, 490 uintType uint, 491 ) (uint, error) { 492 if size > uintType/8 { 493 return 0, newInvalidDatabaseError( 494 "the MaxMind DB file's data section contains bad data (uint%v size of %v)", 495 uintType, 496 size, 497 ) 498 } 499 500 value, newOffset := d.decodeUint(size, offset) 501 502 switch result.Kind() { 503 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 504 n := int64(value) 505 if !result.OverflowInt(n) { 506 result.SetInt(n) 507 return newOffset, nil 508 } 509 case reflect.Uint, 510 reflect.Uint8, 511 reflect.Uint16, 512 reflect.Uint32, 513 reflect.Uint64, 514 reflect.Uintptr: 515 if !result.OverflowUint(value) { 516 result.SetUint(value) 517 return newOffset, nil 518 } 519 case reflect.Interface: 520 if result.NumMethod() == 0 { 521 result.Set(reflect.ValueOf(value)) 522 return newOffset, nil 523 } 524 } 525 return newOffset, newUnmarshalTypeError(value, result.Type()) 526 } 527 528 var bigIntType = reflect.TypeOf(big.Int{}) 529 530 func (d *decoder) unmarshalUint128(size, offset uint, result reflect.Value) (uint, error) { 531 if size > 16 { 532 return 0, newInvalidDatabaseError( 533 "the MaxMind DB file's data section contains bad data (uint128 size of %v)", 534 size, 535 ) 536 } 537 value, newOffset := d.decodeUint128(size, offset) 538 539 switch result.Kind() { 540 case reflect.Struct: 541 if result.Type() == bigIntType { 542 result.Set(reflect.ValueOf(*value)) 543 return newOffset, nil 544 } 545 case reflect.Interface: 546 if result.NumMethod() == 0 { 547 result.Set(reflect.ValueOf(value)) 548 return newOffset, nil 549 } 550 } 551 return newOffset, newUnmarshalTypeError(value, result.Type()) 552 } 553 554 func decodeBool(size, offset uint) (bool, uint) { 555 return size != 0, offset 556 } 557 558 func (d *decoder) decodeBytes(size, offset uint) ([]byte, uint) { 559 newOffset := offset + size 560 bytes := make([]byte, size) 561 copy(bytes, d.buffer[offset:newOffset]) 562 return bytes, newOffset 563 } 564 565 func (d *decoder) decodeFloat64(size, offset uint) (float64, uint) { 566 newOffset := offset + size 567 bits := binary.BigEndian.Uint64(d.buffer[offset:newOffset]) 568 return math.Float64frombits(bits), newOffset 569 } 570 571 func (d *decoder) decodeFloat32(size, offset uint) (float32, uint) { 572 newOffset := offset + size 573 bits := binary.BigEndian.Uint32(d.buffer[offset:newOffset]) 574 return math.Float32frombits(bits), newOffset 575 } 576 577 func (d *decoder) decodeInt(size, offset uint) (int, uint) { 578 newOffset := offset + size 579 var val int32 580 for _, b := range d.buffer[offset:newOffset] { 581 val = (val << 8) | int32(b) 582 } 583 return int(val), newOffset 584 } 585 586 func (d *decoder) decodeMap( 587 size uint, 588 offset uint, 589 result reflect.Value, 590 depth int, 591 ) (uint, error) { 592 if result.IsNil() { 593 result.Set(reflect.MakeMapWithSize(result.Type(), int(size))) 594 } 595 596 mapType := result.Type() 597 keyValue := reflect.New(mapType.Key()).Elem() 598 elemType := mapType.Elem() 599 elemKind := elemType.Kind() 600 var elemValue reflect.Value 601 for i := uint(0); i < size; i++ { 602 var key []byte 603 var err error 604 key, offset, err = d.decodeKey(offset) 605 606 if err != nil { 607 return 0, err 608 } 609 610 if !elemValue.IsValid() || elemKind == reflect.Interface { 611 elemValue = reflect.New(elemType).Elem() 612 } 613 614 offset, err = d.decode(offset, elemValue, depth) 615 if err != nil { 616 return 0, err 617 } 618 619 keyValue.SetString(string(key)) 620 result.SetMapIndex(keyValue, elemValue) 621 } 622 return offset, nil 623 } 624 625 func (d *decoder) decodeMapToDeserializer( 626 size uint, 627 offset uint, 628 dser deserializer, 629 depth int, 630 ) (uint, error) { 631 err := dser.StartMap(size) 632 if err != nil { 633 return 0, err 634 } 635 for i := uint(0); i < size; i++ { 636 // TODO - implement key/value skipping? 637 offset, err = d.decodeToDeserializer(offset, dser, depth, true) 638 if err != nil { 639 return 0, err 640 } 641 642 offset, err = d.decodeToDeserializer(offset, dser, depth, true) 643 if err != nil { 644 return 0, err 645 } 646 } 647 err = dser.End() 648 if err != nil { 649 return 0, err 650 } 651 return offset, nil 652 } 653 654 func (d *decoder) decodePointer( 655 size uint, 656 offset uint, 657 ) (uint, uint, error) { 658 pointerSize := ((size >> 3) & 0x3) + 1 659 newOffset := offset + pointerSize 660 if newOffset > uint(len(d.buffer)) { 661 return 0, 0, newOffsetError() 662 } 663 pointerBytes := d.buffer[offset:newOffset] 664 var prefix uint 665 if pointerSize == 4 { 666 prefix = 0 667 } else { 668 prefix = size & 0x7 669 } 670 unpacked := uintFromBytes(prefix, pointerBytes) 671 672 var pointerValueOffset uint 673 switch pointerSize { 674 case 1: 675 pointerValueOffset = 0 676 case 2: 677 pointerValueOffset = 2048 678 case 3: 679 pointerValueOffset = 526336 680 case 4: 681 pointerValueOffset = 0 682 } 683 684 pointer := unpacked + pointerValueOffset 685 686 return pointer, newOffset, nil 687 } 688 689 func (d *decoder) decodeSlice( 690 size uint, 691 offset uint, 692 result reflect.Value, 693 depth int, 694 ) (uint, error) { 695 result.Set(reflect.MakeSlice(result.Type(), int(size), int(size))) 696 for i := 0; i < int(size); i++ { 697 var err error 698 offset, err = d.decode(offset, result.Index(i), depth) 699 if err != nil { 700 return 0, err 701 } 702 } 703 return offset, nil 704 } 705 706 func (d *decoder) decodeSliceToDeserializer( 707 size uint, 708 offset uint, 709 dser deserializer, 710 depth int, 711 ) (uint, error) { 712 err := dser.StartSlice(size) 713 if err != nil { 714 return 0, err 715 } 716 for i := uint(0); i < size; i++ { 717 offset, err = d.decodeToDeserializer(offset, dser, depth, true) 718 if err != nil { 719 return 0, err 720 } 721 } 722 err = dser.End() 723 if err != nil { 724 return 0, err 725 } 726 return offset, nil 727 } 728 729 func (d *decoder) decodeString(size, offset uint) (string, uint) { 730 newOffset := offset + size 731 return string(d.buffer[offset:newOffset]), newOffset 732 } 733 734 func (d *decoder) decodeStruct( 735 size uint, 736 offset uint, 737 result reflect.Value, 738 depth int, 739 ) (uint, error) { 740 fields := cachedFields(result) 741 742 // This fills in embedded structs 743 for _, i := range fields.anonymousFields { 744 _, err := d.unmarshalMap(size, offset, result.Field(i), depth) 745 if err != nil { 746 return 0, err 747 } 748 } 749 750 // This handles named fields 751 for i := uint(0); i < size; i++ { 752 var ( 753 err error 754 key []byte 755 ) 756 key, offset, err = d.decodeKey(offset) 757 if err != nil { 758 return 0, err 759 } 760 // The string() does not create a copy due to this compiler 761 // optimization: https://github.com/golang/go/issues/3512 762 j, ok := fields.namedFields[string(key)] 763 if !ok { 764 offset, err = d.nextValueOffset(offset, 1) 765 if err != nil { 766 return 0, err 767 } 768 continue 769 } 770 771 offset, err = d.decode(offset, result.Field(j), depth) 772 if err != nil { 773 return 0, err 774 } 775 } 776 return offset, nil 777 } 778 779 type fieldsType struct { 780 namedFields map[string]int 781 anonymousFields []int 782 } 783 784 var fieldsMap sync.Map 785 786 func cachedFields(result reflect.Value) *fieldsType { 787 resultType := result.Type() 788 789 if fields, ok := fieldsMap.Load(resultType); ok { 790 return fields.(*fieldsType) 791 } 792 numFields := resultType.NumField() 793 namedFields := make(map[string]int, numFields) 794 var anonymous []int 795 for i := 0; i < numFields; i++ { 796 field := resultType.Field(i) 797 798 fieldName := field.Name 799 if tag := field.Tag.Get("maxminddb"); tag != "" { 800 if tag == "-" { 801 continue 802 } 803 fieldName = tag 804 } 805 if field.Anonymous { 806 anonymous = append(anonymous, i) 807 continue 808 } 809 namedFields[fieldName] = i 810 } 811 fields := &fieldsType{namedFields, anonymous} 812 fieldsMap.Store(resultType, fields) 813 814 return fields 815 } 816 817 func (d *decoder) decodeUint(size, offset uint) (uint64, uint) { 818 newOffset := offset + size 819 bytes := d.buffer[offset:newOffset] 820 821 var val uint64 822 for _, b := range bytes { 823 val = (val << 8) | uint64(b) 824 } 825 return val, newOffset 826 } 827 828 func (d *decoder) decodeUint128(size, offset uint) (*big.Int, uint) { 829 newOffset := offset + size 830 val := new(big.Int) 831 val.SetBytes(d.buffer[offset:newOffset]) 832 833 return val, newOffset 834 } 835 836 func uintFromBytes(prefix uint, uintBytes []byte) uint { 837 val := prefix 838 for _, b := range uintBytes { 839 val = (val << 8) | uint(b) 840 } 841 return val 842 } 843 844 // decodeKey decodes a map key into []byte slice. We use a []byte so that we 845 // can take advantage of https://github.com/golang/go/issues/3512 to avoid 846 // copying the bytes when decoding a struct. Previously, we achieved this by 847 // using unsafe. 848 func (d *decoder) decodeKey(offset uint) ([]byte, uint, error) { 849 typeNum, size, dataOffset, err := d.decodeCtrlData(offset) 850 if err != nil { 851 return nil, 0, err 852 } 853 if typeNum == _Pointer { 854 pointer, ptrOffset, err := d.decodePointer(size, dataOffset) 855 if err != nil { 856 return nil, 0, err 857 } 858 key, _, err := d.decodeKey(pointer) 859 return key, ptrOffset, err 860 } 861 if typeNum != _String { 862 return nil, 0, newInvalidDatabaseError("unexpected type when decoding string: %v", typeNum) 863 } 864 newOffset := dataOffset + size 865 if newOffset > uint(len(d.buffer)) { 866 return nil, 0, newOffsetError() 867 } 868 return d.buffer[dataOffset:newOffset], newOffset, nil 869 } 870 871 // This function is used to skip ahead to the next value without decoding 872 // the one at the offset passed in. The size bits have different meanings for 873 // different data types. 874 func (d *decoder) nextValueOffset(offset, numberToSkip uint) (uint, error) { 875 if numberToSkip == 0 { 876 return offset, nil 877 } 878 typeNum, size, offset, err := d.decodeCtrlData(offset) 879 if err != nil { 880 return 0, err 881 } 882 switch typeNum { 883 case _Pointer: 884 _, offset, err = d.decodePointer(size, offset) 885 if err != nil { 886 return 0, err 887 } 888 case _Map: 889 numberToSkip += 2 * size 890 case _Slice: 891 numberToSkip += size 892 case _Bool: 893 default: 894 offset += size 895 } 896 return d.nextValueOffset(offset, numberToSkip-1) 897 }