github.com/m3db/m3@v1.5.0/src/dbnode/persist/fs/msgpack/decoder.go (about) 1 // Copyright (c) 2016 Uber Technologies, Inc 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE 20 21 package msgpack 22 23 import ( 24 "errors" 25 "fmt" 26 "io" 27 28 "github.com/m3db/m3/src/dbnode/persist" 29 "github.com/m3db/m3/src/dbnode/persist/schema" 30 "github.com/m3db/m3/src/x/pool" 31 32 "gopkg.in/vmihailenco/msgpack.v2" 33 ) 34 35 var ( 36 emptyIndexInfo schema.IndexInfo 37 emptyIndexSummariesInfo schema.IndexSummariesInfo 38 emptyIndexBloomFilterInfo schema.IndexBloomFilterInfo 39 emptyIndexEntry schema.IndexEntry 40 emptyIndexSummary schema.IndexSummary 41 emptyIndexSummaryToken IndexSummaryToken 42 emptyLogInfo schema.LogInfo 43 emptyLogEntry schema.LogEntry 44 emptyLogMetadata schema.LogMetadata 45 emptyLogEntryRemainingToken DecodeLogEntryRemainingToken 46 47 errorUnableToDetermineNumFieldsToSkip = errors.New("unable to determine num fields to skip") 48 errorCalledDecodeBytesWithoutByteStreamDecoder = errors.New("called decodeBytes without byte stream decoder") 49 errorIndexEntryChecksumMismatch = errors.New("decode index entry encountered checksum mismatch") 50 ) 51 52 // Decoder decodes persisted msgpack-encoded data 53 type Decoder struct { 54 reader DecoderStream 55 // Will only be set if the Decoder is Reset() with a DecoderStream 56 // that also implements ByteStream. 57 byteReader ByteStream 58 // Wraps original reader with reader that can calculate digest. Digest calculation must be enabled, 59 // otherwise it defaults to off. 60 readerWithDigest *decoderStreamWithDigest 61 hasher schema.IndexEntryHasher 62 dec *msgpack.Decoder 63 err error 64 allocDecodedBytes bool 65 66 legacy LegacyEncodingOptions 67 } 68 69 // NewDecoder creates a new decoder 70 func NewDecoder(opts DecodingOptions) *Decoder { 71 return newDecoder(DefaultLegacyEncodingOptions, opts) 72 } 73 74 func newDecoder(legacy LegacyEncodingOptions, opts DecodingOptions) *Decoder { 75 if opts == nil { 76 opts = NewDecodingOptions() 77 } 78 reader := NewByteDecoderStream(nil) 79 return &Decoder{ 80 allocDecodedBytes: opts.AllocDecodedBytes(), 81 reader: reader, 82 dec: msgpack.NewDecoder(reader), 83 legacy: legacy, 84 hasher: opts.IndexEntryHasher(), 85 readerWithDigest: newDecoderStreamWithDigest(nil), 86 } 87 } 88 89 // Reset resets the data stream to decode from 90 func (dec *Decoder) Reset(stream DecoderStream) { 91 dec.reader = stream 92 93 // Do the type assertion upfront so that we don't have to do it 94 // repeatedly later. 95 if byteStream, ok := stream.(ByteStream); ok { 96 dec.byteReader = byteStream 97 } else { 98 dec.byteReader = nil 99 } 100 101 dec.readerWithDigest.reset(dec.reader) 102 dec.dec.Reset(dec.readerWithDigest) 103 dec.err = nil 104 } 105 106 // DecodeIndexInfo decodes the index info 107 func (dec *Decoder) DecodeIndexInfo() (schema.IndexInfo, error) { 108 if dec.err != nil { 109 return emptyIndexInfo, dec.err 110 } 111 112 _, numFieldsToSkip := dec.decodeRootObject(indexInfoVersion, indexInfoType) 113 indexInfo := dec.decodeIndexInfo() 114 dec.skip(numFieldsToSkip) 115 if dec.err != nil { 116 return emptyIndexInfo, dec.err 117 } 118 return indexInfo, nil 119 } 120 121 // DecodeIndexEntry decodes index entry. 122 func (dec *Decoder) DecodeIndexEntry(bytesPool pool.BytesPool) (schema.IndexEntry, error) { 123 if dec.err != nil { 124 return emptyIndexEntry, dec.err 125 } 126 dec.readerWithDigest.setDigestReaderEnabled(true) 127 _, numFieldsToSkip := dec.decodeRootObject(indexEntryVersion, indexEntryType) 128 indexEntry := dec.decodeIndexEntry(bytesPool) 129 dec.readerWithDigest.setDigestReaderEnabled(false) 130 dec.skip(numFieldsToSkip) 131 if dec.err != nil { 132 return emptyIndexEntry, dec.err 133 } 134 return indexEntry, nil 135 } 136 137 // DecodeIndexSummary decodes index summary. 138 func (dec *Decoder) DecodeIndexSummary() ( 139 schema.IndexSummary, IndexSummaryToken, error) { 140 if dec.err != nil { 141 return emptyIndexSummary, emptyIndexSummaryToken, dec.err 142 } 143 _, numFieldsToSkip := dec.decodeRootObject(indexSummaryVersion, indexSummaryType) 144 indexSummary, indexSummaryMetadata := dec.decodeIndexSummary() 145 dec.skip(numFieldsToSkip) 146 if dec.err != nil { 147 return emptyIndexSummary, emptyIndexSummaryToken, dec.err 148 } 149 return indexSummary, indexSummaryMetadata, nil 150 } 151 152 // DecodeLogInfo decodes commit log info. 153 func (dec *Decoder) DecodeLogInfo() (schema.LogInfo, error) { 154 if dec.err != nil { 155 return emptyLogInfo, dec.err 156 } 157 _, numFieldsToSkip := dec.decodeRootObject(logInfoVersion, logInfoType) 158 logInfo := dec.decodeLogInfo() 159 dec.skip(numFieldsToSkip) 160 if dec.err != nil { 161 return emptyLogInfo, dec.err 162 } 163 return logInfo, nil 164 } 165 166 // DecodeLogEntry decodes commit log entry. 167 func (dec *Decoder) DecodeLogEntry() (schema.LogEntry, error) { 168 if dec.err != nil { 169 return emptyLogEntry, dec.err 170 } 171 _, numFieldsToSkip := dec.decodeRootObject(logEntryVersion, logEntryType) 172 logEntry := dec.decodeLogEntry() 173 dec.skip(numFieldsToSkip) 174 if dec.err != nil { 175 return emptyLogEntry, dec.err 176 } 177 return logEntry, nil 178 } 179 180 // DecodeLogEntryRemainingToken contains all the information that DecodeLogEntryRemaining 181 // requires to continue decoding a log entry after a call to DecodeLogEntryUniqueIndex. 182 type DecodeLogEntryRemainingToken struct { 183 numFieldsToSkip1 int 184 numFieldsToSkip2 int 185 } 186 187 // DecodeLogEntryUniqueIndex decodes a log entry as much as is required to return 188 // the series unique index. Call DecodeLogEntryRemaining afterwards to decode the 189 // remaining fields. 190 func (dec *Decoder) DecodeLogEntryUniqueIndex() (DecodeLogEntryRemainingToken, uint64, error) { 191 if dec.err != nil { 192 return emptyLogEntryRemainingToken, 0, dec.err 193 } 194 195 _, numFieldsToSkip1 := dec.decodeRootObject(logEntryVersion, logEntryType) 196 numFieldsToSkip2, _, ok := dec.checkNumFieldsFor(logEntryType, checkNumFieldsOptions{}) 197 if !ok { 198 return emptyLogEntryRemainingToken, 0, errorUnableToDetermineNumFieldsToSkip 199 } 200 idx := dec.decodeVarUint() 201 202 token := DecodeLogEntryRemainingToken{ 203 numFieldsToSkip1: numFieldsToSkip1, 204 numFieldsToSkip2: numFieldsToSkip2, 205 } 206 return token, idx, nil 207 } 208 209 // DecodeLogEntryRemaining can only be called after DecodeLogEntryUniqueIndex, 210 // and it returns a complete schema.LogEntry. 211 func (dec *Decoder) DecodeLogEntryRemaining(token DecodeLogEntryRemainingToken, index uint64) (schema.LogEntry, error) { 212 if dec.err != nil { 213 return emptyLogEntry, dec.err 214 } 215 216 var logEntry schema.LogEntry 217 logEntry.Index = index 218 logEntry.Create = dec.decodeVarint() 219 logEntry.Metadata, _, _ = dec.decodeBytes() 220 logEntry.Timestamp = dec.decodeVarint() 221 logEntry.Value = dec.decodeFloat64() 222 logEntry.Unit = uint32(dec.decodeVarUint()) 223 logEntry.Annotation, _, _ = dec.decodeBytes() 224 225 dec.skip(token.numFieldsToSkip1) 226 if dec.err != nil { 227 return emptyLogEntry, dec.err 228 } 229 dec.skip(token.numFieldsToSkip2) 230 if dec.err != nil { 231 return emptyLogEntry, dec.err 232 } 233 234 return logEntry, nil 235 } 236 237 // DecodeLogMetadata decodes commit log metadata. 238 func (dec *Decoder) DecodeLogMetadata() (schema.LogMetadata, error) { 239 if dec.err != nil { 240 return emptyLogMetadata, dec.err 241 } 242 _, numFieldsToSkip := dec.decodeRootObject(logMetadataVersion, logMetadataType) 243 logMetadata := dec.decodeLogMetadata() 244 dec.skip(numFieldsToSkip) 245 if dec.err != nil { 246 return emptyLogMetadata, dec.err 247 } 248 return logMetadata, nil 249 } 250 251 func (dec *Decoder) decodeIndexInfo() schema.IndexInfo { 252 var opts checkNumFieldsOptions 253 254 // Overrides only used to test forwards compatibility. 255 switch dec.legacy.DecodeLegacyIndexInfoVersion { 256 case LegacyEncodingIndexVersionV1: 257 // V1 had 6 fields. 258 opts.override = true 259 opts.numExpectedMinFields = 6 260 opts.numExpectedCurrFields = 6 261 case LegacyEncodingIndexVersionV2: 262 // V2 had 8 fields. 263 opts.override = true 264 opts.numExpectedMinFields = 6 265 opts.numExpectedCurrFields = 8 266 case LegacyEncodingIndexVersionV3: 267 // V3 had 9 fields. 268 opts.override = true 269 opts.numExpectedMinFields = 6 270 opts.numExpectedCurrFields = 9 271 case LegacyEncodingIndexVersionV4: 272 // V4 had 10 fields. 273 opts.override = true 274 opts.numExpectedMinFields = 6 275 opts.numExpectedCurrFields = 10 276 } 277 278 numFieldsToSkip, actual, ok := dec.checkNumFieldsFor(indexInfoType, opts) 279 if !ok { 280 return emptyIndexInfo 281 } 282 283 var indexInfo schema.IndexInfo 284 indexInfo.BlockStart = dec.decodeVarint() 285 indexInfo.BlockSize = dec.decodeVarint() 286 indexInfo.Entries = dec.decodeVarint() 287 indexInfo.MajorVersion = dec.decodeVarint() 288 indexInfo.Summaries = dec.decodeIndexSummariesInfo() 289 indexInfo.BloomFilter = dec.decodeIndexBloomFilterInfo() 290 291 // At this point if its a V1 file we've decoded all the available fields. 292 if dec.legacy.DecodeLegacyIndexInfoVersion == LegacyEncodingIndexVersionV1 || actual < 8 { 293 dec.skip(numFieldsToSkip) 294 return indexInfo 295 } 296 297 // Decode fields added in V2. 298 indexInfo.SnapshotTime = dec.decodeVarint() 299 indexInfo.FileType = persist.FileSetType(dec.decodeVarint()) 300 301 // At this point if its a V2 file we've decoded all the available fields. 302 if dec.legacy.DecodeLegacyIndexInfoVersion == LegacyEncodingIndexVersionV2 || actual < 9 { 303 dec.skip(numFieldsToSkip) 304 return indexInfo 305 } 306 307 // Decode fields added in V3. 308 indexInfo.SnapshotID, _, _ = dec.decodeBytes() 309 310 // At this point if its a V3 file we've decoded all the available fields. 311 if dec.legacy.DecodeLegacyIndexInfoVersion == LegacyEncodingIndexVersionV3 || actual < 10 { 312 dec.skip(numFieldsToSkip) 313 return indexInfo 314 } 315 316 // Decode fields added in V4. 317 indexInfo.VolumeIndex = int(dec.decodeVarint()) 318 319 // At this point if its a V4 file we've decoded all the available fields. 320 if dec.legacy.DecodeLegacyIndexInfoVersion == LegacyEncodingIndexVersionV4 || actual < 11 { 321 dec.skip(numFieldsToSkip) 322 return indexInfo 323 } 324 325 // Decode fields added in V5. 326 indexInfo.MinorVersion = dec.decodeVarint() 327 328 dec.skip(numFieldsToSkip) 329 return indexInfo 330 } 331 332 func (dec *Decoder) decodeIndexSummariesInfo() schema.IndexSummariesInfo { 333 numFieldsToSkip, _, ok := dec.checkNumFieldsFor(indexSummariesInfoType, checkNumFieldsOptions{}) 334 if !ok { 335 return emptyIndexSummariesInfo 336 } 337 var indexSummariesInfo schema.IndexSummariesInfo 338 indexSummariesInfo.Summaries = dec.decodeVarint() 339 dec.skip(numFieldsToSkip) 340 if dec.err != nil { 341 return emptyIndexSummariesInfo 342 } 343 return indexSummariesInfo 344 } 345 346 func (dec *Decoder) decodeIndexBloomFilterInfo() schema.IndexBloomFilterInfo { 347 numFieldsToSkip, _, ok := dec.checkNumFieldsFor(indexBloomFilterInfoType, checkNumFieldsOptions{}) 348 if !ok { 349 return emptyIndexBloomFilterInfo 350 } 351 var indexBloomFilterInfo schema.IndexBloomFilterInfo 352 indexBloomFilterInfo.NumElementsM = dec.decodeVarint() 353 indexBloomFilterInfo.NumHashesK = dec.decodeVarint() 354 dec.skip(numFieldsToSkip) 355 if dec.err != nil { 356 return emptyIndexBloomFilterInfo 357 } 358 return indexBloomFilterInfo 359 } 360 361 func (dec *Decoder) checkNumIndexEntryFields() (int, int, bool) { 362 var opts checkNumFieldsOptions 363 switch dec.legacy.DecodeLegacyIndexEntryVersion { 364 case LegacyEncodingIndexEntryVersionV1: 365 // V1 had 5 fields. 366 opts.override = true 367 opts.numExpectedMinFields = 5 368 opts.numExpectedCurrFields = 5 369 case LegacyEncodingIndexEntryVersionV2: 370 // V2 had 6 fields. 371 opts.override = true 372 opts.numExpectedMinFields = 5 373 opts.numExpectedCurrFields = 6 374 case LegacyEncodingIndexEntryVersionCurrent: 375 // V3 is current version, no overrides needed 376 break 377 default: 378 dec.err = fmt.Errorf("invalid legacyEncodingIndexEntryVersion provided: %v", 379 dec.legacy.DecodeLegacyIndexEntryVersion) 380 return 0, 0, false 381 } 382 383 return dec.checkNumFieldsFor(indexEntryType, opts) 384 } 385 386 func (dec *Decoder) decodeIndexEntry(bytesPool pool.BytesPool) schema.IndexEntry { 387 numFieldsToSkip, actual, ok := dec.checkNumIndexEntryFields() 388 if !ok { 389 return emptyIndexEntry 390 } 391 392 var indexEntry schema.IndexEntry 393 indexEntry.Index = dec.decodeVarint() 394 395 if bytesPool == nil { 396 indexEntry.ID, _, _ = dec.decodeBytes() 397 } else { 398 indexEntry.ID = dec.decodeBytesWithPool(bytesPool) 399 } 400 401 indexEntry.Size = dec.decodeVarint() 402 indexEntry.Offset = dec.decodeVarint() 403 indexEntry.DataChecksum = dec.decodeVarint() 404 405 // At this point, if its a V1 file, we've decoded all the available fields. 406 if dec.legacy.DecodeLegacyIndexEntryVersion == LegacyEncodingIndexEntryVersionV1 || actual < 6 { 407 dec.skip(numFieldsToSkip) 408 return indexEntry 409 } 410 411 // Decode fields added in V2 412 if bytesPool == nil { 413 indexEntry.EncodedTags, _, _ = dec.decodeBytes() 414 } else { 415 indexEntry.EncodedTags = dec.decodeBytesWithPool(bytesPool) 416 } 417 418 // At this point, if its a V2 file, we've decoded all the available fields. 419 if dec.legacy.DecodeLegacyIndexEntryVersion == LegacyEncodingIndexEntryVersionV2 || actual < 7 { 420 dec.skip(numFieldsToSkip) 421 return indexEntry 422 } 423 424 // NB(nate): Any new fields should be parsed here. 425 426 // Intentionally skip any extra fields here as we've stipulated that from V3 onward, IndexEntryChecksum will be the 427 // final field on index entries 428 dec.skip(numFieldsToSkip) 429 430 // Retrieve actual checksum value here. Attempting to retrieve after decoding the upcoming expected checksum field 431 // would include value in actual checksum calculation which would cause a mismatch 432 actualChecksum := dec.readerWithDigest.digest().Sum32() 433 434 // Decode checksum field originally added in V3 435 indexEntry.IndexChecksum = dec.decodeVarint() 436 if dec.err != nil { 437 dec.err = fmt.Errorf("decode index entry encountered error: %s", dec.err) 438 return emptyIndexEntry 439 } 440 441 if indexEntry.IndexChecksum != int64(actualChecksum) { 442 dec.err = errorIndexEntryChecksumMismatch 443 } 444 445 return indexEntry 446 } 447 448 func (dec *Decoder) decodeIndexSummary() (schema.IndexSummary, IndexSummaryToken) { 449 numFieldsToSkip, _, ok := dec.checkNumFieldsFor(indexSummaryType, checkNumFieldsOptions{}) 450 if !ok { 451 return emptyIndexSummary, emptyIndexSummaryToken 452 } 453 var ( 454 indexSummary schema.IndexSummary 455 idBytesStartOffset int 456 idBytesLength int 457 ) 458 indexSummary.Index = dec.decodeVarint() 459 // Keep track of the offset in the byte stream before we decode the bytes so 460 // that we know exactly where to jump to if we want to just grab the ID itself 461 indexSummary.ID, idBytesStartOffset, idBytesLength = dec.decodeBytes() 462 indexSummary.IndexEntryOffset = dec.decodeVarint() 463 dec.skip(numFieldsToSkip) 464 if dec.err != nil { 465 return emptyIndexSummary, emptyIndexSummaryToken 466 } 467 468 // Downscaling to uint32 is fine because summary files and ID length should 469 // be well below the max value of a uint32 470 indexSummaryToken := NewIndexSummaryToken( 471 uint32(idBytesStartOffset), uint32(idBytesLength), 472 ) 473 return indexSummary, indexSummaryToken 474 } 475 476 func (dec *Decoder) decodeLogInfo() schema.LogInfo { 477 numFieldsToSkip, _, ok := dec.checkNumFieldsFor(logInfoType, checkNumFieldsOptions{}) 478 if !ok { 479 return emptyLogInfo 480 } 481 var logInfo schema.LogInfo 482 483 // Deprecated, have to decode anyways for backwards compatibility, but we ignore the values. 484 logInfo.DeprecatedDoNotUseStart = dec.decodeVarint() 485 logInfo.DeprecatedDoNotUseDuration = dec.decodeVarint() 486 487 logInfo.Index = dec.decodeVarint() 488 dec.skip(numFieldsToSkip) 489 if dec.err != nil { 490 return emptyLogInfo 491 } 492 return logInfo 493 } 494 495 func (dec *Decoder) decodeLogEntry() schema.LogEntry { 496 numFieldsToSkip, _, ok := dec.checkNumFieldsFor(logEntryType, checkNumFieldsOptions{}) 497 if !ok { 498 return emptyLogEntry 499 } 500 var logEntry schema.LogEntry 501 logEntry.Index = dec.decodeVarUint() 502 logEntry.Create = dec.decodeVarint() 503 logEntry.Metadata, _, _ = dec.decodeBytes() 504 logEntry.Timestamp = dec.decodeVarint() 505 logEntry.Value = dec.decodeFloat64() 506 logEntry.Unit = uint32(dec.decodeVarUint()) 507 logEntry.Annotation, _, _ = dec.decodeBytes() 508 dec.skip(numFieldsToSkip) 509 if dec.err != nil { 510 return emptyLogEntry 511 } 512 return logEntry 513 } 514 515 func (dec *Decoder) decodeLogMetadata() schema.LogMetadata { 516 numFieldsToSkip, _, ok := dec.checkNumFieldsFor(logMetadataType, checkNumFieldsOptions{}) 517 if !ok { 518 return emptyLogMetadata 519 } 520 var logMetadata schema.LogMetadata 521 logMetadata.ID, _, _ = dec.decodeBytes() 522 logMetadata.Namespace, _, _ = dec.decodeBytes() 523 logMetadata.Shard = uint32(dec.decodeVarUint()) 524 logMetadata.EncodedTags, _, _ = dec.decodeBytes() 525 dec.skip(numFieldsToSkip) 526 if dec.err != nil { 527 return emptyLogMetadata 528 } 529 return logMetadata 530 } 531 532 func (dec *Decoder) decodeRootObject(expectedVersion int, expectedType objectType) (version int, numFieldsToSkip int) { 533 version = dec.checkVersion(expectedVersion) 534 if dec.err != nil { 535 return 0, 0 536 } 537 numFieldsToSkip, _, ok := dec.checkNumFieldsFor(rootObjectType, checkNumFieldsOptions{}) 538 if !ok { 539 return 0, 0 540 } 541 actualType := dec.decodeObjectType() 542 if dec.err != nil { 543 return 0, 0 544 } 545 if expectedType != actualType { 546 dec.err = fmt.Errorf("object type mismatch: expected %v actual %v", expectedType, actualType) 547 return 0, 0 548 } 549 return version, numFieldsToSkip 550 } 551 552 func (dec *Decoder) checkVersion(expected int) int { 553 version := int(dec.decodeVarint()) 554 if dec.err != nil { 555 return 0 556 } 557 if version > expected { 558 dec.err = fmt.Errorf("version mismatch: expected %v actual %v", expected, version) 559 return 0 560 } 561 562 return version 563 } 564 565 type checkNumFieldsOptions struct { 566 override bool 567 numExpectedMinFields int 568 numExpectedCurrFields int 569 } 570 571 func (dec *Decoder) checkNumFieldsFor( 572 objType objectType, 573 opts checkNumFieldsOptions, 574 ) (int, int, bool) { 575 actual := dec.decodeNumObjectFields() 576 if dec.err != nil { 577 return 0, 0, false 578 } 579 min, curr := numFieldsForType(objType) 580 if opts.override { 581 min = opts.numExpectedMinFields 582 curr = opts.numExpectedCurrFields 583 } 584 if min > actual { 585 dec.err = fmt.Errorf("number of fields mismatch: expected minimum of %d actual %d", min, actual) 586 return 0, 0, false 587 } 588 589 numToSkip := actual - curr 590 if numToSkip < 0 { 591 numToSkip = 0 592 } 593 return numToSkip, actual, true 594 } 595 596 func (dec *Decoder) skip(numFields int) { 597 if dec.err != nil { 598 return 599 } 600 if numFields < 0 { 601 dec.err = fmt.Errorf("number of fields to skip is %d", numFields) 602 return 603 } 604 for i := 0; i < numFields; i++ { 605 if err := dec.dec.Skip(); err != nil { 606 dec.err = err 607 return 608 } 609 } 610 } 611 612 func (dec *Decoder) decodeNumObjectFields() int { 613 return dec.decodeArrayLen() 614 } 615 616 func (dec *Decoder) decodeObjectType() objectType { 617 return objectType(dec.decodeVarint()) 618 } 619 620 func (dec *Decoder) decodeVarint() int64 { 621 if dec.err != nil { 622 return 0 623 } 624 value, err := dec.dec.DecodeInt64() 625 dec.err = err 626 return value 627 } 628 629 func (dec *Decoder) decodeVarUint() uint64 { 630 if dec.err != nil { 631 return 0 632 } 633 value, err := dec.dec.DecodeUint64() 634 dec.err = err 635 return value 636 } 637 638 func (dec *Decoder) decodeFloat64() float64 { 639 if dec.err != nil { 640 return 0.0 641 } 642 value, err := dec.dec.DecodeFloat64() 643 dec.err = err 644 return value 645 } 646 647 // Should only be called if dec.byteReader != nil. 648 func (dec *Decoder) decodeBytes() ([]byte, int, int) { 649 if dec.err != nil { 650 return nil, -1, -1 651 } 652 // If we need to allocate new space for decoded byte slice, we delegate it to msgpack 653 // API which allocates a new slice under the hood, otherwise we simply locate the byte 654 // slice as part of the encoded byte stream and return it 655 var value []byte 656 if dec.allocDecodedBytes { 657 value, dec.err = dec.dec.DecodeBytes() 658 return value, -1, -1 659 } 660 661 if dec.byteReader == nil { 662 // If we're not allowing the msgpack library to allocate the bytes and we haven't been 663 // provided a byte decoder stream, then we've reached an invalid state as its not 664 // possible for us to decode the bytes in an alloc-less way. 665 dec.err = errorCalledDecodeBytesWithoutByteStreamDecoder 666 return nil, -1, -1 667 } 668 669 var ( 670 bytesLen = dec.decodeBytesLen() 671 backingBytes = dec.byteReader.Bytes() 672 numBytes = len(backingBytes) 673 currPos = int(int64(numBytes) - dec.byteReader.Remaining()) 674 ) 675 676 if dec.err != nil { 677 return nil, -1, -1 678 } 679 // NB(xichen): DecodeBytesLen() returns -1 if the byte slice is nil 680 if bytesLen == -1 { 681 return nil, -1, -1 682 } 683 684 targetPos := currPos + bytesLen 685 if bytesLen < 0 || currPos < 0 || targetPos > numBytes { 686 dec.err = fmt.Errorf("invalid currPos %d, bytesLen %d, numBytes %d", currPos, bytesLen, numBytes) 687 return nil, -1, -1 688 } 689 if err := dec.byteReader.Skip(int64(bytesLen)); err != nil { 690 dec.err = err 691 return nil, -1, -1 692 } 693 value = backingBytes[currPos:targetPos] 694 if err := dec.readerWithDigest.capture(value); err != nil { 695 dec.err = err 696 return nil, -1, -1 697 } 698 699 return value, currPos, bytesLen 700 } 701 702 func (dec *Decoder) decodeBytesWithPool(bytesPool pool.BytesPool) []byte { 703 if dec.err != nil { 704 return nil 705 } 706 707 bytesLen := dec.decodeBytesLen() 708 if dec.err != nil { 709 return nil 710 } 711 if bytesLen < 0 { 712 return nil 713 } 714 715 bytes := bytesPool.Get(bytesLen)[:bytesLen] 716 n, err := io.ReadFull(dec.readerWithDigest, bytes) 717 if err != nil { 718 dec.err = err 719 bytesPool.Put(bytes) 720 return nil 721 } 722 if n != bytesLen { 723 // This check is redundant because io.ReadFull will return an error if 724 // its not able to read the specified number of bytes, but we keep it 725 // in for posterity. 726 dec.err = fmt.Errorf( 727 "tried to decode checked bytes of length: %d, but read: %d", 728 bytesLen, n) 729 bytesPool.Put(bytes) 730 return nil 731 } 732 733 return bytes 734 } 735 736 func (dec *Decoder) decodeArrayLen() int { 737 if dec.err != nil { 738 return 0 739 } 740 value, err := dec.dec.DecodeArrayLen() 741 dec.err = err 742 return value 743 } 744 745 func (dec *Decoder) decodeBytesLen() int { 746 if dec.err != nil { 747 return 0 748 } 749 value, err := dec.dec.DecodeBytesLen() 750 dec.err = err 751 return value 752 }