Skip to content

Commit

Permalink
Make unit test pass
Browse files Browse the repository at this point in the history
  • Loading branch information
Bill-hbrhbr committed Nov 25, 2024
1 parent dceb564 commit d5af274
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 92 deletions.
72 changes: 30 additions & 42 deletions components/core/src/clp/streaming_compression/lzma/Compressor.cpp
Original file line number Diff line number Diff line change
@@ -1,34 +1,22 @@
#include "Compressor.hpp"

// spdlog
#include <spdlog/spdlog.h>

// Compression libraries
#include <lzma.h>
#include <zlib.h>

// Project headers
#include "../../Defs.h"

// File-scope constants
static constexpr size_t cCompressedStreamBlockBufferSize = 4096; // 4KiB

namespace streaming_compression::lzma {
namespace clp::streaming_compression::lzma {
Compressor::LzmaOption Compressor::m_option;

Compressor::Compressor()
: ::streaming_compression::Compressor(CompressorType::LZMA),
m_compression_stream_contains_data(false),
m_compressed_stream_file_writer(nullptr),
m_compression_stream(nullptr) {
m_compressed_stream_block_buffer = std::make_unique<Bytef[]>(cCompressedStreamBlockBufferSize);
m_compression_stream = new lzma_stream;
memset(m_compression_stream, 0, sizeof(lzma_stream));
}

Compressor::~Compressor() {
if (nullptr != m_compression_stream) {
delete m_compression_stream;
}
Compressor::Compressor() {
memset(m_compression_stream.get(), 0, sizeof(LzmaStream));
}

void Compressor::init_lzma_encoder(lzma_stream* strm) {
void Compressor::init_lzma_encoder(LzmaStream* strm) {
lzma_options_lzma options;
if (lzma_lzma_preset(&options, m_option.get_compression_level())) {
SPDLOG_ERROR("Failed to initialize LZMA options.");
Expand All @@ -44,10 +32,10 @@ void Compressor::init_lzma_encoder(lzma_stream* strm) {
// to CRC64, which is the default in the xz command line tool. If
// the .xz file needs to be decompressed with XZ Embedded, use
// LZMA_CHECK_CRC32 instead.
lzma_ret ret = lzma_stream_encoder(strm, filters, LZMA_CHECK_CRC64);
auto const ret = lzma_stream_encoder(strm, filters, LZMA_CHECK_CRC64);

// Return successfully if the initialization went fine.
if (ret == LZMA_OK) {
if (LZMA_OK == ret) {
return;
}

Expand Down Expand Up @@ -96,12 +84,12 @@ void Compressor::open(FileWriter& file_writer, int compression_level) {
m_option.set_compression_level(compression_level);
}

init_lzma_encoder(m_compression_stream);
init_lzma_encoder(m_compression_stream.get());
// Setup compressed stream parameters
m_compression_stream->next_in = nullptr;
m_compression_stream->avail_in = 0;
m_compression_stream->next_out = m_compressed_stream_block_buffer.get();
m_compression_stream->avail_out = cCompressedStreamBlockBufferSize;
m_compression_stream->next_out = m_compressed_stream_block_buffer.data();
m_compression_stream->avail_out = m_compressed_stream_block_buffer.size();

m_compressed_stream_file_writer = &file_writer;

Expand Down Expand Up @@ -136,7 +124,7 @@ void Compressor::write(char const* data, size_t data_length) {
// Compress all data
bool hit_input_eof = false;
while (!hit_input_eof) {
lzma_ret return_value = lzma_code(m_compression_stream, action);
auto const return_value = lzma_code(m_compression_stream.get(), action);
switch (return_value) {
case LZMA_OK:
case LZMA_BUF_ERROR:
Expand All @@ -157,21 +145,21 @@ void Compressor::write(char const* data, size_t data_length) {
// Write output buffer to file if it's full
if (0 == m_compression_stream->avail_out) {
m_compressed_stream_file_writer->write(
reinterpret_cast<char*>(m_compressed_stream_block_buffer.get()),
reinterpret_cast<char*>(m_compressed_stream_block_buffer.data()),
cCompressedStreamBlockBufferSize
);
m_compression_stream->next_out = m_compressed_stream_block_buffer.get();
m_compression_stream->next_out = m_compressed_stream_block_buffer.data();
m_compression_stream->avail_out = cCompressedStreamBlockBufferSize;
}
}

// Write any compressed data
if (m_compression_stream->avail_out < cCompressedStreamBlockBufferSize) {
m_compressed_stream_file_writer->write(
reinterpret_cast<char*>(m_compressed_stream_block_buffer.get()),
reinterpret_cast<char*>(m_compressed_stream_block_buffer.data()),
cCompressedStreamBlockBufferSize - m_compression_stream->avail_out
);
m_compression_stream->next_out = m_compressed_stream_block_buffer.get();
m_compression_stream->next_out = m_compressed_stream_block_buffer.data();
m_compression_stream->avail_out = cCompressedStreamBlockBufferSize;
}

Expand Down Expand Up @@ -200,7 +188,7 @@ void Compressor::flush() {

bool flush_complete = false;
while (true) {
lzma_ret return_value = lzma_code(m_compression_stream, LZMA_SYNC_FLUSH);
auto const return_value = lzma_code(m_compression_stream.get(), LZMA_SYNC_FLUSH);
switch (return_value) {
case LZMA_STREAM_END:
flush_complete = true;
Expand All @@ -219,21 +207,21 @@ void Compressor::flush() {
// Write output buffer to file if it's full
if (0 == m_compression_stream->avail_out) {
m_compressed_stream_file_writer->write(
reinterpret_cast<char*>(m_compressed_stream_block_buffer.get()),
reinterpret_cast<char*>(m_compressed_stream_block_buffer.data()),
cCompressedStreamBlockBufferSize
);
m_compression_stream->next_out = m_compressed_stream_block_buffer.get();
m_compression_stream->next_out = m_compressed_stream_block_buffer.data();
m_compression_stream->avail_out = cCompressedStreamBlockBufferSize;
}
}

// Write any compressed data
if (m_compression_stream->avail_out < cCompressedStreamBlockBufferSize) {
m_compressed_stream_file_writer->write(
reinterpret_cast<char*>(m_compressed_stream_block_buffer.get()),
reinterpret_cast<char*>(m_compressed_stream_block_buffer.data()),
cCompressedStreamBlockBufferSize - m_compression_stream->avail_out
);
m_compression_stream->next_out = m_compressed_stream_block_buffer.get();
m_compression_stream->next_out = m_compressed_stream_block_buffer.data();
m_compression_stream->avail_out = cCompressedStreamBlockBufferSize;
}

Expand All @@ -256,7 +244,7 @@ void Compressor::flush_and_close_compression_stream() {

bool flush_complete = false;
while (true) {
lzma_ret return_value = lzma_code(m_compression_stream, LZMA_FINISH);
lzma_ret return_value = lzma_code(m_compression_stream.get(), LZMA_FINISH);
switch (return_value) {
case LZMA_OK:
case LZMA_BUF_ERROR:
Expand All @@ -276,28 +264,28 @@ void Compressor::flush_and_close_compression_stream() {
// Write output buffer to file if it's full
if (0 == m_compression_stream->avail_out) {
m_compressed_stream_file_writer->write(
reinterpret_cast<char*>(m_compressed_stream_block_buffer.get()),
reinterpret_cast<char*>(m_compressed_stream_block_buffer.data()),
cCompressedStreamBlockBufferSize
);
m_compression_stream->next_out = m_compressed_stream_block_buffer.get();
m_compression_stream->next_out = m_compressed_stream_block_buffer.data();
m_compression_stream->avail_out = cCompressedStreamBlockBufferSize;
}
}

// Write any compressed data
if (m_compression_stream->avail_out < cCompressedStreamBlockBufferSize) {
m_compressed_stream_file_writer->write(
reinterpret_cast<char*>(m_compressed_stream_block_buffer.get()),
reinterpret_cast<char*>(m_compressed_stream_block_buffer.data()),
cCompressedStreamBlockBufferSize - m_compression_stream->avail_out
);
m_compression_stream->next_out = m_compressed_stream_block_buffer.get();
m_compression_stream->next_out = m_compressed_stream_block_buffer.data();
m_compression_stream->avail_out = cCompressedStreamBlockBufferSize;
}

m_compression_stream_contains_data = false;

lzma_end(m_compression_stream);
lzma_end(m_compression_stream.get());
m_compression_stream->avail_out = 0;
m_compression_stream->next_out = nullptr;
}
} // namespace streaming_compression::lzma
} // namespace clp::streaming_compression::lzma
84 changes: 50 additions & 34 deletions components/core/src/clp/streaming_compression/lzma/Compressor.hpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#ifndef STREAMING_COMPRESSION_LZMA_COMPRESSOR_HPP
#define STREAMING_COMPRESSION_LZMA_COMPRESSOR_HPP
#ifndef CLP_STREAMING_COMPRESSION_LZMA_COMPRESSOR_HPP
#define CLP_STREAMING_COMPRESSION_LZMA_COMPRESSOR_HPP

// C++ standard libraries
#include <cstdint>
#include <cstddef>
#include <memory>
#include <string>

// ZLIB library
#include <lzma.h>
#include <zlib.h>
#include <zconf.h>

// Project headers
#include "../../Array.hpp"
#include "../../ErrorCode.hpp"
#include "../../FileWriter.hpp"
#include "../../TraceableException.hpp"
#include "../Compressor.hpp"
#include "Constants.hpp"

namespace streaming_compression::lzma {
class Compressor : public ::streaming_compression::Compressor {
namespace clp::streaming_compression::lzma {
class Compressor : public ::clp::streaming_compression::Compressor {
public:
// Types
class OperationFailed : public TraceableException {
Expand All @@ -26,8 +26,8 @@ class Compressor : public ::streaming_compression::Compressor {
: TraceableException(error_code, filename, line_number) {}

// Methods
char const* what() const noexcept override {
return "streaming_compression::gzip::Compressor operation failed";
[[nodiscard]] auto what() const noexcept -> char const* override {
return "streaming_compression::lzma::Compressor operation failed";
}
};

Expand All @@ -38,10 +38,10 @@ class Compressor : public ::streaming_compression::Compressor {
m_dict_size{cDefaultDictionarySize} {}

auto set_compression_level(int compression_level) -> void {
if (0 > compression_level) {
m_compression_level = 0;
} else if (9 < compression_level) {
m_compression_level = 9;
if (compression_level < cMinCompressionLevel) {
m_compression_level = cMinCompressionLevel;
} else if (compression_level > cMaxCompressionLevel) {
m_compression_level = cMaxCompressionLevel;
} else {
m_compression_level = compression_level;
}
Expand All @@ -62,44 +62,57 @@ class Compressor : public ::streaming_compression::Compressor {
Compressor();

// Destructor
~Compressor();
~Compressor() override = default;

// Explicitly disable copy and move constructor/assignment
// Delete copy constructor and assignment operator
Compressor(Compressor const&) = delete;
Compressor& operator=(Compressor const&) = delete;
auto operator=(Compressor const&) -> Compressor& = delete;

// Default move constructor and assignment operator
Compressor(Compressor&&) noexcept = default;
auto operator=(Compressor&&) noexcept -> Compressor& = default;

// Methods implementing the WriterInterface
/**
* Writes the given data to the compressor
* @param data
* @param data_length
*/
void write(char const* data, size_t data_length) override;
auto write(char const* data, size_t data_length) -> void override;

/**
* Writes any internally buffered data to file and ends the current frame
*/
void flush() override;
auto flush() -> void override;

/**
* Tries to get the current position of the write head
* @param pos Position of the write head
* @return ErrorCode_NotInit if the compressor is not open
* @return ErrorCode_Success on success
*/
ErrorCode try_get_pos(size_t& pos) const override;
auto try_get_pos(size_t& pos) const -> ErrorCode override;

/**
* Closes the compressor
*/
auto close() -> void override;

// Methods implementing the Compressor interface
/**
* Initialize streaming compressor
* Initializes the compression stream with the default compression level
* @param file_writer
* @param compression_level
*/
void open(FileWriter& file_writer, int compression_level) override;
auto open(FileWriter& file_writer) -> void override {
this->open(file_writer, cDefaultCompressionLevel);
}

/**
* Closes the compressor
* Initializes the compression stream with the given compression level
* @param file_writer
* @param compression_level
*/
void close() override;
auto open(FileWriter& file_writer, int compression_level) -> void;

// Methods
static auto set_compression_level(int compression_level) -> void {
Expand All @@ -109,25 +122,28 @@ class Compressor : public ::streaming_compression::Compressor {
static auto set_dict_size(uint32_t dict_size) -> void { m_option.set_dict_size(dict_size); }

private:
using LzmaStream = lzma_stream;

/**
* Flushes the stream and closes it
*/
void flush_and_close_compression_stream();

static void init_lzma_encoder(lzma_stream* strm);
static void init_lzma_encoder(LzmaStream* strm);
static LzmaOption m_option;
static constexpr size_t cCompressedStreamBlockBufferSize{4096}; // 4KiB

// Variables
FileWriter* m_compressed_stream_file_writer;
FileWriter* m_compressed_stream_file_writer{nullptr};

// Compressed stream variables
lzma_stream* m_compression_stream;
bool m_compression_stream_contains_data;
std::unique_ptr<LzmaStream> m_compression_stream{std::make_unique<LzmaStream>()};
bool m_compression_stream_contains_data{false};

std::unique_ptr<Bytef[]> m_compressed_stream_block_buffer;
Array<Bytef> m_compressed_stream_block_buffer{cCompressedStreamBlockBufferSize};

size_t m_uncompressed_stream_pos;
size_t m_uncompressed_stream_pos{0};
};
} // namespace streaming_compression::lzma
} // namespace clp::streaming_compression::lzma

#endif // STREAMING_COMPRESSION_LZMA_COMPRESSOR_HPP
#endif // CLP_STREAMING_COMPRESSION_LZMA_COMPRESSOR_HPP
12 changes: 6 additions & 6 deletions components/core/src/clp/streaming_compression/lzma/Constants.hpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#ifndef STREAMING_COMPRESSION_LZMA_CONSTANTS_HPP
#define STREAMING_COMPRESSION_LZMA_CONSTANTS_HPP

#include <lzma.h>

// C++ libraries
#include <cstddef>
#include <cstdint>

namespace streaming_compression::lzma {
#include <lzma.h>

namespace clp::streaming_compression::lzma {
constexpr int cDefaultCompressionLevel{3};
constexpr int cMinCompressionLevel{0};
constexpr int cMaxCompressionLevel{9};
constexpr uint32_t cDefaultDictionarySize{LZMA_DICT_SIZE_DEFAULT};
} // namespace streaming_compression::lzma
} // namespace clp::streaming_compression::lzma

#endif // STREAMING_COMPRESSION_LZMA_CONSTANTS_HPP
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
// Project headers
#include "../../Defs.h"

namespace streaming_compression::lzma {
namespace clp::streaming_compression::lzma {
Decompressor::Decompressor()
: ::streaming_compression::Decompressor(CompressorType::LZMA),
: ::clp::streaming_compression::Decompressor(CompressorType::LZMA),
m_input_type(InputType::NotInitialized),
m_decompression_stream(nullptr),
m_file_reader(nullptr),
Expand Down Expand Up @@ -359,4 +359,4 @@ void Decompressor::reset_stream() {
m_decompressed_stream_pos = 0;
init_decoder(m_decompression_stream);
}
} // namespace streaming_compression::lzma
} // namespace clp::streaming_compression::lzma
Loading

0 comments on commit d5af274

Please sign in to comment.