Skip to content

Commit 938b2d9

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 938b2d9

File tree

1 file changed

+27
-24
lines changed

1 file changed

+27
-24
lines changed

src/electronic-id.cpp

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,30 @@ 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 enforces equal size pattern and mask arrays at compile time.
114+
template <size_t N>
115+
constexpr MaskedATREntry(const byte_type (&_pat)[N], const byte_type (&_mask)[N],
116+
ElectronicIDConstructor&& _constructor) :
117+
pattern(std::begin(_pat), std::end(_pat)), mask(std::begin(_mask), std::end(_mask)),
118+
constructor(std::move(_constructor))
119+
{
120+
}
121+
122+
bool operator==(const byte_vector& atr) const
123+
{
124+
if (atr.size() != pattern.size()) {
125+
return false;
126+
}
127+
128+
for (size_t i = 0; i < atr.size(); ++i) {
129+
if ((atr[i] & mask[i]) != (pattern[i] & mask[i])) {
130+
return false;
131+
}
132+
}
133+
134+
return true;
135+
}
136+
113137
byte_vector pattern;
114138
byte_vector mask;
115139
ElectronicIDConstructor constructor;
@@ -135,26 +159,6 @@ std::string byteVectorToHexString(const byte_vector& bytes)
135159
return hexStringBuilder.str();
136160
}
137161

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-
158162
const auto SUPPORTED_ALGORITHMS = std::map<std::string, HashAlgorithm> {
159163
{"SHA-224"s, HashAlgorithm::SHA224}, {"SHA-256"s, HashAlgorithm::SHA256},
160164
{"SHA-384"s, HashAlgorithm::SHA384}, {"SHA-512"s, HashAlgorithm::SHA512},
@@ -169,10 +173,9 @@ namespace electronic_id
169173

170174
std::optional<ElectronicIDConstructor> findMaskedATR(const byte_vector& atr)
171175
{
172-
for (const auto& entry : MASKED_ATRS) {
173-
if (matchATRWithMask(atr, entry.pattern, entry.mask)) {
174-
return entry.constructor;
175-
}
176+
if (auto i = std::find(MASKED_ATRS.cbegin(), MASKED_ATRS.cend(), atr);
177+
i != MASKED_ATRS.cend()) {
178+
return i->constructor;
176179
}
177180
return std::nullopt;
178181
}

0 commit comments

Comments
 (0)