Skip to content

Commit 6eaecf4

Browse files
mrtsmetsma
andcommitted
Refactor MaskedATREntry to enforce equal pattern/mask sizes at compile time, add operator==
WE2-1040 Signed-off-by: Mart Somermaa <mrts@users.noreply.github.com> Co-authored-by: Raul Metsma <raul@metsma.ee>
1 parent b382e4c commit 6eaecf4

File tree

1 file changed

+28
-24
lines changed

1 file changed

+28
-24
lines changed

src/electronic-id.cpp

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,31 @@ const std::map<byte_vector, ElectronicIDConstructor> SUPPORTED_ATRS {
110110
// Holds ATR pattern, mask, and constructor for variable ATR cards.
111111
struct MaskedATREntry
112112
{
113+
// Single template parameter assures that the pattern and mask arrays are of equal size
114+
// at compile time.
115+
template <size_t N>
116+
constexpr MaskedATREntry(const byte_type (&_pat)[N], const byte_type (&_mask)[N],
117+
ElectronicIDConstructor&& _constructor) :
118+
pattern(std::begin(_pat), std::end(_pat)), mask(std::begin(_mask), std::end(_mask)),
119+
constructor(std::move(_constructor))
120+
{
121+
}
122+
123+
bool operator==(const byte_vector& atr) const
124+
{
125+
if (atr.size() != pattern.size()) {
126+
return false;
127+
}
128+
129+
for (size_t i = 0; i < atr.size(); ++i) {
130+
if ((atr[i] & mask[i]) != (pattern[i] & mask[i])) {
131+
return false;
132+
}
133+
}
134+
135+
return true;
136+
}
137+
113138
byte_vector pattern;
114139
byte_vector mask;
115140
ElectronicIDConstructor constructor;
@@ -135,26 +160,6 @@ std::string byteVectorToHexString(const byte_vector& bytes)
135160
return hexStringBuilder.str();
136161
}
137162

138-
bool matchATRWithMask(const byte_vector& atr, const byte_vector& pattern, const byte_vector& mask)
139-
{
140-
if (pattern.size() != mask.size()) {
141-
THROW(ProgrammingError,
142-
"MaskedATREntry '" + byteVectorToHexString(pattern)
143-
+ "' pattern size does not match mask size");
144-
}
145-
146-
if (atr.size() != pattern.size()) {
147-
return false;
148-
}
149-
for (size_t i = 0; i < atr.size(); ++i) {
150-
if ((atr[i] & mask[i]) != (pattern[i] & mask[i])) {
151-
return false;
152-
}
153-
}
154-
155-
return true;
156-
}
157-
158163
const auto SUPPORTED_ALGORITHMS = std::map<std::string, HashAlgorithm> {
159164
{"SHA-224"s, HashAlgorithm::SHA224}, {"SHA-256"s, HashAlgorithm::SHA256},
160165
{"SHA-384"s, HashAlgorithm::SHA384}, {"SHA-512"s, HashAlgorithm::SHA512},
@@ -169,10 +174,9 @@ namespace electronic_id
169174

170175
std::optional<ElectronicIDConstructor> findMaskedATR(const byte_vector& atr)
171176
{
172-
for (const auto& entry : MASKED_ATRS) {
173-
if (matchATRWithMask(atr, entry.pattern, entry.mask)) {
174-
return entry.constructor;
175-
}
177+
if (auto i = std::find(MASKED_ATRS.cbegin(), MASKED_ATRS.cend(), atr);
178+
i != MASKED_ATRS.cend()) {
179+
return i->constructor;
176180
}
177181
return std::nullopt;
178182
}

0 commit comments

Comments
 (0)