#include "BitArray.h"
#include "BitArrayUtility.h"
#include "BitMatrixIO.h"
#include "CharacterSet.h"
#include "TextDecoder.h"
#include "Utf.h"
#include "qrcode/QREncoder.h"
#include "qrcode/QRCodecMode.h"
#include "qrcode/QREncodeResult.h"
#include "qrcode/QRErrorCorrectionLevel.h"
#include "gtest/gtest.h"
namespace ZXing {
namespace QRCode {
int GetAlphanumericCode(int code);
CodecMode ChooseMode(const std::wstring& content, CharacterSet encoding);
void AppendModeInfo(CodecMode mode, BitArray& bits);
void AppendLengthInfo(int numLetters, const Version& version, CodecMode mode, BitArray& bits);
void AppendNumericBytes(const std::wstring& content, BitArray& bits);
void AppendAlphanumericBytes(const std::wstring& content, BitArray& bits);
void Append8BitBytes(const std::wstring& content, CharacterSet encoding, BitArray& bits);
void AppendKanjiBytes(const std::wstring& content, BitArray& bits);
void AppendBytes(const std::wstring& content, CodecMode mode, CharacterSet encoding, BitArray& bits);
void TerminateBits(int numDataBytes, BitArray& bits);
void GetNumDataBytesAndNumECBytesForBlockID(int numTotalBytes, int numDataBytes, int numRSBlocks, int blockID, int& numDataBytesInBlock, int& numECBytesInBlock);
void GenerateECBytes(const ByteArray& dataBytes, int numEcBytesInBlock, ByteArray& ecBytes);
BitArray InterleaveWithECBytes(const BitArray& bits, int numTotalBytes, int numDataBytes, int numRSBlocks);
}
}
using namespace ZXing;
using namespace ZXing::QRCode;
using namespace ZXing::Utility;
namespace {
std::wstring ShiftJISString(const std::vector<uint8_t>& bytes)
{
std::string str;
TextDecoder::Append(str, bytes.data(), bytes.size(), CharacterSet::Shift_JIS);
return FromUtf8(str);
}
std::string RemoveSpace(std::string s)
{
s.erase(std::remove(s.begin(), s.end(), ' '), s.end());
return s;
}
}
TEST(QREncoderTest, GetAlphanumericCode)
{
for (int i = 0; i < 10; ++i) {
EXPECT_EQ(i, GetAlphanumericCode('0' + i));
}
for (int i = 10; i < 36; ++i) {
EXPECT_EQ(i, GetAlphanumericCode('A' + i - 10));
}
EXPECT_EQ(36, GetAlphanumericCode(' '));
EXPECT_EQ(37, GetAlphanumericCode('$'));
EXPECT_EQ(38, GetAlphanumericCode('%'));
EXPECT_EQ(39, GetAlphanumericCode('*'));
EXPECT_EQ(40, GetAlphanumericCode('+'));
EXPECT_EQ(41, GetAlphanumericCode('-'));
EXPECT_EQ(42, GetAlphanumericCode('.'));
EXPECT_EQ(43, GetAlphanumericCode('/'));
EXPECT_EQ(44, GetAlphanumericCode(':'));
EXPECT_EQ(-1, GetAlphanumericCode('a'));
EXPECT_EQ(-1, GetAlphanumericCode('#'));
EXPECT_EQ(-1, GetAlphanumericCode('\0'));
}
TEST(QREncoderTest, ChooseMode)
{
EXPECT_EQ(CodecMode::NUMERIC, ChooseMode(L"0", CharacterSet::Unknown));
EXPECT_EQ(CodecMode::NUMERIC, ChooseMode(L"0123456789", CharacterSet::Unknown));
EXPECT_EQ(CodecMode::ALPHANUMERIC, ChooseMode(L"A", CharacterSet::Unknown));
EXPECT_EQ(CodecMode::ALPHANUMERIC,
ChooseMode(L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:", CharacterSet::Unknown));
EXPECT_EQ(CodecMode::BYTE, ChooseMode(L"a", CharacterSet::Unknown));
EXPECT_EQ(CodecMode::BYTE, ChooseMode(L"#", CharacterSet::Unknown));
EXPECT_EQ(CodecMode::BYTE, ChooseMode(L"", CharacterSet::Unknown));
EXPECT_EQ(CodecMode::BYTE,
ChooseMode(ShiftJISString({0x8, 0xa, 0x8, 0xa, 0x8, 0xa, 0x8, 0xa6}), CharacterSet::Unknown));
EXPECT_EQ(CodecMode::BYTE, ChooseMode(ShiftJISString({0x9, 0xf, 0x9, 0x7b}), CharacterSet::Unknown));
EXPECT_EQ(CodecMode::BYTE, ChooseMode(ShiftJISString({0xe, 0x4, 0x9, 0x5, 0x9, 0x61}), CharacterSet::Unknown));
}
TEST(QREncoderTest, Encode)
{
auto qrCode = Encode(L"ABCDEF", ErrorCorrectionLevel::High, CharacterSet::Unknown, 0, false, -1);
EXPECT_EQ(qrCode.mode, CodecMode::ALPHANUMERIC);
EXPECT_EQ(qrCode.ecLevel, ErrorCorrectionLevel::High);
ASSERT_NE(qrCode.version, nullptr);
EXPECT_EQ(qrCode.version->versionNumber(), 1);
EXPECT_EQ(qrCode.maskPattern, 4);
EXPECT_EQ(ToString(qrCode.matrix),
"X X X X X X X X X X X X X X X X \n"
"X X X X X X X \n"
"X X X X X X X X X X \n"
"X X X X X X X X X X X X \n"
"X X X X X X X X X X X X \n"
"X X X X X X X \n"
"X X X X X X X X X X X X X X X X X \n"
" X X \n"
" X X X X X X X X X X \n"
" X X X X X X X X X X X X \n"
"X X X X X X X X X X \n"
"X X X X X X X X X \n"
" X X X X X X X X X X X X X \n"
" X X X X X X \n"
"X X X X X X X X X X X X X \n"
"X X X X X X X X X X \n"
"X X X X X X X X X X X \n"
"X X X X X X X X X X X \n"
"X X X X X X X X X \n"
"X X X X X X X \n"
"X X X X X X X X X X X X \n");
}
TEST(QREncoderTest, EncodeWithVersion)
{
auto qrCode = Encode(L"ABCDEF", ErrorCorrectionLevel::High, CharacterSet::Unknown, 7, false, -1);
ASSERT_NE(qrCode.version, nullptr);
EXPECT_EQ(qrCode.version->versionNumber(), 7);
}
TEST(QREncoderTest, EncodeWithVersionTooSmall)
{
EXPECT_THROW(
Encode(L"THISMESSAGEISTOOLONGFORAQRCODEVERSION3", ErrorCorrectionLevel::High, CharacterSet::Unknown, 3, false, -1)
, std::invalid_argument);
}
TEST(QREncoderTest, SimpleUTF8ECI)
{
auto qrCode = Encode(L"hello", ErrorCorrectionLevel::High, CharacterSet::UTF8, 0, false, -1);
EXPECT_EQ(qrCode.mode, CodecMode::BYTE);
EXPECT_EQ(qrCode.ecLevel, ErrorCorrectionLevel::High);
ASSERT_NE(qrCode.version, nullptr);
EXPECT_EQ(qrCode.version->versionNumber(), 1);
EXPECT_EQ(qrCode.maskPattern, 6);
EXPECT_EQ(ToString(qrCode.matrix), "X X X X X X X X X X X X X X X X \n"
"X X X X X X \n"
"X X X X X X X X X X X X X \n"
"X X X X X X X X X X X X \n"
"X X X X X X X X X X X X \n"
"X X X X X \n"
"X X X X X X X X X X X X X X X X X \n"
" X X X X \n"
" X X X X X X X \n"
" X X X X X X X X X \n"
"X X X X X X X X X X X \n"
" X X X X X X \n"
" X X X X X X X X X X X X X X X \n"
" X X X X X X X X X X X X \n"
"X X X X X X X X X X \n"
"X X X X X X \n"
"X X X X X X X X X \n"
"X X X X X X X X X X X X X \n"
"X X X X X X X X X X X X \n"
"X X X X X X \n"
"X X X X X X X X X X X \n");
}
TEST(QREncoderTest, SimpleBINARYECI)
{
auto qrCode = Encode(L"\u00E9", ErrorCorrectionLevel::High, CharacterSet::BINARY, 0, false, -1);
EXPECT_EQ(qrCode.mode, CodecMode::BYTE);
EXPECT_EQ(qrCode.ecLevel, ErrorCorrectionLevel::High);
ASSERT_NE(qrCode.version, nullptr);
EXPECT_EQ(qrCode.version->versionNumber(), 1);
EXPECT_EQ(qrCode.maskPattern, 6);
EXPECT_EQ(ToString(qrCode.matrix),
"X X X X X X X X X X X X X X X X X X \n"
"X X X X X \n"
"X X X X X X X X X X X X X \n"
"X X X X X X X X X X X X X X X \n"
"X X X X X X X X X X X \n"
"X X X X X X \n"
"X X X X X X X X X X X X X X X X X \n"
" X X X \n"
" X X X X X X X \n"
"X X X X X X X X \n"
"X X X X X X X X X X X X X X X \n"
"X X X X X X X X X X X X \n"
" X X X X X X X X X X \n"
" X X X X X X X X \n"
"X X X X X X X X X X X X X X X \n"
"X X X X X X X \n"
"X X X X X X X X X X X X X \n"
"X X X X X X X X X X X X X \n"
"X X X X X X X X X X \n"
"X X X X X X X \n"
"X X X X X X X X X X X X X \n");
}
TEST(QREncoderTest, EncodeKanjiMode)
{
auto qrCode = Encode(L"\u65e5\u672c", ErrorCorrectionLevel::Medium, CharacterSet::Shift_JIS, 0, false, -1);
EXPECT_EQ(qrCode.mode, CodecMode::KANJI);
EXPECT_EQ(qrCode.ecLevel, ErrorCorrectionLevel::Medium);
ASSERT_NE(qrCode.version, nullptr);
EXPECT_EQ(qrCode.version->versionNumber(), 1);
EXPECT_EQ(qrCode.maskPattern, 0);
EXPECT_EQ(ToString(qrCode.matrix),
"X X X X X X X X X X X X X X X X \n"
"X X X X X X \n"
"X X X X X X X X X X X X X X \n"
"X X X X X X X X X X X \n"
"X X X X X X X X X X X X X X X \n"
"X X X X X X X \n"
"X X X X X X X X X X X X X X X X X \n"
" X \n"
"X X X X X X X X \n"
"X X X X X X X X X X \n"
" X X X X X X X X X X X X \n"
"X X X X X X X X X X X \n"
" X X X X X X X X X X X X \n"
" X X X X X \n"
"X X X X X X X X X X X \n"
"X X X X X X X \n"
"X X X X X X X X X X X \n"
"X X X X X X X X X X \n"
"X X X X X X X X X X X X X \n"
"X X X X X X X X X \n"
"X X X X X X X X X X X X X X \n");
}
TEST(QREncoderTest, EncodeShiftjisNumeric)
{
auto qrCode = Encode(L"0123", ErrorCorrectionLevel::Medium, CharacterSet::Shift_JIS, 0, false, -1);
EXPECT_EQ(qrCode.mode, CodecMode::NUMERIC);
EXPECT_EQ(qrCode.ecLevel, ErrorCorrectionLevel::Medium);
ASSERT_NE(qrCode.version, nullptr);
EXPECT_EQ(qrCode.version->versionNumber(), 1);
EXPECT_EQ(qrCode.maskPattern, 2);
EXPECT_EQ(ToString(qrCode.matrix),
"X X X X X X X X X X X X X X X X X \n"
"X X X X X X \n"
"X X X X X X X X X X X \n"
"X X X X X X X X X X X X X X \n"
"X X X X X X X X X X X X X X \n"
"X X X X X X X \n"
"X X X X X X X X X X X X X X X X X \n"
" X X X X X \n"
"X X X X X X X X X X X X X X \n"
"X X X X X X X X \n"
" X X X X X X X X X X X X X X \n"
"X X X X X X X X X \n"
" X X X X X X X X \n"
" X X X X X X X \n"
"X X X X X X X X X X X \n"
"X X X X X X X X X X \n"
"X X X X X X X X X X \n"
"X X X X X X X X X X X \n"
"X X X X X X X X X X X X \n"
"X X X X X X X \n"
"X X X X X X X X X X X X X X \n");
}
TEST(QREncoderTest, EncodeGS1)
{
auto qrCode = Encode(L"100001%11171218", ErrorCorrectionLevel::High, CharacterSet::Unknown, 0, true, -1);
EXPECT_EQ(qrCode.mode, CodecMode::ALPHANUMERIC);
EXPECT_EQ(qrCode.ecLevel, ErrorCorrectionLevel::High);
ASSERT_NE(qrCode.version, nullptr);
EXPECT_EQ(qrCode.version->versionNumber(), 2);
EXPECT_EQ(qrCode.maskPattern, 4);
EXPECT_EQ(ToString(qrCode.matrix),
"X X X X X X X X X X X X X X X X X X X X \n"
"X X X X X X X X \n"
"X X X X X X X X X X X X X X \n"
"X X X X X X X X X X X X X X \n"
"X X X X X X X X X X X X X X \n"
"X X X X X X X X X X \n"
"X X X X X X X X X X X X X X X X X X X \n"
" X X X X X X \n"
" X X X X X X X X X X X \n"
" X X X X X X X X X X X X X X X \n"
" X X X X X X X X X X X X X X \n"
"X X X X X X X X X X X X X X X X X \n"
" X X X X X X X X X X X X \n"
"X X X X X X X X X X X \n"
" X X X X X X X X X X X X X X X X \n"
" X X X X X X X X X X \n"
"X X X X X X X X X X X X X X \n"
" X X X X X X X X \n"
"X X X X X X X X X X X X X X X \n"
"X X X X X X X X X X \n"
"X X X X X X X X X X X X X X X \n"
"X X X X X X X X X X X \n"
"X X X X X X X X X X X X X X \n"
"X X X X X X X X X X X X \n"
"X X X X X X X X X X X X X X \n");
}
TEST(QREncoderTest, EncodeGS1ModeHeaderWithECI)
{
auto qrCode = Encode(L"hello", ErrorCorrectionLevel::High, CharacterSet::UTF8, 0, true, -1);
EXPECT_EQ(qrCode.mode, CodecMode::BYTE);
EXPECT_EQ(qrCode.ecLevel, ErrorCorrectionLevel::High);
ASSERT_NE(qrCode.version, nullptr);
EXPECT_EQ(qrCode.version->versionNumber(), 1);
EXPECT_EQ(qrCode.maskPattern, 5);
EXPECT_EQ(ToString(qrCode.matrix),
"X X X X X X X X X X X X X X X X X \n"
"X X X X X X \n"
"X X X X X X X X X X X X X \n"
"X X X X X X X X X X X X \n"
"X X X X X X X X X X X X \n"
"X X X X X X X X \n"
"X X X X X X X X X X X X X X X X X \n"
" X X X X \n"
" X X X X X X X X \n"
" X X X X X X X X X X X X X X \n"
" X X X X X X X X X X X \n"
"X X X X X X X X X X X X \n"
"X X X X X X X X X X \n"
" X X X X X X X X \n"
"X X X X X X X X X X X X \n"
"X X X X X X X X \n"
"X X X X X X X X X X \n"
"X X X X X X X X X X X X \n"
"X X X X X X X X X X X \n"
"X X X X X X X X X \n"
"X X X X X X X X X X X X X X \n");
}
TEST(QREncoderTest, AppendModeInfo)
{
BitArray bits;
AppendModeInfo(CodecMode::NUMERIC, bits);
EXPECT_EQ(ToString(bits), "...X");
}
TEST(QREncoderTest, AppendLengthInfo)
{
BitArray bits;
AppendLengthInfo(1, *Version::FromNumber(1), CodecMode::NUMERIC, bits);
EXPECT_EQ(ToString(bits), RemoveSpace("........ .X"));
bits = BitArray();
AppendLengthInfo(2, *Version::FromNumber(10), CodecMode::ALPHANUMERIC, bits);
EXPECT_EQ(ToString(bits), RemoveSpace("........ .X."));
bits = BitArray();
AppendLengthInfo(255, *Version::FromNumber(27), CodecMode::BYTE, bits);
EXPECT_EQ(ToString(bits), RemoveSpace("........ XXXXXXXX"));
bits = BitArray();
AppendLengthInfo(512, *Version::FromNumber(40), CodecMode::KANJI, bits);
EXPECT_EQ(ToString(bits), RemoveSpace("..X..... ....")); }
TEST(QREncoderTest, AppendNumericBytes)
{
BitArray bits;
AppendNumericBytes(L"1", bits);
EXPECT_EQ(ToString(bits), RemoveSpace("...X"));
bits = BitArray();
AppendNumericBytes(L"12", bits);
EXPECT_EQ(ToString(bits), RemoveSpace("...XX.."));
bits = BitArray();
AppendNumericBytes(L"123", bits);
EXPECT_EQ(ToString(bits), RemoveSpace("...XXXX. XX"));
bits = BitArray();
AppendNumericBytes(L"1234", bits);
EXPECT_EQ(ToString(bits), RemoveSpace("...XXXX. XX.X.."));
bits = BitArray();
AppendNumericBytes(L"", bits);
EXPECT_EQ(ToString(bits), RemoveSpace(""));
}
TEST(QREncoderTest, AppendAlphanumericBytes)
{
BitArray bits;
AppendAlphanumericBytes(L"A", bits);
EXPECT_EQ(ToString(bits), RemoveSpace("..X.X."));
bits = BitArray();
AppendAlphanumericBytes(L"AB", bits);
EXPECT_EQ(ToString(bits), RemoveSpace("..XXX..X X.X"));
bits = BitArray();
AppendAlphanumericBytes(L"ABC", bits);
EXPECT_EQ(ToString(bits), RemoveSpace("..XXX..X X.X..XX. ."));
bits = BitArray();
AppendAlphanumericBytes(L"", bits);
EXPECT_EQ(ToString(bits), RemoveSpace(""));
EXPECT_THROW(AppendAlphanumericBytes(L"abc", bits), std::invalid_argument);
}
TEST(QREncoderTest, Append8BitBytes)
{
BitArray bits;
Append8BitBytes(L"abc", CharacterSet::Unknown, bits);
EXPECT_EQ(ToString(bits), RemoveSpace(".XX....X .XX...X. .XX...XX"));
bits = BitArray();
Append8BitBytes(L"", CharacterSet::Unknown, bits);
EXPECT_EQ(ToString(bits), RemoveSpace(""));
}
TEST(QREncoderTest, AppendKanjiBytes)
{
BitArray bits;
AppendKanjiBytes(ShiftJISString({ 0x93, 0x5f }), bits);
EXPECT_EQ(ToString(bits), RemoveSpace(".XX.XX.. XXXXX"));
AppendKanjiBytes(ShiftJISString({ 0xe4, 0xaa }), bits);
EXPECT_EQ(ToString(bits), RemoveSpace(".XX.XX.. XXXXXXX. X.X.X.X. X."));
}
TEST(QREncoderTest, AppendBytes)
{
BitArray bits;
AppendBytes(L"1", CodecMode::NUMERIC, CharacterSet::Unknown, bits);
EXPECT_EQ(ToString(bits), RemoveSpace("...X"));
bits = BitArray();
AppendBytes(L"A", CodecMode::ALPHANUMERIC, CharacterSet::Unknown, bits);
EXPECT_EQ(ToString(bits), RemoveSpace("..X.X."));
bits = BitArray();
EXPECT_THROW(AppendBytes(L"a", CodecMode::ALPHANUMERIC, CharacterSet::Unknown, bits), std::invalid_argument);
bits = BitArray();
AppendBytes(L"abc", CodecMode::BYTE, CharacterSet::Unknown, bits);
EXPECT_EQ(ToString(bits), RemoveSpace(".XX....X .XX...X. .XX...XX"));
AppendBytes(L"\0", CodecMode::BYTE, CharacterSet::Unknown, bits);
bits = BitArray();
AppendBytes(ShiftJISString({0x93, 0x5f}), CodecMode::KANJI, CharacterSet::Unknown, bits);
EXPECT_EQ(ToString(bits), RemoveSpace(".XX.XX.. XXXXX"));
}
TEST(QREncoderTest, TerminateBits)
{
BitArray v;
TerminateBits(0, v);
EXPECT_EQ(ToString(v), RemoveSpace(""));
v = BitArray();
TerminateBits(1, v);
EXPECT_EQ(ToString(v), RemoveSpace("........"));
v = BitArray();
v.appendBits(0, 3);
TerminateBits(1, v);
EXPECT_EQ(ToString(v), RemoveSpace("........"));
v = BitArray();
v.appendBits(0, 5);
TerminateBits(1, v);
EXPECT_EQ(ToString(v), RemoveSpace("........"));
v = BitArray();
v.appendBits(0, 8);
TerminateBits(1, v);
EXPECT_EQ(ToString(v), RemoveSpace("........"));
v = BitArray();
TerminateBits(2, v);
EXPECT_EQ(ToString(v), RemoveSpace("........ XXX.XX.."));
v = BitArray();
v.appendBits(0, 1);
TerminateBits(3, v);
EXPECT_EQ(ToString(v), RemoveSpace("........ XXX.XX.. ...X...X"));
}
TEST(QREncoderTest, GetNumDataBytesAndNumECBytesForBlockID)
{
int numDataBytes;
int numEcBytes;
GetNumDataBytesAndNumECBytesForBlockID(26, 9, 1, 0, numDataBytes, numEcBytes);
EXPECT_EQ(9, numDataBytes);
EXPECT_EQ(17, numEcBytes);
GetNumDataBytesAndNumECBytesForBlockID(70, 26, 2, 0, numDataBytes, numEcBytes);
EXPECT_EQ(13, numDataBytes);
EXPECT_EQ(22, numEcBytes);
GetNumDataBytesAndNumECBytesForBlockID(70, 26, 2, 1, numDataBytes, numEcBytes);
EXPECT_EQ(13, numDataBytes);
EXPECT_EQ(22, numEcBytes);
GetNumDataBytesAndNumECBytesForBlockID(196, 66, 5, 0, numDataBytes, numEcBytes);
EXPECT_EQ(13, numDataBytes);
EXPECT_EQ(26, numEcBytes);
GetNumDataBytesAndNumECBytesForBlockID(196, 66, 5, 4, numDataBytes, numEcBytes);
EXPECT_EQ(14, numDataBytes);
EXPECT_EQ(26, numEcBytes);
GetNumDataBytesAndNumECBytesForBlockID(3706, 1276, 81, 0, numDataBytes, numEcBytes);
EXPECT_EQ(15, numDataBytes);
EXPECT_EQ(30, numEcBytes);
GetNumDataBytesAndNumECBytesForBlockID(3706, 1276, 81, 20, numDataBytes, numEcBytes);
EXPECT_EQ(16, numDataBytes);
EXPECT_EQ(30, numEcBytes);
GetNumDataBytesAndNumECBytesForBlockID(3706, 1276, 81, 80, numDataBytes, numEcBytes);
EXPECT_EQ(16, numDataBytes);
EXPECT_EQ(30, numEcBytes);
}
TEST(QREncoderTest, GenerateECBytes)
{
ByteArray ecBytes;
GenerateECBytes({ 32, 65, 205, 69, 41, 220, 46, 128, 236 }, 17, ecBytes);
ByteArray expected = { 42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224, 96, 74, 219, 61 };
EXPECT_EQ(ecBytes, expected);
GenerateECBytes({ 67, 70, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214 }, 18, ecBytes);
expected = { 175, 80, 155, 64, 178, 45, 214, 233, 65, 209, 12, 155, 117, 31, 140, 214, 27, 187 };
EXPECT_EQ(ecBytes, expected);
GenerateECBytes({ 32, 49, 205, 69, 42, 20, 0, 236, 17 }, 17, ecBytes);
expected = { 0, 3, 130, 179, 194, 0, 55, 211, 110, 79, 98, 72, 170, 96, 211, 137, 213 };
EXPECT_EQ(ecBytes, expected);
}
TEST(QREncoderTest, InterleaveWithECBytes)
{
BitArray in;
for (int dataByte : {32, 65, 205, 69, 41, 220, 46, 128, 236})
in.appendBits(dataByte, 8);
BitArray out = InterleaveWithECBytes(in, 26, 9, 1);
std::vector<uint8_t> expected = {
32, 65, 205, 69, 41, 220, 46, 128, 236,
42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224, 96, 74, 219, 61,
}; ASSERT_EQ(Size(expected), out.sizeInBytes());
EXPECT_EQ(expected, out.toBytes());
in = BitArray();
for (int dataByte :
{67, 70, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214, 230, 247, 7, 23, 39, 55,
71, 87, 103, 119, 135, 151, 166, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214, 230,
247, 7, 23, 39, 55, 71, 87, 103, 119, 135, 151, 160, 236, 17, 236, 17, 236, 17, 236, 17})
in.appendBits(dataByte, 8);
out = InterleaveWithECBytes(in, 134, 62, 4);
expected = {
67, 230, 54, 55, 70, 247, 70, 71, 22, 7, 86, 87, 38, 23, 102, 103, 54, 39, 118, 119, 70,
55, 134, 135, 86, 71, 150, 151, 102, 87, 166, 160, 118, 103, 182, 236, 134, 119, 198, 17, 150, 135,
214, 236, 166, 151, 230, 17, 182, 166, 247, 236, 198, 22, 7, 17, 214, 38, 23, 236, 39, 17,
175, 155, 245, 236, 80, 146, 56, 74, 155, 165, 133, 142, 64, 183, 132, 13, 178, 54, 132, 108, 45,
113, 53, 50, 214, 98, 193, 152, 233, 147, 50, 71, 65, 190, 82, 51, 209, 199, 171, 54, 12, 112,
57, 113, 155, 117, 211, 164, 117, 30, 158, 225, 31, 190, 242, 38, 140, 61, 179, 154, 214, 138, 147,
87, 27, 96, 77, 47, 187, 49, 156, 214,
}; EXPECT_EQ(Size(expected), out.sizeInBytes());
EXPECT_EQ(expected, out.toBytes());
}
TEST(QREncoderTest, BugInBitVectorNumBytes)
{
Encode(std::wstring(3518, L'0'), ErrorCorrectionLevel::Low, CharacterSet::Unknown, 0, false, -1);
}