Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
duckdb::MiniZStreamWrapper Struct Reference
Inheritance diagram for duckdb::MiniZStreamWrapper:
Collaboration diagram for duckdb::MiniZStreamWrapper:

Public Member Functions

void Initialize (QueryContext context, CompressedFile &file, bool write) override
 
bool Read (StreamData &stream_data) override
 
void Write (CompressedFile &file, StreamData &stream_data, data_ptr_t buffer, int64_t nr_bytes) override
 
void Close () override
 
void FlushStream () const
 

Public Attributes

CompressedFilefile = nullptr
 
unique_ptr< duckdb_miniz::mz_streammz_stream_ptr
 
bool writing = false
 
duckdb_miniz::mz_ulong crc
 
idx_t total_size
 

Constructor & Destructor Documentation

◆ ~MiniZStreamWrapper()

duckdb::MiniZStreamWrapper::~MiniZStreamWrapper ( )
override
77374 {
77375 // avoid closing if destroyed during stack unwinding
77376 if (Exception::UncaughtException()) {
77377 return;
77378 }
77379 try {
77380 MiniZStreamWrapper::Close();
77381 } catch (std::exception &ex) {
77382 if (file && file->child_handle) {
77383 // FIXME: Make any log context available here.
77384 ErrorData data(ex);
77385 try {
77386 const auto logger = file->child_handle->logger;
77387 if (logger) {
77388 DUCKDB_LOG_ERROR(logger, "MiniZStreamWrapper::~MiniZStreamWrapper()\t\t" + data.Message())
77389 }
77390 } catch (...) { // NOLINT
77391 }
77392 }
77393 } catch (...) { // NOLINT
77394 }
77395}

Member Function Documentation

◆ Initialize()

void duckdb::MiniZStreamWrapper::Initialize ( QueryContext  context,
CompressedFile file,
bool  write 
)
overridevirtual

Implements duckdb::StreamWrapper.

77397 {
77398 Close();
77399 this->file = &file;
77400 mz_stream_ptr = make_uniq<duckdb_miniz::mz_stream>();
77401 memset(mz_stream_ptr.get(), 0, sizeof(duckdb_miniz::mz_stream));
77402 this->writing = write;
77403
77404 // TODO use custom alloc/free methods in miniz to throw exceptions on OOM
77405 uint8_t gzip_hdr[GZIP_HEADER_MINSIZE];
77406 if (write) {
77407 crc = MZ_CRC32_INIT;
77408 total_size = 0;
77409
77410 MiniZStream::InitializeGZIPHeader(gzip_hdr);
77411 file.child_handle->Write(context, gzip_hdr, GZIP_HEADER_MINSIZE);
77412
77413 auto ret = mz_deflateInit2(mz_stream_ptr.get(), duckdb_miniz::MZ_DEFAULT_LEVEL, MZ_DEFLATED,
77414 -MZ_DEFAULT_WINDOW_BITS, 1, 0);
77415 if (ret != duckdb_miniz::MZ_OK) {
77416 throw InternalException("Failed to initialize miniz");
77417 }
77418 } else {
77419 idx_t data_start = GZIP_HEADER_MINSIZE;
77420 auto read_count = file.child_handle->Read(context, gzip_hdr, GZIP_HEADER_MINSIZE);
77421 GZipFileSystem::VerifyGZIPHeader(gzip_hdr, NumericCast<idx_t>(read_count), &file);
77422 // Skip over the extra field if necessary
77423 if (gzip_hdr[3] & GZIP_FLAG_EXTRA) {
77424 uint8_t gzip_xlen[2];
77425 file.child_handle->Seek(data_start);
77426 file.child_handle->Read(context, gzip_xlen, 2);
77427 auto xlen = NumericCast<idx_t>((uint8_t)gzip_xlen[0] | (uint8_t)gzip_xlen[1] << 8);
77428 data_start += xlen + 2;
77429 }
77430 // Skip over the file name if necessary
77431 if (gzip_hdr[3] & GZIP_FLAG_NAME) {
77432 file.child_handle->Seek(data_start);
77433 data_start += GZipConsumeString(context, *file.child_handle);
77434 }
77435 file.child_handle->Seek(data_start);
77436 // stream is now set to beginning of payload data
77437 auto ret = duckdb_miniz::mz_inflateInit2(mz_stream_ptr.get(), -MZ_DEFAULT_WINDOW_BITS);
77438 if (ret != duckdb_miniz::MZ_OK) {
77439 throw InternalException("Failed to initialize miniz");
77440 }
77441 }
77442}
static void VerifyGZIPHeader(uint8_t gzip_hdr[], idx_t read_count, optional_ptr< CompressedFile > source_file)
Verifies that a buffer contains a valid GZIP header.
Definition duckdb.cpp:77607
void write(FileStorage &fs, const String &name, const optflow::GPCTree::Node &node)
::uint8_t uint8_t
Definition duckdb.cpp:76083

◆ Read()

bool duckdb::MiniZStreamWrapper::Read ( StreamData stream_data)
overridevirtual

Implements duckdb::StreamWrapper.

77444 {
77445 // Handling for the concatenated files
77446 if (sd.refresh) {
77447 auto available = static_cast<uint32_t>(sd.in_buff_end - sd.in_buff_start);
77448 if (available <= GZIP_FOOTER_SIZE) {
77449 // Only footer is available so we just close and return finished
77450 Close();
77451 return true;
77452 }
77453
77454 sd.refresh = false;
77455 auto body_ptr = sd.in_buff_start + GZIP_FOOTER_SIZE;
77456 uint8_t gzip_hdr[GZIP_HEADER_MINSIZE];
77457 memcpy(gzip_hdr, body_ptr, GZIP_HEADER_MINSIZE);
77458 GZipFileSystem::VerifyGZIPHeader(gzip_hdr, GZIP_HEADER_MINSIZE, nullptr);
77459 body_ptr += GZIP_HEADER_MINSIZE;
77460 if (gzip_hdr[3] & GZIP_FLAG_EXTRA) {
77461 auto xlen = NumericCast<idx_t>((uint8_t)*body_ptr | (uint8_t) * (body_ptr + 1) << 8);
77462 body_ptr += xlen + 2;
77463 if (GZIP_FOOTER_SIZE + GZIP_HEADER_MINSIZE + 2 + xlen >= GZIP_HEADER_MAXSIZE) {
77464 throw InternalException("Extra field resulting in GZIP header larger than defined maximum (%d)",
77465 GZIP_HEADER_MAXSIZE);
77466 }
77467 }
77468 if (gzip_hdr[3] & GZIP_FLAG_NAME) {
77469 char c;
77470 do {
77471 c = UnsafeNumericCast<char>(*body_ptr);
77472 body_ptr++;
77473 } while (c != '\0' && body_ptr < sd.in_buff_end);
77474 if (static_cast<idx_t>(body_ptr - sd.in_buff_start) >= GZIP_HEADER_MAXSIZE) {
77475 throw InternalException("Filename resulting in GZIP header larger than defined maximum (%d)",
77476 GZIP_HEADER_MAXSIZE);
77477 }
77478 }
77479 sd.in_buff_start = body_ptr;
77480 if (sd.in_buff_end - sd.in_buff_start < 1) {
77481 Close();
77482 return true;
77483 }
77484 duckdb_miniz::mz_inflateEnd(mz_stream_ptr.get());
77485 auto sta = duckdb_miniz::mz_inflateInit2(mz_stream_ptr.get(), -MZ_DEFAULT_WINDOW_BITS);
77486 if (sta != duckdb_miniz::MZ_OK) {
77487 throw InternalException("Failed to initialize miniz");
77488 }
77489 }
77490
77491 // actually decompress
77492 mz_stream_ptr->next_in = sd.in_buff_start;
77493 D_ASSERT(sd.in_buff_end - sd.in_buff_start < NumericLimits<int32_t>::Maximum());
77494 mz_stream_ptr->avail_in = static_cast<uint32_t>(sd.in_buff_end - sd.in_buff_start);
77495 mz_stream_ptr->next_out = data_ptr_cast(sd.out_buff_end);
77496 mz_stream_ptr->avail_out = static_cast<uint32_t>((sd.out_buff.get() + sd.out_buf_size) - sd.out_buff_end);
77497 auto ret = duckdb_miniz::mz_inflate(mz_stream_ptr.get(), duckdb_miniz::MZ_NO_FLUSH);
77498 if (ret != duckdb_miniz::MZ_OK && ret != duckdb_miniz::MZ_STREAM_END) {
77499 throw IOException("Failed to decode gzip stream: %s", duckdb_miniz::mz_error(ret));
77500 }
77501 // update pointers following inflate()
77502 sd.in_buff_start = (data_ptr_t)mz_stream_ptr->next_in; // NOLINT
77503 sd.in_buff_end = sd.in_buff_start + mz_stream_ptr->avail_in;
77504 sd.out_buff_end = data_ptr_cast(mz_stream_ptr->next_out);
77505 D_ASSERT(sd.out_buff_end + mz_stream_ptr->avail_out == sd.out_buff.get() + sd.out_buf_size);
77506
77507 // if stream ended, deallocate inflator
77508 if (ret == duckdb_miniz::MZ_STREAM_END) {
77509 // Concatenated GZIP potentially coming up - refresh input buffer
77510 sd.refresh = true;
77511 }
77512 return false;
77513}
::uint32_t uint32_t

