From 65f700b9668413d82b44f4bed34e56ea7c41df05 Mon Sep 17 00:00:00 2001 From: FloHerrnb Date: Fri, 14 Nov 2025 22:13:02 +0100 Subject: [PATCH 1/3] trying to refactor --- cpp/src/mlt/decode/string.hpp | 104 +++++++++++++++++++--------------- cpp/test/test_fsst.cpp | 35 +++++++++++- justfile | 4 +- 3 files changed, 91 insertions(+), 52 deletions(-) diff --git a/cpp/src/mlt/decode/string.hpp b/cpp/src/mlt/decode/string.hpp index cd8b1a165..d08f22902 100644 --- a/cpp/src/mlt/decode/string.hpp +++ b/cpp/src/mlt/decode/string.hpp @@ -64,7 +64,9 @@ class StringDecoder { throw std::runtime_error("Data stream missing logical type"); } dictType = streamMetadata->getLogicalStreamType()->getDictionaryType(); + /// can we only get 2 dictionarytypes in here? auto& target = (dictType == DictionaryType::SINGLE) ? dictionaryStream : symbolStream; + /// DictionaryTpye::FSST is not used? decodeRaw(tileData, target, streamMetadata->getByteLength(), /*consume=*/true); break; } @@ -209,53 +211,6 @@ class StringDecoder { decompressedLength); } - static std::vector decodeFSST(const std::uint8_t* symbols, - const std::size_t symbolCount, - const std::uint32_t* symbolLengths, - const std::size_t symbolLengthCount, - const std::uint8_t* compressedData, - const std::size_t compressedDataCount, - const std::size_t decompressedLength) { - std::vector output; - - if (decompressedLength > 0) { - output.resize(decompressedLength); - } - std::vector symbolOffsets(symbolLengthCount); - for (size_t i = 1; i < symbolLengthCount; i++) { - symbolOffsets[i] = symbolOffsets[i - 1] + symbolLengths[i - 1]; - } - - std::size_t idx = 0; - for (size_t i = 0; i < compressedDataCount; i++) { - const std::uint8_t symbolIndex = compressedData[i]; - - // 255 is our escape byte -> take the next symbol as it is - if (symbolIndex == 255) { - if (idx == output.size()) { - output.resize(output.size() * 2); - } - output[idx++] = compressedData[++i]; - } else if (symbolIndex < symbolLengthCount) { - const auto len = symbolLengths[symbolIndex]; - if (idx + len > output.size()) { - output.resize((output.size() + len) * 2); - } - const auto offset = symbolOffsets[symbolIndex]; - if (offset >= symbolCount) { - throw std::runtime_error("FSST decode: symbol index out of bounds"); - } - std::memcpy(&output[idx], &symbols[offset], len); - idx += len; - } else { - throw std::runtime_error("FSST decode: invalid symbol index"); - } - } - - output.resize(idx); - return output; - } - private: IntegerDecoder& intDecoder; @@ -317,6 +272,61 @@ class StringDecoder { out.push_back(dictionary[offsets[offsetIndex++]]); } } + + /// the symbols are uint8_t since they are already aligned in memory with the corresponding size + static std::vector decodeFSST(const std::uint8_t* symbols, + const std::size_t symbolCount, + const std::uint32_t* symbolLengths, + const std::size_t symbolLengthCount, + const std::uint8_t* compressedData, + const std::size_t compressedDataCount, + const std::size_t decompressedLength) { + std::vector output(decompressedLength); + std::vector symbolOffsets(symbolLengthCount); + for (size_t i = 1; i < symbolLengthCount; i++) { + symbolOffsets[i] = symbolOffsets[i - 1] + symbolLengths[i - 1]; + } + + /* the code below provides a faster lookup in my opinion. It is the "easy" example from the fsst paper. + This is currently not possible since the symbols are already tightly packed inside the byte stream for fsst encoding. + The trade-off was made for tighter packing for the symbol table + + We can decode 8bytes of string value via + void decodeSingleByteviaFSST(uint8_t in[], uint8_t out[], + uint64_t sym[256], uint8_t len[256]){ + uint8_t code = *in++; + *((uint64_t*)out) = sym[code]; + out += len[code]; + } + */ + + for (size_t i = 0; i < compressedDataCount; i++) { + const std::uint8_t symbolIndex = compressedData[i]; + + // 255 is our escape byte -> take the next symbol as it is + if (symbolIndex == 255) { + /// this operation just copies the plain strings which are uncompressed + output.push_back(compressedData[++i]); + } else if (symbolIndex < symbolLengthCount) { + const auto len = symbolLengths[symbolIndex]; + const auto offset = symbolOffsets[symbolIndex]; + if (offset >= symbolCount) { + throw std::runtime_error("FSST decode: symbol index out of bounds"); + } + /// one symbol from the original fsst paper is here encoded as the contingous memory + /// symbols[offset] until symbols[offset+length] contains the up to 8 bytes + /// this results from the decoder side since the java class Symbol contains an array of up to 8 bytes + /// for each Symbol object + for (uint32_t j = 0; j < len; ++j) { + output.push_back(symbols[(size_t)offset + j]); + } + //std::memcpy(&output[idx], &symbols[offset], len); + } else { + throw std::runtime_error("FSST decode: invalid symbol index"); + } + } + return output; + } }; } // namespace mlt::decoder diff --git a/cpp/test/test_fsst.cpp b/cpp/test/test_fsst.cpp index f76860b9d..5c4ce74c2 100644 --- a/cpp/test/test_fsst.cpp +++ b/cpp/test/test_fsst.cpp @@ -5,7 +5,7 @@ #include #include -TEST(FSST, DecodeFromJava) { +TEST(FSST, DecodeFromJava_decode1) { const std::string expected = "AAAAAAABBBAAACCdddddEEEEEEfffEEEEAAAAAddddCC"; const std::vector symbols = {65, 65, 69, 69, 100, 100, 65, 66, 67, 69, 100, 102}; const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1}; @@ -16,15 +16,44 @@ TEST(FSST, DecodeFromJava) { symbols, symbolLengths, javaCompressed, expected.size()); EXPECT_EQ(decoded.size(), expected.size()); - EXPECT_EQ(0, memcmp(expected.c_str(), decoded.data(), expected.size())); + // EXPECT_EQ(0, memcmp(expected.c_str(), decoded.data(), expected.size())); +} + +TEST(FSST, DecodeFromJava_decode2){ + const std::string expected = "AAAAAAABBBAAACCdddddEEEEEEfffEEEEAAAAAddddCC"; + const std::vector symbols = {65, 65, 69, 69, 100, 100, 65, 66, 67, 69, 100, 102}; + const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1}; + const std::vector javaCompressed = {0, 0, 0, 3, 4, 4, 4, 0, 3, 5, 5, 2, 2, 7, 1, + 1, 1, 8, 8, 8, 1, 1, 0, 0, 3, 2, 2, 5, 5}; // also make sure buffer growth works const auto decoded2 = mlt::decoder::StringDecoder::decodeFSST(symbols, symbolLengths, javaCompressed, 0); EXPECT_EQ(decoded2.size(), expected.size()); EXPECT_EQ(0, memcmp(expected.c_str(), decoded2.data(), expected.size())); +} + +TEST(FSST, DecodeFromJava_decode3){ + const std::string expected = "AAAAAAABBBAAACCdddddEEEEEEfffEEEEAAAAAddddCC"; + const std::vector symbols = {65, 65, 69, 69, 100, 100, 65, 66, 67, 69, 100, 102}; + const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1}; + const std::vector javaCompressed = {0, 0, 0, 3, 4, 4, 4, 0, 3, 5, 5, 2, 2, 7, 1, + 1, 1, 8, 8, 8, 1, 1, 0, 0, 3, 2, 2, 5, 5}; const auto decoded3 = mlt::decoder::StringDecoder::decodeFSST( symbols, symbolLengths, javaCompressed, expected.size() / 2); EXPECT_EQ(decoded3.size(), expected.size()); - EXPECT_EQ(0, memcmp(expected.c_str(), decoded3.data(), expected.size() / 2)); + // EXPECT_EQ(0, memcmp(expected.c_str(), decoded3.data(), expected.size() / 2)); } + +/*TEST(FSST, DecodeFromJava_decode4){ + const std::string expected = "AAAAAAABBBAAACCdddddEEEEEEfffEEEEAAAAAddddCCk"; + const std::vector symbols = {65, 65, 69, 69, 100, 100, 65, 66, 67, 69, 100, 102, 255, 107}; + const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1}; + const std::vector javaCompressed = {0, 0, 0, 3, 4, 4, 4, 0, 3, 5, 5, 2, 2, 7, 1, + 1, 1, 8, 8, 8, 1, 1, 0, 0, 3, 2, 2, 5, 5}; + + const auto decoded4 = mlt::decoder::StringDecoder::decodeFSST( + symbols, symbolLengths, javaCompressed, expected.size()); + EXPECT_EQ(decoded4.size(), expected.size()); + EXPECT_EQ(0, memcmp(expected.c_str(), decoded4.data(), expected.size())); +}*/ diff --git a/justfile b/justfile index 04dab4703..3c8e516b2 100755 --- a/justfile +++ b/justfile @@ -158,13 +158,13 @@ mkdocs-build: cd mkdocs && docker run --rm -v ${PWD}:/docs squidfunk/mkdocs-material build --strict # Build Java encoder and generate .mlt files for all .pbf files in test/fixtures -[working-directory: 'java'] +#[working-directory: 'java'] generate-expected-mlt: (cargo-install 'fd' 'fd-find') ./gradlew cli fd . ../test/fixtures --no-ignore --extension pbf --extension mvt -x {{quote(just_executable())}} generate-one-expected-mlt # Generate a single .mlt file for a given .mvt or .pbf file, assuming JAR is built -[working-directory: 'java'] +#[working-directory: 'java'] [private] generate-one-expected-mlt file: java \ From 063147b4e2f93e6c8f9b94032752c929c903486f Mon Sep 17 00:00:00 2001 From: FloHerrnb Date: Fri, 14 Nov 2025 23:16:22 +0100 Subject: [PATCH 2/3] rebuilding to std::vector behavior and refactoring code --- cpp/src/mlt/decode/string.hpp | 50 +++++++++++++++++------------------ cpp/test/test_fsst.cpp | 45 ++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 36 deletions(-) diff --git a/cpp/src/mlt/decode/string.hpp b/cpp/src/mlt/decode/string.hpp index d08f22902..b83c92688 100644 --- a/cpp/src/mlt/decode/string.hpp +++ b/cpp/src/mlt/decode/string.hpp @@ -273,7 +273,6 @@ class StringDecoder { } } - /// the symbols are uint8_t since they are already aligned in memory with the corresponding size static std::vector decodeFSST(const std::uint8_t* symbols, const std::size_t symbolCount, const std::uint32_t* symbolLengths, @@ -281,31 +280,23 @@ class StringDecoder { const std::uint8_t* compressedData, const std::size_t compressedDataCount, const std::size_t decompressedLength) { - std::vector output(decompressedLength); - std::vector symbolOffsets(symbolLengthCount); + std::vector output; + output.reserve(decompressedLength); + + std::vector symbolOffsets; for (size_t i = 1; i < symbolLengthCount; i++) { symbolOffsets[i] = symbolOffsets[i - 1] + symbolLengths[i - 1]; } - - /* the code below provides a faster lookup in my opinion. It is the "easy" example from the fsst paper. - This is currently not possible since the symbols are already tightly packed inside the byte stream for fsst encoding. - The trade-off was made for tighter packing for the symbol table - - We can decode 8bytes of string value via - void decodeSingleByteviaFSST(uint8_t in[], uint8_t out[], - uint64_t sym[256], uint8_t len[256]){ - uint8_t code = *in++; - *((uint64_t*)out) = sym[code]; - out += len[code]; - } - */ - + for (size_t i = 0; i < compressedDataCount; i++) { const std::uint8_t symbolIndex = compressedData[i]; - // 255 is our escape byte -> take the next symbol as it is if (symbolIndex == 255) { /// this operation just copies the plain strings which are uncompressed + if(compressedData[i+1]==255) + { + throw std::runtime_error("FSST decode: two escape sequences in a row detected index"); + } output.push_back(compressedData[++i]); } else if (symbolIndex < symbolLengthCount) { const auto len = symbolLengths[symbolIndex]; @@ -313,19 +304,26 @@ class StringDecoder { if (offset >= symbolCount) { throw std::runtime_error("FSST decode: symbol index out of bounds"); } - /// one symbol from the original fsst paper is here encoded as the contingous memory - /// symbols[offset] until symbols[offset+length] contains the up to 8 bytes - /// this results from the decoder side since the java class Symbol contains an array of up to 8 bytes - /// for each Symbol object - for (uint32_t j = 0; j < len; ++j) { - output.push_back(symbols[(size_t)offset + j]); - } - //std::memcpy(&output[idx], &symbols[offset], len); + const std::uint8_t* start = symbols + offset; + const std::uint8_t* end = start + len; + output.insert(output.end(), start, end); } else { throw std::runtime_error("FSST decode: invalid symbol index"); } } return output; + /* the code below provides a faster lookup in my opinion. It is the "easy" example from the fsst paper. + This is currently not possible since the symbols are already tightly packed inside the byte stream for fsst encoding. + The trade-off was made for tighter packing for the symbol table + + We can decode 8bytes of string value via + void decodeSingleByteviaFSST(uint8_t in[], uint8_t out[], + uint64_t sym[256], uint8_t len[256]){ + uint8_t code = *in++; + *((uint64_t*)out) = sym[code]; + out += len[code]; + } + */ } }; diff --git a/cpp/test/test_fsst.cpp b/cpp/test/test_fsst.cpp index 5c4ce74c2..fc3c393ed 100644 --- a/cpp/test/test_fsst.cpp +++ b/cpp/test/test_fsst.cpp @@ -16,7 +16,7 @@ TEST(FSST, DecodeFromJava_decode1) { symbols, symbolLengths, javaCompressed, expected.size()); EXPECT_EQ(decoded.size(), expected.size()); - // EXPECT_EQ(0, memcmp(expected.c_str(), decoded.data(), expected.size())); + EXPECT_EQ(0, memcmp(expected.c_str(), decoded.data(), expected.size())); } TEST(FSST, DecodeFromJava_decode2){ @@ -42,18 +42,43 @@ TEST(FSST, DecodeFromJava_decode3){ const auto decoded3 = mlt::decoder::StringDecoder::decodeFSST( symbols, symbolLengths, javaCompressed, expected.size() / 2); EXPECT_EQ(decoded3.size(), expected.size()); - // EXPECT_EQ(0, memcmp(expected.c_str(), decoded3.data(), expected.size() / 2)); + EXPECT_EQ(0, memcmp(expected.c_str(), decoded3.data(), expected.size() / 2)); } -/*TEST(FSST, DecodeFromJava_decode4){ +TEST(FSST, DecodeFromJava_With_one_Escape_character){ const std::string expected = "AAAAAAABBBAAACCdddddEEEEEEfffEEEEAAAAAddddCCk"; - const std::vector symbols = {65, 65, 69, 69, 100, 100, 65, 66, 67, 69, 100, 102, 255, 107}; - const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1}; + const std::vector symbols = {65, 65, 69, 69, 100, 100, 65, 66, 67, 69, 100, 102}; + const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1, 1}; const std::vector javaCompressed = {0, 0, 0, 3, 4, 4, 4, 0, 3, 5, 5, 2, 2, 7, 1, - 1, 1, 8, 8, 8, 1, 1, 0, 0, 3, 2, 2, 5, 5}; + 1, 1, 8, 8, 8, 1, 1, 0, 0, 3, 2, 2, 5, 5, 255, 107}; - const auto decoded4 = mlt::decoder::StringDecoder::decodeFSST( + const auto decoded = mlt::decoder::StringDecoder::decodeFSST( symbols, symbolLengths, javaCompressed, expected.size()); - EXPECT_EQ(decoded4.size(), expected.size()); - EXPECT_EQ(0, memcmp(expected.c_str(), decoded4.data(), expected.size())); -}*/ + EXPECT_EQ(decoded.size(), expected.size()); + EXPECT_EQ(0, memcmp(expected.c_str(), decoded.data(), expected.size())); +} + +TEST(FSST, DecodeFromJava_With_multiple_Escape_characters){ + const std::string expected = "AAAAAAABBBAAACCdddddEEEEEEfffEEEEAAAAAddddCCkkk"; + const std::vector symbols = {65, 65, 69, 69, 100, 100, 65, 66, 67, 69, 100, 102}; + const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1, 1}; + const std::vector javaCompressed = {0, 0, 0, 3, 4, 4, 4, 0, 3, 5, 5, 2, 2, 7, 1, + 1, 1, 8, 8, 8, 1, 1, 0, 0, 3, 2, 2, 5, 5, 255, 107, 255, 107, 255, 107}; + + const auto decoded = mlt::decoder::StringDecoder::decodeFSST( + symbols, symbolLengths, javaCompressed, expected.size()); + EXPECT_EQ(decoded.size(), expected.size()); + EXPECT_EQ(0, memcmp(expected.c_str(), decoded.data(), expected.size())); +} + +TEST(FSST, DecodeFromJava_With_one_single_escaped_character){ + const std::string expected = "k"; + const std::vector symbols = {65, 65, 69, 69, 100, 100, 65, 66, 67, 69, 100, 102}; + const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1};; + const std::vector javaCompressed = {255, 107}; + + const auto decoded = mlt::decoder::StringDecoder::decodeFSST( + symbols, symbolLengths, javaCompressed, expected.size()); + EXPECT_EQ(decoded.size(), expected.size()); + EXPECT_EQ(0, memcmp(expected.c_str(), decoded.data(), expected.size())); +} From 48209e30cc301c204e3186400e50e6b92c5a5c60 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 14 Nov 2025 22:20:23 +0000 Subject: [PATCH 3/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- cpp/src/mlt/decode/string.hpp | 17 ++++++++--------- cpp/test/test_fsst.cpp | 21 +++++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/cpp/src/mlt/decode/string.hpp b/cpp/src/mlt/decode/string.hpp index b83c92688..6f55e954b 100644 --- a/cpp/src/mlt/decode/string.hpp +++ b/cpp/src/mlt/decode/string.hpp @@ -287,15 +287,14 @@ class StringDecoder { for (size_t i = 1; i < symbolLengthCount; i++) { symbolOffsets[i] = symbolOffsets[i - 1] + symbolLengths[i - 1]; } - + for (size_t i = 0; i < compressedDataCount; i++) { const std::uint8_t symbolIndex = compressedData[i]; // 255 is our escape byte -> take the next symbol as it is if (symbolIndex == 255) { /// this operation just copies the plain strings which are uncompressed - if(compressedData[i+1]==255) - { - throw std::runtime_error("FSST decode: two escape sequences in a row detected index"); + if (compressedData[i + 1] == 255) { + throw std::runtime_error("FSST decode: two escape sequences in a row detected index"); } output.push_back(compressedData[++i]); } else if (symbolIndex < symbolLengthCount) { @@ -305,7 +304,7 @@ class StringDecoder { throw std::runtime_error("FSST decode: symbol index out of bounds"); } const std::uint8_t* start = symbols + offset; - const std::uint8_t* end = start + len; + const std::uint8_t* end = start + len; output.insert(output.end(), start, end); } else { throw std::runtime_error("FSST decode: invalid symbol index"); @@ -313,16 +312,16 @@ class StringDecoder { } return output; /* the code below provides a faster lookup in my opinion. It is the "easy" example from the fsst paper. - This is currently not possible since the symbols are already tightly packed inside the byte stream for fsst encoding. - The trade-off was made for tighter packing for the symbol table + This is currently not possible since the symbols are already tightly packed inside the byte stream for fsst + encoding. The trade-off was made for tighter packing for the symbol table - We can decode 8bytes of string value via + We can decode 8bytes of string value via void decodeSingleByteviaFSST(uint8_t in[], uint8_t out[], uint64_t sym[256], uint8_t len[256]){ uint8_t code = *in++; *((uint64_t*)out) = sym[code]; out += len[code]; - } + } */ } }; diff --git a/cpp/test/test_fsst.cpp b/cpp/test/test_fsst.cpp index fc3c393ed..68a2742f4 100644 --- a/cpp/test/test_fsst.cpp +++ b/cpp/test/test_fsst.cpp @@ -19,7 +19,7 @@ TEST(FSST, DecodeFromJava_decode1) { EXPECT_EQ(0, memcmp(expected.c_str(), decoded.data(), expected.size())); } -TEST(FSST, DecodeFromJava_decode2){ +TEST(FSST, DecodeFromJava_decode2) { const std::string expected = "AAAAAAABBBAAACCdddddEEEEEEfffEEEEAAAAAddddCC"; const std::vector symbols = {65, 65, 69, 69, 100, 100, 65, 66, 67, 69, 100, 102}; const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1}; @@ -32,7 +32,7 @@ TEST(FSST, DecodeFromJava_decode2){ EXPECT_EQ(0, memcmp(expected.c_str(), decoded2.data(), expected.size())); } -TEST(FSST, DecodeFromJava_decode3){ +TEST(FSST, DecodeFromJava_decode3) { const std::string expected = "AAAAAAABBBAAACCdddddEEEEEEfffEEEEAAAAAddddCC"; const std::vector symbols = {65, 65, 69, 69, 100, 100, 65, 66, 67, 69, 100, 102}; const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1}; @@ -45,12 +45,12 @@ TEST(FSST, DecodeFromJava_decode3){ EXPECT_EQ(0, memcmp(expected.c_str(), decoded3.data(), expected.size() / 2)); } -TEST(FSST, DecodeFromJava_With_one_Escape_character){ +TEST(FSST, DecodeFromJava_With_one_Escape_character) { const std::string expected = "AAAAAAABBBAAACCdddddEEEEEEfffEEEEAAAAAddddCCk"; const std::vector symbols = {65, 65, 69, 69, 100, 100, 65, 66, 67, 69, 100, 102}; const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1, 1}; - const std::vector javaCompressed = {0, 0, 0, 3, 4, 4, 4, 0, 3, 5, 5, 2, 2, 7, 1, - 1, 1, 8, 8, 8, 1, 1, 0, 0, 3, 2, 2, 5, 5, 255, 107}; + const std::vector javaCompressed = {0, 0, 0, 3, 4, 4, 4, 0, 3, 5, 5, 2, 2, 7, 1, 1, + 1, 8, 8, 8, 1, 1, 0, 0, 3, 2, 2, 5, 5, 255, 107}; const auto decoded = mlt::decoder::StringDecoder::decodeFSST( symbols, symbolLengths, javaCompressed, expected.size()); @@ -58,12 +58,12 @@ TEST(FSST, DecodeFromJava_With_one_Escape_character){ EXPECT_EQ(0, memcmp(expected.c_str(), decoded.data(), expected.size())); } -TEST(FSST, DecodeFromJava_With_multiple_Escape_characters){ +TEST(FSST, DecodeFromJava_With_multiple_Escape_characters) { const std::string expected = "AAAAAAABBBAAACCdddddEEEEEEfffEEEEAAAAAddddCCkkk"; const std::vector symbols = {65, 65, 69, 69, 100, 100, 65, 66, 67, 69, 100, 102}; const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1, 1}; - const std::vector javaCompressed = {0, 0, 0, 3, 4, 4, 4, 0, 3, 5, 5, 2, 2, 7, 1, - 1, 1, 8, 8, 8, 1, 1, 0, 0, 3, 2, 2, 5, 5, 255, 107, 255, 107, 255, 107}; + const std::vector javaCompressed = {0, 0, 0, 3, 4, 4, 4, 0, 3, 5, 5, 2, 2, 7, 1, 1, 1, 8, + 8, 8, 1, 1, 0, 0, 3, 2, 2, 5, 5, 255, 107, 255, 107, 255, 107}; const auto decoded = mlt::decoder::StringDecoder::decodeFSST( symbols, symbolLengths, javaCompressed, expected.size()); @@ -71,10 +71,11 @@ TEST(FSST, DecodeFromJava_With_multiple_Escape_characters){ EXPECT_EQ(0, memcmp(expected.c_str(), decoded.data(), expected.size())); } -TEST(FSST, DecodeFromJava_With_one_single_escaped_character){ +TEST(FSST, DecodeFromJava_With_one_single_escaped_character) { const std::string expected = "k"; const std::vector symbols = {65, 65, 69, 69, 100, 100, 65, 66, 67, 69, 100, 102}; - const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1};; + const std::vector symbolLengths = {2, 2, 2, 1, 1, 1, 1, 1, 1}; + ; const std::vector javaCompressed = {255, 107}; const auto decoded = mlt::decoder::StringDecoder::decodeFSST(