From d9f9a26bde7e7a0357efdd08e300c922b8a57dd8 Mon Sep 17 00:00:00 2001 From: dm1sh Date: Tue, 21 Dec 2021 14:04:40 +0300 Subject: [PATCH] Fixed error correction bytes number to write in final bytes array Added exclipt size_t to unsigned conversion Fixed google test in Visual Studio --- QRCodeLibrary.sln | 24 +++++++++--------- QRCodeLibrary/BitArray.hpp | 4 ++- QRCodeLibrary/DataBlocks.cpp | 9 ++++--- QRCodeLibrary/DataBlocks.hpp | 2 +- QRCodeLibrary/Encoder.cpp | 11 +++++---- QRCodeLibrary/Encoder.hpp | 5 ++-- QRCodeLibrary/QRCodeLibrary.vcxproj | 1 + QRCodeLibrary/QRCodeLibrary.vcxproj.filters | 3 +++ QRCodeLibrary/QRMatrix.cpp | 27 +++++++++++---------- QRCodeLibrary/utils.hpp | 10 ++++++++ tests/DataBlocks_test.cpp | 2 +- tests/Encoder_test.cpp | 11 +++++---- tests/main_tests.cpp | 2 +- tests/packages.config | 2 +- tests/tests.vcxproj | 11 +++++---- 15 files changed, 73 insertions(+), 51 deletions(-) create mode 100644 QRCodeLibrary/utils.hpp diff --git a/QRCodeLibrary.sln b/QRCodeLibrary.sln index 8c97003..bf60673 100644 --- a/QRCodeLibrary.sln +++ b/QRCodeLibrary.sln @@ -1,14 +1,14 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31911.196 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QRCodeLibrary", "QRCodeLibrary\QRCodeLibrary.vcxproj", "{B1126767-CDF7-4831-8B08-85BF457DB4E2}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests\tests.vcxproj", "{96CDAF28-007A-4900-B24E-E21676713543}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Demo", "Demo\Demo.vcxproj", "{B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests\tests.vcxproj", "{3E0B17AF-839B-4963-BD22-7F2C8E87CE65}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -25,14 +25,6 @@ Global {B1126767-CDF7-4831-8B08-85BF457DB4E2}.Release|x64.Build.0 = Release|x64 {B1126767-CDF7-4831-8B08-85BF457DB4E2}.Release|x86.ActiveCfg = Release|Win32 {B1126767-CDF7-4831-8B08-85BF457DB4E2}.Release|x86.Build.0 = Release|Win32 - {96CDAF28-007A-4900-B24E-E21676713543}.Debug|x64.ActiveCfg = Debug|x64 - {96CDAF28-007A-4900-B24E-E21676713543}.Debug|x64.Build.0 = Debug|x64 - {96CDAF28-007A-4900-B24E-E21676713543}.Debug|x86.ActiveCfg = Debug|Win32 - {96CDAF28-007A-4900-B24E-E21676713543}.Debug|x86.Build.0 = Debug|Win32 - {96CDAF28-007A-4900-B24E-E21676713543}.Release|x64.ActiveCfg = Release|x64 - {96CDAF28-007A-4900-B24E-E21676713543}.Release|x64.Build.0 = Release|x64 - {96CDAF28-007A-4900-B24E-E21676713543}.Release|x86.ActiveCfg = Release|Win32 - {96CDAF28-007A-4900-B24E-E21676713543}.Release|x86.Build.0 = Release|Win32 {B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}.Debug|x64.ActiveCfg = Debug|x64 {B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}.Debug|x64.Build.0 = Debug|x64 {B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}.Debug|x86.ActiveCfg = Debug|Win32 @@ -41,6 +33,14 @@ Global {B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}.Release|x64.Build.0 = Release|x64 {B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}.Release|x86.ActiveCfg = Release|Win32 {B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}.Release|x86.Build.0 = Release|Win32 + {3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Debug|x64.ActiveCfg = Debug|x64 + {3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Debug|x64.Build.0 = Debug|x64 + {3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Debug|x86.ActiveCfg = Debug|Win32 + {3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Debug|x86.Build.0 = Debug|Win32 + {3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Release|x64.ActiveCfg = Release|x64 + {3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Release|x64.Build.0 = Release|x64 + {3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Release|x86.ActiveCfg = Release|Win32 + {3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/QRCodeLibrary/BitArray.hpp b/QRCodeLibrary/BitArray.hpp index 4125fd6..010266b 100644 --- a/QRCodeLibrary/BitArray.hpp +++ b/QRCodeLibrary/BitArray.hpp @@ -4,6 +4,8 @@ #include #include +#include "utils.hpp" + using namespace std; constexpr unsigned ceil_div(unsigned a, unsigned b) { @@ -15,7 +17,7 @@ class BitArray { public: BitArray(unsigned size_ = 0) : size{ size_ }, v(ceil_div(size_, 8), 0) {}; - BitArray(const vector& input) : size(input.size() * 8), v{ input } {}; + BitArray(const vector& input) : size(to_U(input.size()) * 8), v{ input } {}; operator std::string() const; diff --git a/QRCodeLibrary/DataBlocks.cpp b/QRCodeLibrary/DataBlocks.cpp index e5346b0..566c997 100644 --- a/QRCodeLibrary/DataBlocks.cpp +++ b/QRCodeLibrary/DataBlocks.cpp @@ -2,19 +2,20 @@ #include "DataBlocks.hpp" #include "Tables.hpp" +#include "utils.hpp" vector& DataBlocks::compose_joined_data_and_EC_blocks() { vector>data_block_sizes; - divide_to_blocks(data_block_sizes, e_data.size(), Tables::data_blocks_number.at(corr_lvl).at(version)); + divide_to_blocks(data_block_sizes, to_U(e_data.size()), Tables::data_blocks_number.at(corr_lvl).at(version)); unsigned EC_bytes_number = Tables::correction_bytes_num.at(corr_lvl).at(version); vector> EC_blocks(data_block_sizes.size(), vector()); for (unsigned i = 0; i < data_block_sizes.size(); i++) compose_EC_bytes(EC_blocks[i], e_data.cbegin() + data_block_sizes[i].second, EC_bytes_number, data_block_sizes[i].first); - join_data_and_EC_blocks(data, e_data, data_block_sizes, EC_blocks); + join_data_and_EC_blocks(data, e_data, data_block_sizes, EC_blocks, EC_bytes_number); return data; } @@ -59,7 +60,7 @@ unsigned get_db_byte_index(unsigned block_index, unsigned byte_index, const vect return db_sizes[block_index].second + byte_index; } -void DataBlocks::join_data_and_EC_blocks(vector& res, const vector& e_data, const vector>& db_sizes, const vector>& ec_codes) +void DataBlocks::join_data_and_EC_blocks(vector& res, const vector& e_data, const vector>& db_sizes, const vector>& ec_codes, unsigned ec_bytes_number) { if (ec_codes.size()) res.reserve(e_data.size() + ec_codes.at(0).size() * ec_codes.size()); @@ -72,7 +73,7 @@ void DataBlocks::join_data_and_EC_blocks(vector& res, const vecto res.push_back(e_data[get_db_byte_index(j, i, db_sizes)]); if (ec_codes.size()) - for (unsigned i = 0; i < ec_codes.at(0).size(); i++) + for (unsigned i = 0; i < ec_bytes_number; i++) for (unsigned j = 0; j < ec_codes.size(); j++) res.push_back(ec_codes[j][i]); } diff --git a/QRCodeLibrary/DataBlocks.hpp b/QRCodeLibrary/DataBlocks.hpp index 10e5206..90c81f4 100644 --- a/QRCodeLibrary/DataBlocks.hpp +++ b/QRCodeLibrary/DataBlocks.hpp @@ -16,7 +16,7 @@ public: static void divide_to_blocks(vector>& db_sizes, unsigned data_size, unsigned db_number); static void compose_EC_bytes(vector& res, const vector::const_iterator& src, unsigned corr_bytes_num, unsigned db_size); - static void join_data_and_EC_blocks(vector&res, const vector& e_data, const vector>& db_sizes, const vector>& ec_codes); + static void join_data_and_EC_blocks(vector&res, const vector& e_data, const vector>& db_sizes, const vector>& ec_codes, unsigned ec_bytes_number); private: const vector& e_data; diff --git a/QRCodeLibrary/Encoder.cpp b/QRCodeLibrary/Encoder.cpp index 74a7867..4f5fd08 100644 --- a/QRCodeLibrary/Encoder.cpp +++ b/QRCodeLibrary/Encoder.cpp @@ -2,12 +2,13 @@ #include "Encoder.hpp" #include "Tables.hpp" +#include "utils.hpp" #include BitArray& Encoder::encode() { - unsigned encoded_bit_num = calculate_encoded_input_size(input.size(), method); + unsigned encoded_bit_num = calculate_encoded_input_size(to_U(input.size()), method); unsigned metadata_bit_num = calculate_metadata_size(method, ((version < 0) ? 0 : version)); if (version < 0) { @@ -22,7 +23,7 @@ BitArray& Encoder::encode() e.resize(Tables::max_capability.at(corr_lvl).at(version)); - write_metadata(input.size(), metadata_bit_num - 4, method, e); + write_metadata(to_U(input.size()), metadata_bit_num - 4, method, e); encode_input(metadata_bit_num); pad_data(e, metadata_bit_num + encoded_bit_num); @@ -71,10 +72,10 @@ void Encoder::encode_numeric(const string& input, BitArray& out, unsigned offset if (input.size() % 3 == 2) { int bin = stoi(input.substr(input.size() - 2, 2)); - out.set(offset + input.size() / 3 * 10, bin, 7); + out.set(offset + to_U(input.size()) / 3 * 10, bin, 7); } else if (input.size() % 3 == 1) - out.set(offset + input.size() / 3 * 10, input[input.size() - 1] - '0', 4); + out.set(offset + to_U(input.size()) / 3 * 10, input[input.size() - 1] - '0', 4); } void Encoder::encode_alphabetic(const string& input, BitArray& out, unsigned offset) @@ -86,7 +87,7 @@ void Encoder::encode_alphabetic(const string& input, BitArray& out, unsigned off if (input.size() % 2 == 1) { int bin = encode_char(input[input.size() - 1]); - out.set(offset + input.size() / 2 * 11, bin, 6); + out.set(offset + to_U(input.size()) / 2 * 11, bin, 6); } } diff --git a/QRCodeLibrary/Encoder.hpp b/QRCodeLibrary/Encoder.hpp index 359b7d5..6e07737 100644 --- a/QRCodeLibrary/Encoder.hpp +++ b/QRCodeLibrary/Encoder.hpp @@ -6,6 +6,7 @@ #include "Method.hpp" #include "BitArray.hpp" +#include "utils.hpp" using namespace std; @@ -86,7 +87,7 @@ constexpr unsigned Encoder::calculate_encoded_input_size(unsigned input_size, QR template constexpr unsigned upper_index(const array arr, T val) { - unsigned count = arr.size(), s = 0, e = 0, step = 0; + unsigned count = to_U(arr.size()), s = 0, e = 0, step = 0; while (count > 0) { step = count / 2; @@ -101,4 +102,4 @@ constexpr unsigned upper_index(const array arr, T val) { } return s; -} \ No newline at end of file +} diff --git a/QRCodeLibrary/QRCodeLibrary.vcxproj b/QRCodeLibrary/QRCodeLibrary.vcxproj index 9da81e0..d2461b5 100644 --- a/QRCodeLibrary/QRCodeLibrary.vcxproj +++ b/QRCodeLibrary/QRCodeLibrary.vcxproj @@ -161,6 +161,7 @@ + diff --git a/QRCodeLibrary/QRCodeLibrary.vcxproj.filters b/QRCodeLibrary/QRCodeLibrary.vcxproj.filters index c346194..7c88c76 100644 --- a/QRCodeLibrary/QRCodeLibrary.vcxproj.filters +++ b/QRCodeLibrary/QRCodeLibrary.vcxproj.filters @@ -45,6 +45,9 @@ Header Files + + Header Files + diff --git a/QRCodeLibrary/QRMatrix.cpp b/QRCodeLibrary/QRMatrix.cpp index 2acd103..f6b5ffd 100644 --- a/QRCodeLibrary/QRMatrix.cpp +++ b/QRCodeLibrary/QRMatrix.cpp @@ -2,6 +2,7 @@ #include "QRMatrix.hpp" #include "Tables.hpp" +#include "utils.hpp" void QRMatrix::draw_patterns() { @@ -14,8 +15,8 @@ void QRMatrix::draw_patterns() void QRMatrix::draw_finder_patterns() { draw_finder_square(0, 0); - draw_finder_square(c.size() - 7, 0); - draw_finder_square(0, c.size() - 7); + draw_finder_square(to_U(c.size()) - 7, 0); + draw_finder_square(0, to_U(c.size()) - 7); draw_finder_square_separators(); } @@ -34,13 +35,13 @@ void QRMatrix::draw_finder_square(unsigned y, unsigned x) void QRMatrix::draw_finder_square_separators() { set(7, 0, 0b0000000, 7); - set(7, c.size() - 7, 0b0000000, 7); - set(c.size() - 8, 0, 0b0000000, 7); + set(7, to_U(c.size()) - 7, 0b0000000, 7); + set(to_U(c.size()) - 8, 0, 0b0000000, 7); for (unsigned i = 0; i < 8; i++) { set(i, 7, 0); - set(i, c.size() - 8, 0); - set(c.size() - 8 + i, 7, 0); + set(i, to_U(c.size()) - 8, 0); + set(to_U(c.size()) - 8 + i, 7, 0); } } @@ -48,7 +49,7 @@ void QRMatrix::draw_alignment_patters() { auto& coordinates = Tables::alignment_patterns_coordinates.at(version); for (unsigned i = 0; i < coordinates.size(); i++) { - unsigned s = i, e = coordinates.size(); + unsigned s = i, e = to_U(coordinates.size()); if (coordinates[i] == 6) s++, e--; @@ -81,7 +82,7 @@ void QRMatrix::draw_timing_patterns() void QRMatrix::draw_dark_module() { - set(c.size() - 8, 8, 1); + set(to_U(c.size()) - 8, 8, 1); } void QRMatrix::place_metadata(CorrectionLevel corr_lvl, unsigned char mask_n) @@ -90,14 +91,14 @@ void QRMatrix::place_metadata(CorrectionLevel corr_lvl, unsigned char mask_n) const auto& v_codes = Tables::version_codes.at(version-6); for (unsigned i = 0; i < 3; i++) for (unsigned j = 0; j < 6; j++) { - set(c.size() - 11 + i, j, (v_codes.at(i) >> (6 - 1 - j)) & 1); - set(j, c.size() - 11 + i, (v_codes.at(i) >> (6 - 1 - j)) & 1); + set(to_U(c.size()) - 11 + i, j, (v_codes.at(i) >> (6 - 1 - j)) & 1); + set(j, to_U(c.size()) - 11 + i, (v_codes.at(i) >> (6 - 1 - j)) & 1); } } unsigned code = Tables::corr_lvl_and_mask_codes.at(corr_lvl)[mask_n]; - unsigned y1 = 8, y2 = c.size() - 1, x1 = 0, x2 = 8; + unsigned y1 = 8, y2 = to_U(c.size()) - 1, x1 = 0, x2 = 8; for (unsigned i = 0; i < 15; i++) { set(y1, x1, (code >> (15 - 1 - i)) & 1); set(y2, x2, (code >> (15 - 1 - i)) & 1); @@ -112,7 +113,7 @@ void QRMatrix::place_metadata(CorrectionLevel corr_lvl, unsigned char mask_n) } if (y2 > c.size() - 8) y2--; - if (y2 == c.size() - 8) { y2 = 8; x2 = c.size() - 8; } + if (y2 == to_U(c.size()) - 8) { y2 = 8; x2 = to_U(c.size()) - 8; } else if (y2 == 8) x2++; @@ -123,7 +124,7 @@ void QRMatrix::place_metadata(CorrectionLevel corr_lvl, unsigned char mask_n) void QRMatrix::place_data(const BitArray& data, unsigned char mask_n) { - unsigned y = c.size() - 1; + unsigned y = to_U(c.size()) - 1; unsigned x = y; unsigned step = 0; bool horiz_dir = true; diff --git a/QRCodeLibrary/utils.hpp b/QRCodeLibrary/utils.hpp new file mode 100644 index 0000000..9f47c8d --- /dev/null +++ b/QRCodeLibrary/utils.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include +#include + +constexpr unsigned to_U(size_t val) { + if (val > (std::numeric_limits::max)()) + throw std::runtime_error("Too big number to convert it to unsigned int" + std::to_string(val)); + return static_cast(val); +} diff --git a/tests/DataBlocks_test.cpp b/tests/DataBlocks_test.cpp index 3f415bc..5c5589d 100644 --- a/tests/DataBlocks_test.cpp +++ b/tests/DataBlocks_test.cpp @@ -40,7 +40,7 @@ TEST(DataBlocksTests, JoinsDataAndECBlocks) { { 235, 159, 5, 173, 24, 147, 59, 33, 106, 40, 255, 172, 82, 2, 131, 32, 178, 236 } }; - DataBlocks::join_data_and_EC_blocks(joined, e_data, d_b_sizes, EC_blocks); + DataBlocks::join_data_and_EC_blocks(joined, e_data, d_b_sizes, EC_blocks, 18); const vectorres{ 67, 246, 182, 70, 85, 246, 230, 247, 70, 66, 247, 118, 134, 7, 119, diff --git a/tests/Encoder_test.cpp b/tests/Encoder_test.cpp index 2d8f70d..f4918d1 100644 --- a/tests/Encoder_test.cpp +++ b/tests/Encoder_test.cpp @@ -3,6 +3,7 @@ #define private public #include "../QRCodeLibrary/Encoder.hpp" +#include "../QRCodeLibrary/utils.hpp" /* upper_index function */ @@ -65,29 +66,29 @@ TEST(EncoderTests, DetermitesVersion) { TEST(EncoderTests, WritesMetadata) { string expected("010001100100"); - BitArray arr(expected.size()); + BitArray arr(to_U(expected.size())); - Encoder::write_metadata(100, expected.size() - 4, QRCodeMethod::Byte, arr); + Encoder::write_metadata(100, to_U(expected.size()) - 4, QRCodeMethod::Byte, arr); EXPECT_EQ(std::string(arr), expected); } TEST(EncoderTests, EncodesNumeric) { - BitArray tmp(string("00110110001110000100101001").size()); + BitArray tmp(to_U(string("00110110001110000100101001").size())); Encoder::encode_numeric("8675309", tmp, 2); EXPECT_EQ(std::string(tmp), "00110110001110000100101001"); } TEST(EncoderTests, EncodesAlphabetic) { - BitArray tmp(string("0000110000101101111000110100010111001011011100010011010100001101").size()); + BitArray tmp(to_U(string("0000110000101101111000110100010111001011011100010011010100001101").size())); Encoder::encode_alphabetic("HELLO WORLD", tmp, 3); EXPECT_EQ(std::string(tmp), "0000110000101101111000110100010111001011011100010011010100001101"); } TEST(EncoderTests, EncodesBytes) { - BitArray tmp(string("0000110100001001010011010000101111001101000010111000110100011000001011010001100000001101000010111000110100001011100100100000110100001010100011010000101110001101000110001000110100001011101011010000101111101101000010110010").size()); + BitArray tmp(to_U(string("0000110100001001010011010000101111001101000010111000110100011000001011010001100000001101000010111000110100001011100100100000110100001010100011010000101110001101000110001000110100001011101011010000101111101101000010110010").size())); Encoder::encode_byte(u8"Дмитрий Шишков", tmp, 4); EXPECT_EQ(std::string(tmp), "0000110100001001010011010000101111001101000010111000110100011000001011010001100000001101000010111000110100001011100100100000110100001010100011010000101110001101000110001000110100001011101011010000101111101101000010110010"); diff --git a/tests/main_tests.cpp b/tests/main_tests.cpp index 939a61d..e3c31a5 100644 --- a/tests/main_tests.cpp +++ b/tests/main_tests.cpp @@ -1,4 +1,4 @@ -#include "gtest/gtest.h" +#include "pch.h" int main(int argc, char **argv) { diff --git a/tests/packages.config b/tests/packages.config index 434bb12..88f987c 100644 --- a/tests/packages.config +++ b/tests/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/tests/tests.vcxproj b/tests/tests.vcxproj index 6dcd1e7..b894cfd 100644 --- a/tests/tests.vcxproj +++ b/tests/tests.vcxproj @@ -19,9 +19,9 @@ - {96cdaf28-007a-4900-b24e-e21676713543} + {3e0b17af-839b-4963-bd22-7f2c8e87ce65} Win32Proj - 10.0 + 10.0.19041.0 Application v143 Unicode @@ -39,14 +39,15 @@ + - Create Create Create Create + @@ -61,7 +62,7 @@ - + @@ -129,6 +130,6 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file