Switched from string to vector of unsigned chars as input
This commit is contained in:
parent
d9f9a26bde
commit
562df68c92
@ -64,7 +64,7 @@ int main() {
|
||||
input = cp1251_to_utf8(input.c_str());
|
||||
#endif
|
||||
|
||||
QRCode qr(input);
|
||||
QRCode qr(input, CorrectionLevel::H);
|
||||
|
||||
const auto& res = qr.to_vector();
|
||||
|
||||
|
@ -91,7 +91,7 @@ void Encoder::encode_alphabetic(const string& input, BitArray& out, unsigned off
|
||||
}
|
||||
}
|
||||
|
||||
void Encoder::encode_byte(const string& input, BitArray& out, unsigned offset)
|
||||
void Encoder::encode_byte(const byte_list& input, BitArray& out, unsigned offset)
|
||||
{
|
||||
for (unsigned i = 0; i < input.size(); i++)
|
||||
out.set(offset + i * 8, input[i], 8);
|
||||
|
@ -13,7 +13,7 @@ using namespace std;
|
||||
class Encoder
|
||||
{
|
||||
public:
|
||||
Encoder(const string& input_, CorrectionLevel corr_lvl_ = CorrectionLevel::M, QRCodeMethod method_ = QRCodeMethod::Dynamic, char version_ = -1) : input{ input_ }, corr_lvl{ corr_lvl_ }, method{ method_ }, version{ version_ } {};
|
||||
Encoder(const byte_list& input_, CorrectionLevel corr_lvl_ = CorrectionLevel::M, QRCodeMethod method_ = QRCodeMethod::Dynamic, char version_ = -1) : input{ input_ }, corr_lvl{ corr_lvl_ }, method{ method_ }, version{ version_ } {};
|
||||
|
||||
BitArray& encode();
|
||||
|
||||
@ -27,10 +27,10 @@ public:
|
||||
constexpr void encode_input(unsigned offset) {
|
||||
switch (method) {
|
||||
case QRCodeMethod::Numeric:
|
||||
encode_numeric(input, e, offset);
|
||||
encode_numeric(bytes_to_str(input), e, offset);
|
||||
break;
|
||||
case QRCodeMethod::Alphabetic:
|
||||
encode_alphabetic(input, e, offset);
|
||||
encode_alphabetic(bytes_to_str(input), e, offset);
|
||||
break;
|
||||
case QRCodeMethod::Byte:
|
||||
encode_byte(input, e, offset);
|
||||
@ -40,7 +40,7 @@ public:
|
||||
|
||||
static void encode_numeric(const string& input, BitArray& out, unsigned offset);
|
||||
static void encode_alphabetic(const string& input, BitArray& out, unsigned offset);
|
||||
static void encode_byte(const string& input, BitArray& out, unsigned offset);
|
||||
static void encode_byte(const byte_list& input, BitArray& out, unsigned offset);
|
||||
|
||||
static void pad_data(BitArray& arr, unsigned bits_written);
|
||||
|
||||
@ -50,7 +50,7 @@ public:
|
||||
private:
|
||||
static constexpr unsigned char encode_char(char ch);
|
||||
|
||||
const string input;
|
||||
const byte_list input;
|
||||
CorrectionLevel corr_lvl;
|
||||
const QRCodeMethod method;
|
||||
char version;
|
||||
@ -86,8 +86,8 @@ constexpr unsigned Encoder::calculate_encoded_input_size(unsigned input_size, QR
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
constexpr unsigned upper_index(const array<T, N> arr, T val) {
|
||||
unsigned count = to_U(arr.size()), s = 0, e = 0, step = 0;
|
||||
constexpr unsigned upper_index(const array<T, N>& arr, T val) {
|
||||
unsigned count = N, s = 0, e = 0, step = 0;
|
||||
|
||||
while (count > 0) {
|
||||
step = count / 2;
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "Method.hpp"
|
||||
#include "Tables.hpp"
|
||||
|
||||
QRCodeMethod Method::determite_method(string& input)
|
||||
QRCodeMethod Method::determite_method(byte_list& input)
|
||||
{
|
||||
QRCodeMethod type = QRCodeMethod::Numeric;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -20,7 +20,7 @@ enum class CorrectionLevel {
|
||||
|
||||
class Method {
|
||||
public:
|
||||
static QRCodeMethod determite_method(string& input);
|
||||
static QRCodeMethod determite_method(byte_list& input);
|
||||
|
||||
static constexpr bool is_num(char ch) { return ch >= '0' && ch <= '9'; };
|
||||
};
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "DataBlocks.hpp"
|
||||
#include "Tables.hpp"
|
||||
|
||||
QRCode::QRCode(string& input_, CorrectionLevel corr_lvl_, QRCodeMethod method_, char version_, unsigned char mask_n) :
|
||||
QRCode::QRCode(const byte_list& input_, CorrectionLevel corr_lvl_, QRCodeMethod method_, char version_, unsigned char mask_n) :
|
||||
input{ input_ }, corr_lvl{ corr_lvl_ }, method{ method_ }, version{ version_ }, matrix(0)
|
||||
{
|
||||
if (method == QRCodeMethod::Dynamic) {
|
||||
|
@ -4,20 +4,22 @@
|
||||
|
||||
#include "Method.hpp"
|
||||
#include "QRMatrix.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class QRCode
|
||||
{
|
||||
public:
|
||||
QRCode(string& input_, CorrectionLevel corr_lvl_ = CorrectionLevel::M, QRCodeMethod method_ = QRCodeMethod::Dynamic, char version_ = -1, unsigned char mask_n = 0);
|
||||
QRCode(const byte_list& input_, CorrectionLevel corr_lvl_ = CorrectionLevel::M, QRCodeMethod method_ = QRCodeMethod::Dynamic, char version_ = -1, unsigned char mask_n = 0);
|
||||
QRCode(const string& input_, CorrectionLevel corr_lvl_ = CorrectionLevel::M, QRCodeMethod method_ = QRCodeMethod::Dynamic, char version_ = -1, unsigned char mask_n = 0) : QRCode(str_to_bytes(input_), corr_lvl_, method_, version_, mask_n) {};
|
||||
|
||||
string to_string() const { return matrix.to_string(); };
|
||||
string to_ascii(char black = '#', char white = ' ', char empty = 'E') const { return matrix.to_ascii(black, white, empty); }
|
||||
vector<vector<Trit>> to_vector() const { return matrix.to_vector(); };
|
||||
|
||||
protected:
|
||||
string input;
|
||||
byte_list input;
|
||||
CorrectionLevel corr_lvl;
|
||||
QRCodeMethod method;
|
||||
char version;
|
||||
|
@ -1,10 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
constexpr unsigned to_U(size_t val) {
|
||||
constexpr static unsigned to_U(size_t val) {
|
||||
if (val > (std::numeric_limits<unsigned int>::max)())
|
||||
throw std::runtime_error("Too big number to convert it to unsigned int" + std::to_string(val));
|
||||
return static_cast<unsigned>(val);
|
||||
}
|
||||
|
||||
using byte_list = std::vector<unsigned char>;
|
||||
|
||||
static byte_list str_to_bytes(const std::string& inp) {
|
||||
return byte_list(inp.begin(), inp.end());
|
||||
}
|
||||
|
||||
static std::string bytes_to_str(const byte_list& inp) {
|
||||
return std::string(inp.begin(), inp.end());
|
||||
}
|
12
README.MD
12
README.MD
@ -7,20 +7,24 @@
|
||||
|
||||
## Description
|
||||
|
||||
A C++ library for QRCode generation. It provides `QRCode` class with constructor, accepting input string and other QR code properties (see constructor definition below). After class construction you can access QR code content as new-line separated string of zeros and ones (useful for latter processing in other languages), multiline ASCII string for immidiate console output, or 2D vector of `Trit`s. It is an internal enum with three possible values: black, white or empty.
|
||||
A C++ library for QRCode generation. It provides `QRCode` class with constructor, accepting input bytes as vector of unsigned chars or string and other QR code properties (see constructor definition below). After class construction you can access QR code content as new-line separated string of zeros and ones (useful for latter processing in other languages), multiline ASCII string for immidiate console output, or 2D vector of `Trit`s. It is an internal enum with three possible values: black, white or empty.
|
||||
|
||||
## Library interface
|
||||
|
||||
```c++
|
||||
using byte_list = vector<unsigned char>; // shorthand for
|
||||
|
||||
class QRCode
|
||||
{
|
||||
public:
|
||||
QRCode( string& input_, // input string for qr-code encoding
|
||||
QRCode( const byte_list& input_, // input bytes for qr-code encoding
|
||||
CorrectionLevel corr_lvl_ = CorrectionLevel::M, // correction level of qr-code (see below for possible values)
|
||||
QRCodeMethod method_ = QRCodeMethod::Dynamic, // input encoding method (see below for possible values)
|
||||
char version_ = -1, // manual version, starting from 0 (0 - 39 versions). If not set, calculated dynamically
|
||||
unsigned char mask_n = 0 // index of mask to use (see below for different masks options)
|
||||
);
|
||||
// same as before except for input as std::string
|
||||
QRCode(const string& input_, CorrectionLevel corr_lvl_ = CorrectionLevel::M, QRCodeMethod method_ = QRCodeMethod::Dynamic, char version_ = -1, unsigned char mask_n = 0)
|
||||
|
||||
string to_string() const; // presents qr-code as multiline string of zeros and ones
|
||||
string to_ascii(char black = '#', char white = ' ', char empty = 'E') const; // presents qr-code as multiline string of specified characters
|
||||
@ -92,9 +96,7 @@ Creating qrcode from string "HELLO WORLD" with quarter correction level, in alph
|
||||
|
||||
// ...
|
||||
|
||||
std::string input("HELLO WORLD");
|
||||
|
||||
QRCode qr(input, CorrectionLevel::Q, QRCodeMethod::Alphabetic, 1, 3);
|
||||
QRCode qr("HELLO WORLD", CorrectionLevel::Q, QRCodeMethod::Alphabetic, 1, 3);
|
||||
|
||||
std::cout << qr.to_ascii('#', ' ', 'E') << std::endl;
|
||||
```
|
||||
|
@ -3,7 +3,6 @@
|
||||
#define private public
|
||||
|
||||
#include "../QRCodeLibrary/Encoder.hpp"
|
||||
#include "../QRCodeLibrary/utils.hpp"
|
||||
|
||||
/* upper_index function */
|
||||
|
||||
@ -89,7 +88,7 @@ TEST(EncoderTests, EncodesAlphabetic) {
|
||||
|
||||
TEST(EncoderTests, EncodesBytes) {
|
||||
BitArray tmp(to_U(string("0000110100001001010011010000101111001101000010111000110100011000001011010001100000001101000010111000110100001011100100100000110100001010100011010000101110001101000110001000110100001011101011010000101111101101000010110010").size()));
|
||||
Encoder::encode_byte(u8"Дмитрий Шишков", tmp, 4);
|
||||
Encoder::encode_byte(str_to_bytes(u8"Дмитрий Шишков"), tmp, 4);
|
||||
|
||||
EXPECT_EQ(std::string(tmp), "0000110100001001010011010000101111001101000010111000110100011000001011010001100000001101000010111000110100001011100100100000110100001010100011010000101110001101000110001000110100001011101011010000101111101101000010110010");
|
||||
}
|
||||
@ -106,15 +105,15 @@ TEST(EncoderTests, PadsData) {
|
||||
}
|
||||
|
||||
TEST(EncoderTests, EncodesInput) {
|
||||
Encoder e1("8675309", CorrectionLevel::Q, QRCodeMethod::Numeric);
|
||||
Encoder e1(str_to_bytes("8675309"), CorrectionLevel::Q, QRCodeMethod::Numeric);
|
||||
e1.encode();
|
||||
EXPECT_EQ(std::string(e1.get_data()), "00010000000111110110001110000100101001001110110000010001111011000001000111101100000100011110110000010001");
|
||||
|
||||
Encoder e2("HELLO WORLD", CorrectionLevel::M, QRCodeMethod::Alphabetic);
|
||||
Encoder e2(str_to_bytes("HELLO WORLD"), CorrectionLevel::M, QRCodeMethod::Alphabetic);
|
||||
e2.encode();
|
||||
EXPECT_EQ(std::string(e2.get_data()), "00100000010110110000101101111000110100010111001011011100010011010100001101000000111011000001000111101100000100011110110000010001");
|
||||
|
||||
Encoder e3(u8"Дмитрий Шишков", CorrectionLevel::Q, QRCodeMethod::Byte);
|
||||
Encoder e3(str_to_bytes(u8"Дмитрий Шишков"), CorrectionLevel::Q, QRCodeMethod::Byte);
|
||||
e3.encode();
|
||||
EXPECT_EQ(std::string(e3.get_data()), "01000001101111010000100101001101000010111100110100001011100011010001100000101101000110000000110100001011100011010000101110010010000011010000101010001101000010111000110100011000100011010000101110101101000010111110110100001011001000001110110000010001111011000001000111101100");
|
||||
}
|
@ -10,9 +10,9 @@ TEST(MethodTests, DetermitesStringMethod) {
|
||||
string a2("ABC");
|
||||
string a3("ghfjghfj gfjhgd");
|
||||
|
||||
EXPECT_EQ(Method::determite_method(a1), QRCodeMethod::Numeric);
|
||||
EXPECT_EQ(Method::determite_method(a2), QRCodeMethod::Alphabetic);
|
||||
EXPECT_EQ(Method::determite_method(a3), QRCodeMethod::Byte);
|
||||
EXPECT_EQ(Method::determite_method(str_to_bytes(a1)), QRCodeMethod::Numeric);
|
||||
EXPECT_EQ(Method::determite_method(str_to_bytes(a2)), QRCodeMethod::Alphabetic);
|
||||
EXPECT_EQ(Method::determite_method(str_to_bytes(a3)), QRCodeMethod::Byte);
|
||||
}
|
||||
|
||||
TEST(MethodTests, ChecksNumber) {
|
||||
|
@ -5,16 +5,10 @@
|
||||
|
||||
#include "../QRCodeLibrary/QRCode.hpp"
|
||||
|
||||
class QRCodeConstructorMock : public QRCode {
|
||||
public:
|
||||
template <typename ...Parameters>
|
||||
QRCodeConstructorMock(Parameters ...params) {};
|
||||
};
|
||||
TEST(QRCodeTests, ConstructsClass) {
|
||||
string inp("TESTTESTTESTTESTTESTTEST");
|
||||
QRCode qr(inp);
|
||||
QRCode qr("TESTTESTTESTTESTTESTTEST");
|
||||
|
||||
EXPECT_EQ(qr.input, "TESTTESTTESTTESTTESTTEST");
|
||||
EXPECT_EQ(qr.input, str_to_bytes("TESTTESTTESTTESTTESTTEST"));
|
||||
EXPECT_EQ(qr.corr_lvl, CorrectionLevel::M);
|
||||
EXPECT_EQ(qr.method, QRCodeMethod::Alphabetic);
|
||||
EXPECT_EQ(qr.version, 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user