MCPcopy Create free account
hub / github.com/apache/impala / SnappyBlockDecompress

Function SnappyBlockDecompress

be/src/util/decompress.cc:443–510  ·  view source on GitHub ↗

Utility function to decompress snappy block compressed data. If size_only is true, this function does not decompress but only computes the output size and writes the result to *output_len. If size_only is false, output buffer size must be at least *output_len. *output_len is updated with the actual output size if the decompression succeeds, and is set to 0 otherwise. size_only is an O(1) operatio

Source from the content-addressed store, hash-verified

441// otherwise.
442// size_only is an O(1) operation (just reads a single varint for each snappy block).
443static Status SnappyBlockDecompress(int64_t input_len, const uint8_t* input,
444 bool size_only, int64_t* output_len, char* output) {
445 int64_t buffer_size = *output_len;
446 *output_len = 0;
447 int64_t uncompressed_total_len = 0;
448 while (input_len > 0) {
449 uint32_t uncompressed_block_len = ReadWriteUtil::GetInt<uint32_t>(input);
450 input += sizeof(uint32_t);
451 input_len -= sizeof(uint32_t);
452
453 if (!size_only) {
454 int64_t remaining_output_size = buffer_size - uncompressed_total_len;
455 if (remaining_output_size < uncompressed_block_len) {
456 return Status(TErrorCode::SNAPPY_DECOMPRESS_DECOMPRESS_SIZE_INCORRECT);
457 }
458 }
459
460 while (uncompressed_block_len > 0) {
461 // Check that input length should not be negative.
462 if (input_len < 0) {
463 stringstream ss;
464 ss << " Corruption snappy decomp input_len " << input_len;
465 return Status(ss.str());
466 }
467 // Read the length of the next snappy compressed block.
468 size_t compressed_len = ReadWriteUtil::GetInt<uint32_t>(input);
469 input += sizeof(uint32_t);
470 input_len -= sizeof(uint32_t);
471
472 if (compressed_len == 0 || compressed_len > input_len) {
473 return Status(TErrorCode::SNAPPY_DECOMPRESS_INVALID_COMPRESSED_LENGTH);
474 }
475
476 // Read how big the output will be.
477 size_t uncompressed_len;
478 if (!snappy::GetUncompressedLength(reinterpret_cast<const char*>(input),
479 compressed_len, &uncompressed_len)) {
480 return Status(TErrorCode::SNAPPY_DECOMPRESS_UNCOMPRESSED_LENGTH_FAILED);
481 }
482 // Check that uncompressed length should be greater than 0.
483 if (uncompressed_len <= 0) {
484 return Status(TErrorCode::SNAPPY_DECOMPRESS_UNCOMPRESSED_LENGTH_FAILED);
485 }
486 DCHECK_GT(uncompressed_len, 0);
487
488 if (!size_only) {
489 // Check output bounds
490 int64_t remaining_output_size = buffer_size - uncompressed_total_len;
491 if (remaining_output_size < uncompressed_len) {
492 return Status(TErrorCode::SNAPPY_DECOMPRESS_DECOMPRESS_SIZE_INCORRECT);
493 }
494 // Decompress this snappy block
495 if (!snappy::RawUncompress(reinterpret_cast<const char*>(input),
496 compressed_len, output)) {
497 return Status(TErrorCode::SNAPPY_DECOMPRESS_RAW_UNCOMPRESS_FAILED);
498 }
499 output += uncompressed_len;
500 }

Callers 1

ProcessBlockMethod · 0.85

Calls 3

OKFunction · 0.85
StatusClass · 0.70
strMethod · 0.45

Tested by

no test coverage detected