#include "BarcodeFormat.h"
#include "Version.h"
#include "ZXAlgorithms.h"
#include <algorithm>
namespace ZXing {
static_assert(ZX_BCF_ID('\0', '\0') == 0, "BarcodeFormat encoding error");
BarcodeFormat Symbology(BarcodeFormat format)
{
return BarcodeFormat(ZX_BCF_ID(SymbologyKey(format), ' ' * (VariantKey(format) != 0)));
}
std::string_view Name(BarcodeFormat format)
{
switch (format) {
#define X(NAME, SYM, VAR, FLAGS, ZINT, ENABLED, HRI) \
case BarcodeFormat(ZX_BCF_ID(SYM, VAR)): return HRI;
ZX_BCF_LIST(X)
#undef X
default: return "Unknown";
};
}
BarcodeFormat BarcodeFormatFromString(std::string_view str)
{
if (str.size() < 3)
throw std::invalid_argument(StrCat("This is not a valid barcode format: '", str, "'"));
#define X(NAME, SYM, VAR, FLAGS, ZINT, ENABLED, HRI) \
if ((str[0] == ']' && str[1] == SYM && str[2] == VAR) || IsEqualIgnoreCase(str, #NAME) || IsEqualIgnoreCaseAnd(str, HRI, " -_/")) \
return BarcodeFormat(ZX_BCF_ID(SYM, VAR));
ZX_BCF_LIST(X)
#undef X
throw std::invalid_argument(StrCat("This is not a valid barcode format: '", str, "'"));
}
std::string ToString(BarcodeFormat format)
{
return std::string(Name(format));
}
bool operator<=(BarcodeFormat e, BarcodeFormat s)
{
return e == s || s == BarcodeFormat::All
|| (SymbologyKey(s) == '*' ? SymbologyKey(e) != '*' && (e & s)
: SymbologyKey(s) == SymbologyKey(e) && VariantKey(s) == ' ');
}
bool operator&(BarcodeFormat a, BarcodeFormat b)
{
if (SymbologyKey(a) == '*' && SymbologyKey(b) == '*') {
switch (VariantKey(a)) {
case 'l': return ZXING_ENABLE_1D && !Contains("smp", VariantKey(b));
case 's': return ZXING_ENABLE_PDF417 && !Contains("lmp", VariantKey(b));
case 'p': return !Contains("lms", VariantKey(b)); case 'm':
return (ZXING_ENABLE_MAXICODE || ZXING_ENABLE_QRCODE || ZXING_ENABLE_DATAMATRIX || ZXING_ENABLE_AZTEC)
&& !Contains("lsp", VariantKey(b));
default: return true;
}
}
if (SymbologyKey(a) == '*')
std::swap(a, b);
if (SymbologyKey(b) == '*') {
char vkb = VariantKey(b);
if (vkb == '*')
return true;
switch (a) {
#ifdef ZXING_USE_ZINT
#define USING_ZINT 1
#else
#define USING_ZINT 0
#endif
#define X(NAME, SYM, VAR, FLAGS, ZINT, ENABLED, HRI) \
case BarcodeFormat(ZX_BCF_ID(SYM, VAR)): \
return ENABLED \
&& ((vkb == 'w' && USING_ZINT) ? ZINT : (FLAGS[0] == vkb || FLAGS[1] == vkb || FLAGS[2] == vkb || FLAGS[3] == vkb || FLAGS[4] == vkb));
ZX_BCF_LIST(X)
#undef X
};
}
if (a == b || Symbology(a) == b || a == Symbology(b))
return true;
return false;
}
inline bool operator<(BarcodeFormat a, BarcodeFormat b)
{
return SymbologyKey(a) < SymbologyKey(b) || (SymbologyKey(a) == SymbologyKey(b) && VariantKey(a) < VariantKey(b));
}
void BarcodeFormats::normalize()
{
std::erase_if(formats_, [](BarcodeFormat t) { return t == BarcodeFormat::None; });
std::sort(formats_.begin(), formats_.end());
formats_.erase(std::unique(formats_.begin(), formats_.end()), formats_.end());
}
BarcodeFormats::BarcodeFormats(std::string_view str)
{
while (str.size() >= 3 && str[0] == ']') {
formats_.push_back(BarcodeFormat(ZX_BCF_ID(str[1], str[2])));
str.remove_prefix(3);
}
ForEachToken(TrimWS(str, " []"), ",|", [this](std::string_view token) {
if (!token.empty())
formats_.push_back(BarcodeFormatFromString(token));
});
normalize();
}
BarcodeFormats BarcodeFormats::list(const BarcodeFormats& filter)
{
std::vector<BarcodeFormat> res;
res.reserve(100);
if (filter.empty()) {
#define X(NAME, SYM, VAR, FLAGS, ZINT, ENABLED, HRI) \
if (ENABLED) \
res.push_back(BarcodeFormat(ZX_BCF_ID(SYM, VAR)));
ZX_BCF_LIST(X)
#undef X
return res;
}
for (auto f : filter) {
#define X(NAME, SYM, VAR, FLAGS, ZINT, ENABLED, HRI) \
if (ENABLED && SYM != '*' \
&& (SymbologyKey(f) == '*' ? BarcodeFormat(ZX_BCF_ID(SYM, VAR)) & f \
: SYM == SymbologyKey(f) && (VariantKey(f) == ' ' || VariantKey(f) == VAR))) \
res.push_back(BarcodeFormat(ZX_BCF_ID(SYM, VAR)));
ZX_BCF_LIST(X)
#undef X
}
return res;
}
BarcodeFormats BarcodeFormats::operator&(const BarcodeFormats& other)
{
std::vector<BarcodeFormat> res;
std::set_intersection(begin(), end(), other.begin(), other.end(), std::back_inserter(res));
return res;
}
BarcodeFormats BarcodeFormatsFromString(std::string_view str)
{
return BarcodeFormats(str);
}
std::string ToString(const BarcodeFormats& formats)
{
if (formats.empty())
return {};
std::string res;
for (auto f : formats)
res += std::string(Name(f)) + ", ";
return res.substr(0, res.size() - 2);
}
}
#if 0#endif