◆ Write()

void duckdb::MiniZStreamWrapper::Write ( CompressedFile file,
StreamData stream_data,
data_ptr_t  buffer,
int64_t  nr_bytes 
)
overridevirtual

Implements duckdb::StreamWrapper.

77516 {
77517 // update the src and the total size
77518 crc = duckdb_miniz::mz_crc32(crc, reinterpret_cast<const unsigned char *>(uncompressed_data),
77519 UnsafeNumericCast<size_t>(uncompressed_size));
77520 total_size += UnsafeNumericCast<idx_t>(uncompressed_size);
77521
77522 auto remaining = uncompressed_size;
77523 while (remaining > 0) {
77524 auto output_remaining = UnsafeNumericCast<idx_t>((sd.out_buff.get() + sd.out_buf_size) - sd.out_buff_start);
77525
77526 mz_stream_ptr->next_in = reinterpret_cast<const unsigned char *>(uncompressed_data);
77527 mz_stream_ptr->avail_in = NumericCast<unsigned int>(remaining);
77528 mz_stream_ptr->next_out = sd.out_buff_start;
77529 mz_stream_ptr->avail_out = NumericCast<unsigned int>(output_remaining);
77530
77531 auto res = mz_deflate(mz_stream_ptr.get(), duckdb_miniz::MZ_NO_FLUSH);
77532 if (res != duckdb_miniz::MZ_OK) {
77533 D_ASSERT(res != duckdb_miniz::MZ_STREAM_END);
77534 throw InternalException("Failed to compress GZIP block");
77535 }
77536 sd.out_buff_start += output_remaining - mz_stream_ptr->avail_out;
77537 if (mz_stream_ptr->avail_out == 0) {
77538 // no more output buffer available: flush
77539 file.child_handle->Write(sd.out_buff.get(),
77540 UnsafeNumericCast<idx_t>(sd.out_buff_start - sd.out_buff.get()));
77541 sd.out_buff_start = sd.out_buff.get();
77542 }
77543 auto written = UnsafeNumericCast<idx_t>(remaining - mz_stream_ptr->avail_in);
77544 uncompressed_data += written;
77545 remaining = mz_stream_ptr->avail_in;
77546 }
77547}

◆ Close()

void duckdb::MiniZStreamWrapper::Close ( )
overridevirtual

Implements duckdb::StreamWrapper.

77574 {
77575 if (!mz_stream_ptr) {
77576 return;
77577 }
77578 if (writing) {
77579 // flush anything remaining in the stream
77580 FlushStream();
77581
77582 // write the footer
77583 unsigned char gzip_footer[MiniZStream::GZIP_FOOTER_SIZE];
77584 MiniZStream::InitializeGZIPFooter(gzip_footer, crc, total_size);
77585 file->child_handle->Write(gzip_footer, MiniZStream::GZIP_FOOTER_SIZE);
77586
77587 duckdb_miniz::mz_deflateEnd(mz_stream_ptr.get());
77588 } else {
77589 duckdb_miniz::mz_inflateEnd(mz_stream_ptr.get());
77590 }
77591 mz_stream_ptr = nullptr;
77592 file = nullptr;
77593}

◆ FlushStream()

void duckdb::MiniZStreamWrapper::FlushStream ( ) const
77549 {
77550 auto &sd = file->stream_data;
77551 mz_stream_ptr->next_in = nullptr;
77552 mz_stream_ptr->avail_in = 0;
77553 while (true) {
77554 auto output_remaining = (sd.out_buff.get() + sd.out_buf_size) - sd.out_buff_start;
77555 mz_stream_ptr->next_out = sd.out_buff_start;
77556 mz_stream_ptr->avail_out = NumericCast<unsigned int>(output_remaining);
77557
77558 auto res = mz_deflate(mz_stream_ptr.get(), duckdb_miniz::MZ_FINISH);
77559 sd.out_buff_start += (output_remaining - mz_stream_ptr->avail_out);
77560 if (sd.out_buff_start > sd.out_buff.get()) {
77561 file->child_handle->Write(sd.out_buff.get(),
77562 UnsafeNumericCast<idx_t>(sd.out_buff_start - sd.out_buff.get()));
77563 sd.out_buff_start = sd.out_buff.get();
77564 }
77565 if (res == duckdb_miniz::MZ_STREAM_END) {
77566 break;
77567 }
77568 if (res != duckdb_miniz::MZ_OK) {
77569 throw InternalException("Failed to compress GZIP block");
77570 }
77571 }
77572}

The documentation for this struct was generated from the following file: