mirror of
https://git.code.sf.net/p/zint/code
synced 2025-05-13 22:54:35 -04:00
ITF-14/EAN-14/NVE-18: allow check digit to be given and then
verified; allow and ignore prefixes "01", "[01]" and "(01)" (or "00" etc if NVE-18) if check digit given, following commit [789e04] (ticket #333)
This commit is contained in:
parent
d886ecf5c7
commit
86363ff0f7
7 changed files with 211 additions and 84 deletions
|
@ -42,32 +42,53 @@
|
|||
INTERNAL int gs1_128(struct zint_symbol *symbol, unsigned char source[], int length);
|
||||
|
||||
/* Helper to do NVE18 or EAN14 */
|
||||
static int nve18_or_ean14(struct zint_symbol *symbol, unsigned char source[], const int length, const int data_len) {
|
||||
static int nve18_or_ean14(struct zint_symbol *symbol, const unsigned char source[], int length, const int data_len) {
|
||||
static const char prefix[2][2][5] = {
|
||||
{ "(01)", "[01]" }, /* EAN14 */
|
||||
{ "(00)", "[00]" }, /* NVE18 */
|
||||
};
|
||||
const int idx = data_len == 17;
|
||||
unsigned char ean128_equiv[23];
|
||||
int i, zeroes;
|
||||
unsigned char have_check_digit = '\0';
|
||||
unsigned char check_digit;
|
||||
int error_number;
|
||||
|
||||
if (length > data_len) {
|
||||
return ZEXT errtxtf(ZINT_ERROR_TOO_LONG, symbol, 345, "Input length %1$d too long (maximum %2$d)", length,
|
||||
data_len);
|
||||
/* Allow and ignore any AI prefix, but only if have check digit */
|
||||
if (length == data_len + 1 + 4
|
||||
&& (memcmp(source, prefix[idx][0], 4) == 0 || memcmp(source, prefix[idx][1], 4) == 0)) {
|
||||
source += 4;
|
||||
length -= 4;
|
||||
/* Likewise initial '01' (EAN-14) or '00' (NVE-18), if have check digit */
|
||||
} else if (length == data_len + 1 + 2 && source[0] == prefix[idx][0][1] && source[1] == prefix[idx][0][2]) {
|
||||
source += 2;
|
||||
length -= 2;
|
||||
}
|
||||
if (length > data_len + 1) {
|
||||
return ZEXT errtxtf(ZINT_ERROR_TOO_LONG, symbol, 345, "Input length %1$d too long (maximum %2$d)",
|
||||
length, data_len + 1);
|
||||
}
|
||||
|
||||
if ((i = not_sane(NEON_F, source, length))) {
|
||||
/* Note: for all "at position" error messages, escape sequences not accounted for */
|
||||
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 346,
|
||||
"Invalid character at position %d in input (digits only)", i);
|
||||
}
|
||||
if (length == data_len + 1) {
|
||||
have_check_digit = source[data_len];
|
||||
length--;
|
||||
}
|
||||
|
||||
zeroes = data_len - length;
|
||||
memcpy(ean128_equiv, prefix[data_len == 17][!(symbol->input_mode & GS1PARENS_MODE)], 4);
|
||||
memcpy(ean128_equiv, prefix[idx][!(symbol->input_mode & GS1PARENS_MODE)], 4);
|
||||
memset(ean128_equiv + 4, '0', zeroes);
|
||||
memcpy(ean128_equiv + 4 + zeroes, source, length);
|
||||
|
||||
ean128_equiv[data_len + 4] = gs1_check_digit(ean128_equiv + 4, data_len);
|
||||
check_digit = (unsigned char) gs1_check_digit(ean128_equiv + 4, data_len);
|
||||
if (have_check_digit && have_check_digit != check_digit) {
|
||||
return ZEXT errtxtf(ZINT_ERROR_INVALID_CHECK, symbol, 347, "Invalid check digit '%1$c', expecting '%2$c'",
|
||||
have_check_digit, check_digit);
|
||||
}
|
||||
ean128_equiv[data_len + 4] = check_digit;
|
||||
ean128_equiv[data_len + 5] = '\0'; /* Terminating NUL required by `c128_cost()` */
|
||||
|
||||
error_number = gs1_128(symbol, ean128_equiv, data_len + 5);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue