Changed C++, Rust, Python code to use debug-mode assertions that can be disabled, similar to Java's assert, corresponding to the logic in the Java language port.

This commit is contained in:
Project Nayuki 2021-11-06 17:03:16 +00:00
parent 68cddb816d
commit ad537b93d9
3 changed files with 26 additions and 40 deletions

View File

@ -22,6 +22,7 @@
*/
#include <algorithm>
#include <cassert>
#include <climits>
#include <cstddef>
#include <cstdlib>
@ -278,8 +279,7 @@ QrCode QrCode::encodeSegments(const vector<QrSegment> &segs, Ecc ecl,
throw data_too_long(sb.str());
}
}
if (dataUsedBits == -1)
throw std::logic_error("Assertion error");
assert(dataUsedBits != -1);
// Increase the error correction level while the data still fits in the current version number
for (Ecc newEcl : {Ecc::MEDIUM, Ecc::QUARTILE, Ecc::HIGH}) { // From low to high
@ -294,17 +294,14 @@ QrCode QrCode::encodeSegments(const vector<QrSegment> &segs, Ecc ecl,
bb.appendBits(static_cast<uint32_t>(seg.getNumChars()), seg.getMode().numCharCountBits(version));
bb.insert(bb.end(), seg.getData().begin(), seg.getData().end());
}
if (bb.size() != static_cast<unsigned int>(dataUsedBits))
throw std::logic_error("Assertion error");
assert(bb.size() == static_cast<unsigned int>(dataUsedBits));
// Add terminator and pad up to a byte if applicable
size_t dataCapacityBits = static_cast<size_t>(getNumDataCodewords(version, ecl)) * 8;
if (bb.size() > dataCapacityBits)
throw std::logic_error("Assertion error");
assert(bb.size() <= dataCapacityBits);
bb.appendBits(0, std::min(4, static_cast<int>(dataCapacityBits - bb.size())));
bb.appendBits(0, (8 - static_cast<int>(bb.size() % 8)) % 8);
if (bb.size() % 8 != 0)
throw std::logic_error("Assertion error");
assert(bb.size() % 8 == 0);
// Pad with alternating bytes until data capacity is reached
for (uint8_t padByte = 0xEC; bb.size() < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
@ -352,8 +349,7 @@ QrCode::QrCode(int ver, Ecc ecl, const vector<uint8_t> &dataCodewords, int msk)
applyMask(i); // Undoes the mask due to XOR
}
}
if (msk < 0 || msk > 7)
throw std::logic_error("Assertion error");
assert(0 <= msk && msk <= 7);
mask = msk;
applyMask(msk); // Apply the final choice of mask
drawFormatBits(msk); // Overwrite old format bits
@ -424,8 +420,7 @@ void QrCode::drawFormatBits(int msk) {
for (int i = 0; i < 10; i++)
rem = (rem << 1) ^ ((rem >> 9) * 0x537);
int bits = (data << 10 | rem) ^ 0x5412; // uint15
if (bits >> 15 != 0)
throw std::logic_error("Assertion error");
assert(bits >> 15 == 0);
// Draw first copy
for (int i = 0; i <= 5; i++)
@ -454,8 +449,7 @@ void QrCode::drawVersion() {
for (int i = 0; i < 12; i++)
rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
long bits = static_cast<long>(version) << 12 | rem; // uint18
if (bits >> 18 != 0)
throw std::logic_error("Assertion error");
assert(bits >> 18 == 0);
// Draw two copies
for (int i = 0; i < 18; i++) {
@ -534,8 +528,7 @@ vector<uint8_t> QrCode::addEccAndInterleave(const vector<uint8_t> &data) const {
result.push_back(blocks.at(j).at(i));
}
}
if (result.size() != static_cast<unsigned int>(rawCodewords))
throw std::logic_error("Assertion error");
assert(result.size() == static_cast<unsigned int>(rawCodewords));
return result;
}
@ -563,8 +556,7 @@ void QrCode::drawCodewords(const vector<uint8_t> &data) {
}
}
}
if (i != data.size() * 8)
throw std::logic_error("Assertion error");
assert(i == data.size() * 8);
}
@ -662,11 +654,9 @@ long QrCode::getPenaltyScore() const {
int total = size * size; // Note that size is odd, so dark/total != 1/2
// Compute the smallest integer k >= 0 such that (45-5k)% <= dark/total <= (55+5k)%
int k = static_cast<int>((std::abs(dark * 20L - total * 10L) + total - 1) / total) - 1;
if (!(0 <= k && k <= 9))
throw std::logic_error("Assertion error");
assert(0 <= k && k <= 9);
result += k * PENALTY_N4;
if (!(0 <= result && result <= 2568888L)) // Non-tight upper bound based on default values of PENALTY_N1, ..., N4
throw std::logic_error("Assertion error");
assert(0 <= result && result <= 2568888L); // Non-tight upper bound based on default values of PENALTY_N1, ..., N4
return result;
}
@ -697,8 +687,7 @@ int QrCode::getNumRawDataModules(int ver) {
if (ver >= 7)
result -= 36;
}
if (!(208 <= result && result <= 29648))
throw std::logic_error("Assertion error");
assert(208 <= result && result <= 29648);
return result;
}
@ -755,16 +744,14 @@ uint8_t QrCode::reedSolomonMultiply(uint8_t x, uint8_t y) {
z = (z << 1) ^ ((z >> 7) * 0x11D);
z ^= ((y >> i) & 1) * x;
}
if (z >> 8 != 0)
throw std::logic_error("Assertion error");
assert(z >> 8 == 0);
return static_cast<uint8_t>(z);
}
int QrCode::finderPenaltyCountPatterns(const std::array<int,7> &runHistory) const {
int n = runHistory.at(1);
if (n > size * 3)
throw std::logic_error("Assertion error");
assert(n <= size * 3);
bool core = n > 0 && runHistory.at(2) == n && runHistory.at(3) == n * 3 && runHistory.at(4) == n && runHistory.at(5) == n;
return (core && runHistory.at(0) >= n * 4 && runHistory.at(6) >= n ? 1 : 0)
+ (core && runHistory.at(6) >= n * 4 && runHistory.at(0) >= n ? 1 : 0);

View File

@ -95,8 +95,7 @@ class QrCode:
if datausedbits is not None:
msg = "Data length = {} bits, Max capacity = {} bits".format(datausedbits, datacapacitybits)
raise DataTooLongError(msg)
if datausedbits is None:
raise AssertionError()
assert datausedbits is not None
# Increase the error correction level while the data still fits in the current version number
for newecl in (QrCode.Ecc.MEDIUM, QrCode.Ecc.QUARTILE, QrCode.Ecc.HIGH): # From low to high

View File

@ -240,16 +240,16 @@ impl QrCode {
bb.append_bits(seg.numchars as u32, seg.mode.num_char_count_bits(version));
bb.0.extend_from_slice(&seg.data);
}
assert_eq!(bb.0.len(), datausedbits);
debug_assert_eq!(bb.0.len(), datausedbits);
// Add terminator and pad up to a byte if applicable
let datacapacitybits: usize = QrCode::get_num_data_codewords(version, ecl) * 8;
assert!(bb.0.len() <= datacapacitybits);
debug_assert!(bb.0.len() <= datacapacitybits);
let numzerobits: usize = std::cmp::min(4, datacapacitybits - bb.0.len());
bb.append_bits(0, numzerobits as u8);
let numzerobits: usize = bb.0.len().wrapping_neg() & 7;
bb.append_bits(0, numzerobits as u8);
assert_eq!(bb.0.len() % 8, 0);
debug_assert_eq!(bb.0.len() % 8, 0);
// Pad with alternating bytes until data capacity is reached
for &padbyte in [0xEC, 0x11].iter().cycle() {
@ -415,7 +415,7 @@ impl QrCode {
}
(data << 10 | rem) ^ 0x5412 // uint15
};
assert_eq!(bits >> 15, 0);
debug_assert_eq!(bits >> 15, 0);
// Draw first copy
for i in 0 .. 6 {
@ -456,7 +456,7 @@ impl QrCode {
}
data << 12 | rem // uint18
};
assert_eq!(bits >> 18, 0);
debug_assert_eq!(bits >> 18, 0);
// Draw two copies
for i in 0 .. 18 {
@ -577,7 +577,7 @@ impl QrCode {
}
right -= 2;
}
assert_eq!(i, data.len() * 8);
debug_assert_eq!(i, data.len() * 8);
}
@ -678,9 +678,9 @@ impl QrCode {
let total: i32 = size * size; // Note that size is odd, so dark/total != 1/2
// Compute the smallest integer k >= 0 such that (45-5k)% <= dark/total <= (55+5k)%
let k: i32 = ((dark * 20 - total * 10).abs() + total - 1) / total - 1;
assert!(0 <= k && k <= 9);
debug_assert!(0 <= k && k <= 9);
result += k * PENALTY_N4;
assert!(0 <= result && result <= 2568888); // Non-tight upper bound based on default values of PENALTY_N1, ..., N4
debug_assert!(0 <= result && result <= 2568888); // Non-tight upper bound based on default values of PENALTY_N1, ..., N4
result
}
@ -720,7 +720,7 @@ impl QrCode {
result -= 36;
}
}
assert!((208 ..= 29648).contains(&result));
debug_assert!((208 ..= 29648).contains(&result));
result
}
@ -832,7 +832,7 @@ impl FinderPenalty {
pub fn count_patterns(&self) -> i32 {
let rh = &self.run_history;
let n = rh[1];
assert!(n <= self.qr_size * 3);
debug_assert!(n <= self.qr_size * 3);
let core = n > 0 && rh[2] == n && rh[3] == n * 3 && rh[4] == n && rh[5] == n;
( i32::from(core && rh[0] >= n * 4 && rh[6] >= n)
+ i32::from(core && rh[6] >= n * 4 && rh[0] >= n))