-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
decompress block type 00 - no compression
Change-Id: I5ceb11f5b6ba0ef63e250757747dab79c7958653
- Loading branch information
Showing
8 changed files
with
236 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"name": "lldb bit_span_test", | ||
"type": "lldb", | ||
"request": "launch", | ||
"program": "${workspaceFolder}/bazel-bin/huffman/test/bit_span_test", | ||
"cwd": "${workspaceFolder}", | ||
// necessary for debugging binaries built by bazel | ||
// see: | ||
// https://github.com/vadimcn/codelldb/wiki/Breakpoints-are-not-getting-hit#source-file-path-mismatch | ||
"sourceMap": { | ||
"/proc/self/cwd": "${workspaceFolder}" | ||
}, | ||
"preLaunchTask": "build-debug", | ||
}, | ||
{ | ||
"name": "lldb decompress_test", | ||
"type": "lldb", | ||
"request": "launch", | ||
"program": "${workspaceFolder}/bazel-bin/src/test/decompress_test", | ||
"cwd": "${workspaceFolder}", | ||
// necessary for debugging binaries built by bazel | ||
// see: | ||
// https://github.com/vadimcn/codelldb/wiki/Breakpoints-are-not-getting-hit#source-file-path-mismatch | ||
"sourceMap": { | ||
"/proc/self/cwd": "${workspaceFolder}" | ||
}, | ||
"preLaunchTask": "build-debug", | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"tasks": [ | ||
{ | ||
"args": [ | ||
"build", | ||
"-c", | ||
"dbg", | ||
"//..." | ||
], | ||
"command": "bazel", | ||
"group": "build", | ||
"label": "build-debug", | ||
"problemMatcher": [], | ||
"type": "shell" | ||
} | ||
], | ||
"version": "2.0.0" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#include "decompress.hpp" | ||
|
||
#include "huffman/huffman.hpp" | ||
|
||
#include <expected> | ||
|
||
namespace starflate::detail { | ||
|
||
auto valid(BlockType type) -> bool | ||
{ | ||
using enum BlockType; | ||
return type == NoCompression || type == FixedHuffman || | ||
type == DynamicHuffman; | ||
} | ||
|
||
auto read_header(huffman::bit_span& compressed_bits) | ||
-> std::expected<BlockHeader, DecompressError> | ||
{ | ||
if (std::ranges::size(compressed_bits) < 3) { | ||
return std::unexpected{DecompressError::InvalidBlockHeader}; | ||
} | ||
auto type = static_cast<BlockType>( | ||
std::uint8_t{static_cast<bool>(compressed_bits[1])} | | ||
(std::uint8_t{static_cast<bool>(compressed_bits[2])} << 1)); | ||
if (not valid(type)) { | ||
return std::unexpected{DecompressError::InvalidBlockHeader}; | ||
} | ||
bool final{static_cast<bool>(compressed_bits[0])}; | ||
compressed_bits.consume(3); | ||
return BlockHeader{final, type}; | ||
} | ||
} // namespace starflate::detail |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,5 +6,6 @@ cc_test( | |
srcs = ["decompress_test.cpp"], | ||
deps = [ | ||
"//src:decompress", | ||
"@boost_ut", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,87 @@ | ||
#include "huffman/src/utility.hpp" | ||
#include "src/decompress.hpp" | ||
|
||
auto main() -> int | ||
#include <boost/ut.hpp> | ||
|
||
#include <vector> | ||
|
||
template <class... Ts> | ||
constexpr auto byte_vector(Ts... values) | ||
{ | ||
return 0; | ||
return std::vector<std::byte>{std::byte(values)...}; | ||
} | ||
|
||
auto main() -> int | ||
{ | ||
using ::boost::ut::expect; | ||
using ::boost::ut::fatal; | ||
using ::boost::ut::test; | ||
using namespace starflate; | ||
test("read_header") = [] -> void { | ||
huffman::bit_span empty{nullptr, 0, 0}; | ||
expect(detail::read_header(empty).error() == | ||
DecompressError::InvalidBlockHeader); | ||
|
||
constexpr auto bad_block_type = huffman::byte_array(0b111); | ||
huffman::bit_span bad_block_type_span{ | ||
bad_block_type.data(), bad_block_type.size() * CHAR_BIT, 0}; | ||
expect(detail::read_header(bad_block_type_span).error() == | ||
DecompressError::InvalidBlockHeader); | ||
|
||
constexpr auto fixed = huffman::byte_array(0b010); | ||
huffman::bit_span fixed_span{fixed.data(), fixed.size() * CHAR_BIT, 0}; | ||
auto header = detail::read_header(fixed_span); | ||
expect(header.has_value()) | ||
<< "got error: " << static_cast<int>(header.error()); | ||
expect(not header->final); | ||
expect(header->type == detail::BlockType::FixedHuffman) | ||
<< "got type: " << static_cast<int>(header->type); | ||
|
||
constexpr auto no_compression = huffman::byte_array(0b001); | ||
huffman::bit_span no_compression_span{ | ||
no_compression.data(), no_compression.size() * CHAR_BIT, 0}; | ||
header = detail::read_header(no_compression_span); | ||
expect(header.has_value()) | ||
<< "got error: " << static_cast<int>(header.error()); | ||
expect(header->final); | ||
expect(header->type == detail::BlockType::NoCompression) | ||
<< "got type: " << static_cast<int>(header->type); | ||
}; | ||
|
||
test("no compression") = [] { | ||
constexpr auto compressed = huffman::byte_array( | ||
0b001, | ||
5, | ||
0, // len = 5 | ||
~5, | ||
~0, // nlen = 5 | ||
'h', | ||
'e', | ||
'l', | ||
'l', | ||
'o'); | ||
|
||
const auto expected = byte_vector('h', 'e', 'l', 'l', 'o'); | ||
|
||
const auto actual = | ||
decompress(std::span{compressed.data(), compressed.size()}); | ||
expect(fatal(actual.has_value())) | ||
<< "got error code: " << static_cast<std::int32_t>(actual.error()); | ||
expect(fatal(actual->size() == expected.size())); | ||
expect(*actual == expected); | ||
}; | ||
|
||
test("fixed huffman") = [] { | ||
constexpr auto compressed = huffman::byte_array(0b101); | ||
const auto actual = | ||
decompress(std::span{compressed.data(), compressed.size()}); | ||
expect(not actual.has_value()); | ||
}; | ||
|
||
test("dynamic huffman") = [] { | ||
constexpr auto compressed = huffman::byte_array(0b011); | ||
const auto actual = | ||
decompress(std::span{compressed.data(), compressed.size()}); | ||
expect(not actual.has_value()); | ||
}; | ||
}; |