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.

pull/134/head
Project Nayuki 3 years ago
parent 68cddb816d
commit ad537b93d9

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

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

@ -240,16 +240,16 @@ impl QrCode {
bb.append_bits(seg.numchars as u32, seg.mode.num_char_count_bits(version)); bb.append_bits(seg.numchars as u32, seg.mode.num_char_count_bits(version));
bb.0.extend_from_slice(&seg.data); 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 // Add terminator and pad up to a byte if applicable
let datacapacitybits: usize = QrCode::get_num_data_codewords(version, ecl) * 8; 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()); let numzerobits: usize = std::cmp::min(4, datacapacitybits - bb.0.len());
bb.append_bits(0, numzerobits as u8); bb.append_bits(0, numzerobits as u8);
let numzerobits: usize = bb.0.len().wrapping_neg() & 7; let numzerobits: usize = bb.0.len().wrapping_neg() & 7;
bb.append_bits(0, numzerobits as u8); 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 // Pad with alternating bytes until data capacity is reached
for &padbyte in [0xEC, 0x11].iter().cycle() { for &padbyte in [0xEC, 0x11].iter().cycle() {
@ -415,7 +415,7 @@ impl QrCode {
} }
(data << 10 | rem) ^ 0x5412 // uint15 (data << 10 | rem) ^ 0x5412 // uint15
}; };
assert_eq!(bits >> 15, 0); debug_assert_eq!(bits >> 15, 0);
// Draw first copy // Draw first copy
for i in 0 .. 6 { for i in 0 .. 6 {
@ -456,7 +456,7 @@ impl QrCode {
} }
data << 12 | rem // uint18 data << 12 | rem // uint18
}; };
assert_eq!(bits >> 18, 0); debug_assert_eq!(bits >> 18, 0);
// Draw two copies // Draw two copies
for i in 0 .. 18 { for i in 0 .. 18 {
@ -577,7 +577,7 @@ impl QrCode {
} }
right -= 2; 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 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)% // 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; 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; 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 result
} }
@ -720,7 +720,7 @@ impl QrCode {
result -= 36; result -= 36;
} }
} }
assert!((208 ..= 29648).contains(&result)); debug_assert!((208 ..= 29648).contains(&result));
result result
} }
@ -832,7 +832,7 @@ impl FinderPenalty {
pub fn count_patterns(&self) -> i32 { pub fn count_patterns(&self) -> i32 {
let rh = &self.run_history; let rh = &self.run_history;
let n = rh[1]; 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; 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[0] >= n * 4 && rh[6] >= n)
+ i32::from(core && rh[6] >= n * 4 && rh[0] >= n)) + i32::from(core && rh[6] >= n * 4 && rh[0] >= n))

Loading…
Cancel
Save