MAILMARK_2D: fix postcode validation: no limited alphanumerics,

spaced-out DPS "outward"-only allowed, all-blank DPS allowed
  (ticket #334, props Milton Neal)
This commit is contained in:
gitlost 2025-04-09 00:10:51 +01:00
parent 86363ff0f7
commit 182c84fa4d
6 changed files with 263 additions and 158 deletions

View file

@ -1,4 +1,4 @@
Version 2.15.0.9 (dev) not released yet (2025-04-04) Version 2.15.0.9 (dev) not released yet (2025-04-09)
==================================================== ====================================================
**Incompatible changes** **Incompatible changes**
@ -42,6 +42,9 @@ Bugs
`ZINT_CAP_STACKABLE` `ZINT_CAP_STACKABLE`
- ZBarcode_Cap: add missing symbologies to `ZINT_CAP_BINDABLE` (was - ZBarcode_Cap: add missing symbologies to `ZINT_CAP_BINDABLE` (was
`ZINT_CAP_STACKABLE`) `ZINT_CAP_STACKABLE`)
- MAILMARK_2D: fix postcode validation: no limited alphanumerics, spaced-out
DPS "outward"-only allowed, all-blank DPS allowed (ticket #334, props Milton
Neal)
- manual/man page: fix DATAMATRIX Sizes tables "28 12x26" -> "27 12x26" - manual/man page: fix DATAMATRIX Sizes tables "28 12x26" -> "27 12x26"

View file

@ -40,6 +40,7 @@
* *
*/ */
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include "common.h" #include "common.h"
#include "large.h" #include "large.h"
@ -48,15 +49,15 @@
#define RUBIDIUM_F (IS_NUM_F | IS_UPR_F | IS_SPC_F) /* RUBIDIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ " */ #define RUBIDIUM_F (IS_NUM_F | IS_UPR_F | IS_SPC_F) /* RUBIDIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ " */
/* Allowed character values from Table 3 */ /* Allowed character values from Table 3 */
#define SET_F "ABCDEFGHIJKLMNOPQRSTUVWXYZ" #define SET_A "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define SET_L "ABDEFGHJLNPQRSTUWXYZ" #define SET_L "ABDEFGHJLNPQRSTUWXYZ"
#define SET_N "0123456789" #define SET_N "0123456789"
#define SET_S " " #define SET_S " "
static const char mailmark_postcode_format[6][9] = { static const char mailmark_postcode_format[6][9] = {
{'F','N','F','N','L','L','N','L','S'}, {'F','F','N','N','L','L','N','L','S'}, {'A','N','A','N','L','L','N','L','S'}, {'A','A','N','N','L','L','N','L','S'},
{'F','F','N','N','N','L','L','N','L'}, {'F','F','N','F','N','L','L','N','L'}, {'A','A','N','N','N','L','L','N','L'}, {'A','A','N','A','N','L','L','N','L'},
{'F','N','N','L','L','N','L','S','S'}, {'F','N','N','N','L','L','N','L','S'} {'A','N','N','L','L','N','L','S','S'}, {'A','N','N','N','L','L','N','L','S'}
}; };
/* Data/Check Symbols from Table 5 */ /* Data/Check Symbols from Table 5 */
@ -80,15 +81,16 @@ static const unsigned char mailmark_extender_group_l[26] = {
2, 5, 7, 8, 13, 14, 15, 16, 21, 22, 23, 0, 1, 3, 4, 6, 9, 10, 11, 12, 17, 18, 19, 20, 24, 25 2, 5, 7, 8, 13, 14, 15, 16, 21, 22, 23, 0, 1, 3, 4, 6, 9, 10, 11, 12, 17, 18, 19, 20, 24, 25
}; };
static int mailmark_verify_character(char input, char type) { static int mailmark_verify_character(const char input, const char type, const int is_2d) {
int val = 0; int val = 0;
switch (type) { switch (type) {
case 'F': case 'A':
val = posn(SET_F, input); val = posn(SET_A, input);
break; break;
case 'L': case 'L':
val = posn(SET_L, input); /* Limited only applies to 4-state (ticket #334, props Milton Neal) */
val = posn(is_2d ? SET_A : SET_L, input);
break; break;
case 'N': case 'N':
val = posn(SET_N, input); val = posn(SET_N, input);
@ -98,35 +100,33 @@ static int mailmark_verify_character(char input, char type) {
break; break;
} }
if (val == -1) { return val != -1;
return 0;
} else {
return 1;
}
} }
static int mailmark_verify_postcode(const char postcode[10], int *p_postcode_type) { static int mailmark_verify_postcode(const char postcode[10], const int length, int *p_postcode_type) {
const int is_2d = !p_postcode_type;
int postcode_type; int postcode_type;
/* Detect postcode type */ /* Detect postcode type */
/* postcode_type is used to select which format of postcode /* postcode_type is used to select which format of postcode
* *
* 1 = FNFNLLNLS * 1 = ANANLLNLS
* 2 = FFNNLLNLS * 2 = AANNLLNLS
* 3 = FFNNNLLNL * 3 = AANNNLLNL
* 4 = FFNFNLLNL * 4 = AANANLLNL
* 5 = FNNLLNLSS * 5 = ANNLLNLSS
* 6 = FNNNLLNLS * 6 = ANNNLLNLS
* 7 = International designation * 7 = International designation
*/ */
assert(length == 9 || (length >= 2 && length <= 4));
if (strcmp(postcode, "XY11 ") == 0) { if (length >= 4 && memcmp(postcode, "XY11 ", length) == 0) {
postcode_type = 7; postcode_type = 7;
} else { } else {
if (postcode[7] == ' ') { if (length == 2 || (length == 9 && postcode[7] == ' ')) {
postcode_type = 5; postcode_type = 5;
} else { } else {
if (postcode[8] == ' ') { if (length == 3 || (length == 9 && postcode[8] == ' ')) {
/* Types 1, 2 and 6 */ /* Types 1, 2 and 6 */
if (z_isdigit(postcode[1])) { if (z_isdigit(postcode[1])) {
if (z_isdigit(postcode[2])) { if (z_isdigit(postcode[2])) {
@ -138,6 +138,7 @@ static int mailmark_verify_postcode(const char postcode[10], int *p_postcode_typ
postcode_type = 2; postcode_type = 2;
} }
} else { } else {
assert(length >= 4);
/* Types 3 and 4 */ /* Types 3 and 4 */
if (z_isdigit(postcode[3])) { if (z_isdigit(postcode[3])) {
postcode_type = 3; postcode_type = 3;
@ -156,8 +157,8 @@ static int mailmark_verify_postcode(const char postcode[10], int *p_postcode_typ
if (postcode_type != 7) { if (postcode_type != 7) {
int i; int i;
const char *const pattern = mailmark_postcode_format[postcode_type - 1]; const char *const pattern = mailmark_postcode_format[postcode_type - 1];
for (i = 0; i < 9; i++) { for (i = 0; i < length; i++) {
if (!(mailmark_verify_character(postcode[i], pattern[i]))) { if (!mailmark_verify_character(postcode[i], pattern[i], is_2d)) {
return 1; return 1;
} }
} }
@ -262,13 +263,12 @@ INTERNAL int mailmark_4s(struct zint_symbol *symbol, unsigned char source[], int
} }
} }
/* Separate Destination Post Code plus DPS field */ /* Destination Post Code plus DPS field */
for (i = 0; i < 9; i++) { for (i = 0; i < 9; i++) {
postcode[i] = local_source[(length - 9) + i]; postcode[i] = local_source[(length - 9) + i];
} }
postcode[9] = '\0'; if (mailmark_verify_postcode(postcode, 9, &postcode_type) != 0) {
if (mailmark_verify_postcode(postcode, &postcode_type) != 0) { return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 587, "Invalid postcode \"%.9s\"", postcode);
return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 587, "Invalid postcode \"%s\"", postcode);
} }
/* Convert postcode to internal user field */ /* Convert postcode to internal user field */
@ -282,9 +282,9 @@ INTERNAL int mailmark_4s(struct zint_symbol *symbol, unsigned char source[], int
for (i = 0; i < 9; i++) { for (i = 0; i < 9; i++) {
switch (pattern[i]) { switch (pattern[i]) {
case 'F': case 'A':
large_mul_u64(&b, 26); large_mul_u64(&b, 26);
large_add_u64(&b, posn(SET_F, postcode[i])); large_add_u64(&b, posn(SET_A, postcode[i]));
break; break;
case 'L': case 'L':
large_mul_u64(&b, 20); large_mul_u64(&b, 20);
@ -511,7 +511,7 @@ INTERNAL int datamatrix(struct zint_symbol *symbol, struct zint_seg segs[], cons
/* Royal Mail 2D Mailmark (CMDM) (Data Matrix) */ /* Royal Mail 2D Mailmark (CMDM) (Data Matrix) */
/* https://www.royalmailtechnical.com/rmt_docs/User_Guides_2021/Mailmark_Barcode_definition_document_20210215.pdf */ /* https://www.royalmailtechnical.com/rmt_docs/User_Guides_2021/Mailmark_Barcode_definition_document_20210215.pdf */
INTERNAL int mailmark_2d(struct zint_symbol *symbol, unsigned char source[], int length) { INTERNAL int mailmark_2d(struct zint_symbol *symbol, unsigned char source[], int length) {
static const char spaces[9] = " ";
unsigned char local_source[90 + 1]; unsigned char local_source[90 + 1];
char postcode[10]; char postcode[10];
int i; int i;
@ -614,12 +614,16 @@ INTERNAL int mailmark_2d(struct zint_symbol *symbol, unsigned char source[], int
} }
/* Destination Post Code plus DPS field */ /* Destination Post Code plus DPS field */
for (i = 0; i < 9; i++) { if (memcmp(local_source + 22, spaces, 9) != 0) { /* If not blank (allowed) */
postcode[i] = local_source[22 + i]; for (i = 0; i < 9; i++) {
} postcode[i] = local_source[22 + i];
postcode[9] = '\0'; }
if (mailmark_verify_postcode(postcode, NULL) != 0) { for (i = 8; i >= 0 && postcode[i] == ' '; i--); /* Find trailing spaces */
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 872, "Invalid Destination Post Code plus DPS"); i++;
/* If not 2 to 4 non-spaces left, check full post code */
if (mailmark_verify_postcode(postcode, i >= 2 && i <= 4 ? i : 9, NULL /*p_postcode_type*/) != 0) {
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 872, "Invalid Destination Post Code plus DPS");
}
} }
/* Service Type */ /* Service Type */
@ -628,7 +632,7 @@ INTERNAL int mailmark_2d(struct zint_symbol *symbol, unsigned char source[], int
} }
/* Return to Sender Post Code */ /* Return to Sender Post Code */
if (memcmp(local_source + 32, " ", 7) != 0) { /* If not blank (allowed) */ if (memcmp(local_source + 32, spaces, 7) != 0) { /* If not blank (allowed) */
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
postcode[i] = local_source[32 + i]; postcode[i] = local_source[32 + i];
} }
@ -640,14 +644,13 @@ INTERNAL int mailmark_2d(struct zint_symbol *symbol, unsigned char source[], int
while (i != 9) { while (i != 9) {
postcode[i++] = ' '; postcode[i++] = ' ';
} }
postcode[9] = '\0'; if (mailmark_verify_postcode(postcode, 9, NULL /*p_postcode_type*/) != 0) {
if (mailmark_verify_postcode(postcode, NULL) != 0) {
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 874, "Invalid Return to Sender Post Code"); return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 874, "Invalid Return to Sender Post Code");
} }
} }
/* Reserved */ /* Reserved */
if (memcmp(local_source + 39, " ", 6) != 0) { if (memcmp(local_source + 39, spaces, 6) != 0) {
return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 875, "Invalid Reserved field (must be spaces only)"); return errtxt(ZINT_ERROR_INVALID_DATA, symbol, 875, "Invalid Reserved field (must be spaces only)");
} }

View file

@ -69,8 +69,8 @@ static void test_4s_hrt(const testCtx *const p_ctx) {
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
length = testUtilSetSymbol(symbol, BARCODE_MAILMARK_4S, -1 /*input_mode*/, -1 /*eci*/, length = testUtilSetSymbol(symbol, BARCODE_MAILMARK_4S, -1 /*input_mode*/, -1 /*eci*/,
-1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options, -1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, data[i].output_options,
data[i].data, -1, debug); data[i].data, -1, debug);
expected_length = (int) strlen(data[i].expected); expected_length = (int) strlen(data[i].expected);
expected_raw_length = (int) strlen(data[i].expected_raw); expected_raw_length = (int) strlen(data[i].expected_raw);
@ -167,7 +167,8 @@ static void test_4s_input(const testCtx *const p_ctx) {
/* 53*/ { "01000000000000000C12JQ3U A", ZINT_ERROR_INVALID_DATA, -1, -1 }, /* F N N L L N L S S bad 2nd S */ /* 53*/ { "01000000000000000C12JQ3U A", ZINT_ERROR_INVALID_DATA, -1, -1 }, /* F N N L L N L S S bad 2nd S */
/* 54*/ { "01000000000000000C123JQ4U ", 0, 3, 155, }, /* F N N N L L N L S */ /* 54*/ { "01000000000000000C123JQ4U ", 0, 3, 155, }, /* F N N N L L N L S */
/* 55*/ { "01000000000000000C 23JQ4U ", ZINT_ERROR_INVALID_DATA, -1, -1 }, /* F N N N L L N L S bad 1st N (non-alpha otherwise matches 2nd pattern) */ /* 55*/ { "01000000000000000C 23JQ4U ", ZINT_ERROR_INVALID_DATA, -1, -1 }, /* F N N N L L N L S bad 1st N (non-alpha otherwise matches 2nd pattern) */
/* 56*/ { "41038422416563762XY1", ZINT_ERROR_INVALID_DATA, -1, -1 }, /* 56*/ { "01000000000000000 ", ZINT_ERROR_INVALID_DATA, -1, -1 }, /* All spaces */
/* 57*/ { "41038422416563762XY1", ZINT_ERROR_INVALID_DATA, -1, -1 },
}; };
const int data_size = ARRAY_SIZE(data); const int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
@ -182,14 +183,19 @@ static void test_4s_input(const testCtx *const p_ctx) {
symbol = ZBarcode_Create(); symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
length = testUtilSetSymbol(symbol, BARCODE_MAILMARK_4S, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); length = testUtilSetSymbol(symbol, BARCODE_MAILMARK_4S, -1 /*input_mode*/, -1 /*eci*/,
-1 /*option_1*/, -1 /*option_2*/, -1 /*option_2*/, -1 /*output_options*/,
data[i].data, -1, debug);
ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n",
i, ret, data[i].ret, symbol->errtxt);
if (ret < ZINT_ERROR) { if (ret < ZINT_ERROR) {
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n",
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n",
i, symbol->width, data[i].expected_width);
} }
ZBarcode_Delete(symbol); ZBarcode_Delete(symbol);
@ -252,19 +258,24 @@ static void test_4s_encode_vector(const testCtx *const p_ctx) {
symbol = ZBarcode_Create(); symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
length = testUtilSetSymbol(symbol, BARCODE_MAILMARK_4S, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); length = testUtilSetSymbol(symbol, BARCODE_MAILMARK_4S, -1 /*input_mode*/, -1 /*eci*/,
-1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, -1 /*output_options*/,
data[i].data, -1, debug);
ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret_encode, symbol->errtxt); assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d (%s)\n",
i, ret, data[i].ret_encode, symbol->errtxt);
assert_equal(symbol->rows, 3, "i:%d symbol->rows %d != 3\n", i, symbol->rows); assert_equal(symbol->rows, 3, "i:%d symbol->rows %d != 3\n", i, symbol->rows);
ret = testUtilDAFTConvert(symbol, actual_daft, sizeof(actual_daft)); ret = testUtilDAFTConvert(symbol, actual_daft, sizeof(actual_daft));
assert_nonzero(ret, "i:%d testUtilDAFTConvert ret == 0", i); assert_nonzero(ret, "i:%d testUtilDAFTConvert ret == 0", i);
assert_zero(strcmp(actual_daft, data[i].expected_daft), "i:%d\n actual %s\nexpected %s\n", i, actual_daft, data[i].expected_daft); assert_zero(strcmp(actual_daft, data[i].expected_daft), "i:%d\n actual %s\nexpected %s\n",
i, actual_daft, data[i].expected_daft);
ret = ZBarcode_Buffer_Vector(symbol, 0); ret = ZBarcode_Buffer_Vector(symbol, 0);
assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d (%s)\n", i, ret, data[i].ret_vector, symbol->errtxt); assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d (%s)\n",
i, ret, data[i].ret_vector, symbol->errtxt);
ZBarcode_Delete(symbol); ZBarcode_Delete(symbol);
} }
@ -306,10 +317,13 @@ static void test_4s_encode(const testCtx *const p_ctx) {
symbol = ZBarcode_Create(); symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
length = testUtilSetSymbol(symbol, BARCODE_MAILMARK_4S, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); length = testUtilSetSymbol(symbol, BARCODE_MAILMARK_4S, -1 /*input_mode*/, -1 /*eci*/,
-1 /*option_1*/, -1 /*option_2*/, -1 /*option_3*/, -1 /*output_options*/,
data[i].data, -1, debug);
ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n",
i, ret, data[i].ret, symbol->errtxt);
if (p_ctx->generate) { if (p_ctx->generate) {
printf(" /*%3d*/ { \"%s\", %s, %d, %d, \"%s\",\n", printf(" /*%3d*/ { \"%s\", %s, %d, %d, \"%s\",\n",
@ -321,11 +335,14 @@ static void test_4s_encode(const testCtx *const p_ctx) {
if (ret < ZINT_ERROR) { if (ret < ZINT_ERROR) {
int width, row; int width, row;
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n",
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); i, symbol->rows, data[i].expected_rows, data[i].data);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n",
i, symbol->width, data[i].expected_width, data[i].data);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n",
i, ret, width, row, data[i].data);
} }
} }
@ -348,6 +365,7 @@ static void test_2d_input(const testCtx *const p_ctx) {
int expected_option_2; int expected_option_2;
}; };
/* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */
/* UUUUIVCSSSSSSSIIIIIIIIDDDDDDDDDSRRRRRRRSSSSSS */
static const struct item data[] = { static const struct item data[] = {
/* 0*/ { -1, "012100123412345678AB19XY1A 0", 0, 24, 24, "", 8 }, /* 0*/ { -1, "012100123412345678AB19XY1A 0", 0, 24, 24, "", 8 },
/* 1*/ { -1, "012100123412345678ab19xy1a 0", 0, 24, 24, "", 8 }, /* Converts to upper */ /* 1*/ { -1, "012100123412345678ab19xy1a 0", 0, 24, 24, "", 8 }, /* Converts to upper */
@ -371,18 +389,36 @@ static void test_2d_input(const testCtx *const p_ctx) {
/* 19*/ { -1, "JGB 01 100123412345678AB19XY1A 0", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 869: Invalid Class (cannot be space)", 8 }, /* 19*/ { -1, "JGB 01 100123412345678AB19XY1A 0", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 869: Invalid Class (cannot be space)", 8 },
/* 20*/ { -1, "JGB 012100123A12345678AB19XY1A 0", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 870: Invalid Supply Chain ID (7 digits only)", 8 }, /* 20*/ { -1, "JGB 012100123A12345678AB19XY1A 0", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 870: Invalid Supply Chain ID (7 digits only)", 8 },
/* 21*/ { -1, "JGB 01210012341234567AAB19XY1A 0", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 871: Invalid Item ID (8 digits only)", 8 }, /* 21*/ { -1, "JGB 01210012341234567AAB19XY1A 0", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 871: Invalid Item ID (8 digits only)", 8 },
/* 22*/ { -1, "JGB 012100123412345678AB19VY1A 0", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 872: Invalid Destination Post Code plus DPS", 8 }, /* 22*/ { -1, "JGB 012100123412345678AB19VY1A 0", 0, 24, 24, "", 8 }, /* Limited ('V') allowed for 2D (ticket #334, props Milton Neal) */
/* 23*/ { -1, "JGB 012100123412345678AB19XY11 0", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 872: Invalid Destination Post Code plus DPS", 8 }, /* 23*/ { -1, "JGB 012100123412345678AB19XY11 0", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 872: Invalid Destination Post Code plus DPS", 8 },
/* 24*/ { -1, "JGB 012100123412345678AB19XY1A 7", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 873: Invalid Service Type (\"0\" to \"6\" only)", 8 }, /* 24*/ { -1, "JGB 012100123412345678ABC9XY1A 0", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 872: Invalid Destination Post Code plus DPS", 8 },
/* 25*/ { -1, "JGB 012100123412345678AB19XY1A 0AB18XY", 0, 24, 24, "", 8 }, /* 25*/ { -1, "JGB 012100123412345678 0AB181XY ", 0, 24, 24, "", 8 }, /* DPS all spaces */
/* 26*/ { -1, "JGB 012100123412345678AB190XY1A0AB18XY", 0, 24, 24, "", 8 }, /* 25*/ { -1, "JGB 012100123412345678AB1 0AB181XY ", 0, 24, 24, "", 8 }, /* DPS 'AAN' + spaces */
/* 27*/ { -1, "JGB 012100123412345678AB19XY1A 0AB18XI", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 874: Invalid Return to Sender Post Code", 8 }, /* 26*/ { -1, "JGB 012100123412345678AB 0AB181XY ", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 872: Invalid Destination Post Code plus DPS", 8 },
/* 28*/ { -1, "JGB 012100123412345678AB19XY1A 0A18XY", 0, 24, 24, "", 8 }, /* 27*/ { -1, "JGB 012100123412345678A1 0AB181XY ", 0, 24, 24, "", 8 }, /* DPS 'AN' + spaces */
/* 29*/ { -1, "JGB 012100123412345678AB19XY1A 0A18XC", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 874: Invalid Return to Sender Post Code", 8 }, /* 28*/ { -1, "JGB 012100123412345678A 0AB181XY ", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 872: Invalid Destination Post Code plus DPS", 8 },
/* 30*/ { -1, "JGB 012100123412345678AB19XY1A 0AB181XY", 0, 24, 24, "", 8 }, /* 29*/ { -1, "JGB 012100123412345678A12 0AB181XY ", 0, 24, 24, "", 8 }, /* DPS 'ANN' + spaces */
/* 31*/ { -1, "JGB 012100123412345678AB19XY1A 0AB181VY", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 874: Invalid Return to Sender Post Code", 8 }, /* 30*/ { -1, "JGB 012100123412345678A123 0AB181XY ", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 872: Invalid Destination Post Code plus DPS", 8 },
/* 32*/ { -1, "JGB 012100123412345678AB19XY1A 0AB181XY ", 0, 24, 24, "", 8 }, /* 31*/ { -1, "JGB 012100123412345678AB12 0AB181XY ", 0, 24, 24, "", 8 }, /* DPS 'AANN' + spaces */
/* 33*/ { -1, "JGB 012100123412345678AB19XY1A 0AB181XYA ", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 875: Invalid Reserved field (must be spaces only)", 8 }, /* 32*/ { -1, "JGB 012100123412345678AB123 0AB181XY ", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 872: Invalid Destination Post Code plus DPS", 8 },
/* 33*/ { -1, "JGB 012100123412345678A1B 0AB181XY ", 0, 24, 24, "", 8 }, /* DPS 'ANA' + spaces */
/* 34*/ { -1, "JGB 012100123412345678A1B1 0AB181XY ", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 872: Invalid Destination Post Code plus DPS", 8 },
/* 35*/ { -1, "JGB 012100123412345678AB1A 0AB181XY ", 0, 24, 24, "", 8 }, /* DPS 'AANA' + spaces */
/* 36*/ { -1, "JGB 012100123412345678AB1A1 0AB181XY ", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 872: Invalid Destination Post Code plus DPS", 8 },
/* 37*/ { -1, "JGB 012100123412345678AB19XY1A 7", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 873: Invalid Service Type (\"0\" to \"6\" only)", 8 },
/* 38*/ { -1, "JGB 012100123412345678AB19XY1A 0AB18XY", 0, 24, 24, "", 8 },
/* 39*/ { -1, "JGB 012100123412345678AB190XY1A0AB18XY", 0, 24, 24, "", 8 },
/* 40*/ { -1, "JGB 012100123412345678AB19XY1A 0AB18XI", 0, 24, 24, "", 8 }, /* Limited ('I') allowed for 2D (ticket #334, props Milton Neal) */
/* 41*/ { -1, "JGB 012100123412345678AB19XY1A 0A18XY", 0, 24, 24, "", 8 },
/* 42*/ { -1, "JGB 012100123412345678AB19XY1A 0A18XC", 0, 24, 24, "", 8 }, /* Limited ('C') allowed for 2D (ticket #334, props Milton Neal) */
/* 43*/ { -1, "JGB 012100123412345678AB19XY1A 0AB181XY", 0, 24, 24, "", 8 },
/* 44*/ { -1, "JGB 012100123412345678AB19XY1A 0AB181VY", 0, 24, 24, "", 8 }, /* Limited ('C') allowed for 2D (ticket #334, props Milton Neal) */
/* 45*/ { -1, "JGB 012100123412345678AB19XY1A 0ABC81XY", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 874: Invalid Return to Sender Post Code", 8 },
/* 46*/ { -1, "JGB 012100123412345678AB19XY1A 01B181VY", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 874: Invalid Return to Sender Post Code", 8 },
/* 47*/ { -1, "JGB 012100123412345678AB19XY1A 0AB1811Y", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 874: Invalid Return to Sender Post Code", 8 },
/* 48*/ { -1, "JGB 012100123412345678AB19XY1A 0A1AB1XY", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 874: Invalid Return to Sender Post Code", 8 },
/* 49*/ { -1, "JGB 012100123412345678AB19XY1A 0AB181XY ", 0, 24, 24, "", 8 },
/* 50*/ { -1, "JGB 012100123412345678AB19XY1A 0AB181XYA ", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 875: Invalid Reserved field (must be spaces only)", 8 },
}; };
const int data_size = ARRAY_SIZE(data); const int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
@ -402,11 +438,14 @@ static void test_2d_input(const testCtx *const p_ctx) {
data[i].data, -1, debug); data[i].data, -1, debug);
ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n",
i, ret, data[i].ret, symbol->errtxt);
if (ret < ZINT_ERROR) { if (ret < ZINT_ERROR) {
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n",
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n",
i, symbol->width, data[i].expected_width);
} }
assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d strcmp(%s, %s) != 0\n",
i, symbol->errtxt, data[i].expected_errtxt); i, symbol->errtxt, data[i].expected_errtxt);
@ -624,10 +663,13 @@ static void test_2d_encode(const testCtx *const p_ctx) {
symbol = ZBarcode_Create(); symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
length = testUtilSetSymbol(symbol, BARCODE_MAILMARK_2D, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug); length = testUtilSetSymbol(symbol, BARCODE_MAILMARK_2D, -1 /*input_mode*/, -1 /*eci*/,
-1 /*option_1*/, data[i].option_2, -1 /*option_3*/, -1 /*output_options*/,
data[i].data, -1, debug);
ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); ret = ZBarcode_Encode(symbol, TCU(data[i].data), length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n",
i, ret, data[i].ret, symbol->errtxt);
if (p_ctx->generate) { if (p_ctx->generate) {
printf(" /*%3d*/ { %d, \"%s\", %s, %d, %d, %d, \"%s\",\n", printf(" /*%3d*/ { %d, \"%s\", %s, %d, %d, %d, \"%s\",\n",
@ -639,30 +681,42 @@ static void test_2d_encode(const testCtx *const p_ctx) {
if (ret < ZINT_ERROR) { if (ret < ZINT_ERROR) {
int width, row; int width, row;
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n",
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); i, symbol->rows, data[i].expected_rows, data[i].data);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n",
i, symbol->width, data[i].expected_width, data[i].data);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n",
i, ret, width, row, data[i].data);
if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) { if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) {
if (!data[i].bwipp_cmp) { if (!data[i].bwipp_cmp) {
if (debug & ZINT_DEBUG_TEST_PRINT) printf("i:%d %s not BWIPP compatible (%s)\n", i, testUtilBarcodeName(symbol->symbology), data[i].comment); if (debug & ZINT_DEBUG_TEST_PRINT) {
printf("i:%d %s not BWIPP compatible (%s)\n",
i, testUtilBarcodeName(symbol->symbology), data[i].comment);
}
} else { } else {
ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf, sizeof(cmp_buf), NULL); ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, cmp_buf,
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); sizeof(cmp_buf), NULL);
assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n",
i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected); ret = testUtilBwippCmp(symbol, cmp_msg, cmp_buf, data[i].expected);
assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n",
i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf, data[i].expected); i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_buf,
data[i].expected);
} }
} }
if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) {
int cmp_len, ret_len; int cmp_len, ret_len;
char modules_dump[144 * 144 + 1]; char modules_dump[144 * 144 + 1];
assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1,
ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf, sizeof(cmp_buf), &cmp_len); "i:%d testUtilModulesDump == -1\n", i);
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, 1 /*zxingcpp_cmp*/, cmp_buf,
sizeof(cmp_buf), &cmp_len);
assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n",
i, testUtilBarcodeName(symbol->symbology), ret);
ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length,
NULL /*primary*/, escaped, &ret_len); NULL /*primary*/, escaped, &ret_len);

View file

@ -5909,26 +5909,24 @@ data-tag=": Royal Mail 4-State Mailmark Input Fields">
</div> </div>
<p>The 6 Destination+DPS (Destination Post Code plus Delivery Point <p>The 6 Destination+DPS (Destination Post Code plus Delivery Point
Suffix) patterns are:</p> Suffix) patterns are:</p>
<div id="tbl:mailmark_destination_dps" class="tablenos"> <div id="tbl:mailmark_4s_destination_dps" class="tablenos">
<table id="tbl:mailmark_destination_dps" <table id="tbl:mailmark_4s_destination_dps"
data-tag=": Royal Mail Mailmark Destination+DPS Patterns"> data-tag=": Royal Mail 4-State Mailmark Destination+DPS Patterns">
<caption><span>Table : Royal Mail Mailmark Destination+DPS <caption><span>Table : Royal Mail 4-State Mailmark Destination+DPS
Patterns:</span> </caption> Patterns:</span> </caption>
<tbody> <tbody>
<tr> <tr>
<td><code>FNFNLLNLS</code></td> <td><code>ANNLLNLSS</code></td>
<td><code>FFNNLLNLS</code></td> <td><code>AANNLLNLS</code></td>
<td><code>FFNNNLLNL</code></td> <td><code>ANNNLLNLS</code></td>
</tr> <td><code>AANNNLLNL</code></td>
<tr> <td><code>ANANLLNLS</code></td>
<td><code>FFNFNLLNL</code></td> <td><code>AANANLLNL</code></td>
<td><code>FNNLLNLSS</code></td>
<td><code>FNNNLLNLS</code></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
<p>where <code>'F'</code> stands for full alphabetic (A-Z), <p>where <code>'A'</code> stands for full alphabetic (A-Z),
<code>'L'</code> for limited alphabetic (A-Z less <code>'L'</code> for limited alphabetic (A-Z less
<code>'CIKMOV'</code>), <code>'N'</code> for numeric (0-9), and <code>'CIKMOV'</code>), <code>'N'</code> for numeric (0-9), and
<code>'S'</code> for space.</p> <code>'S'</code> for space.</p>
@ -6300,7 +6298,7 @@ data-tag=": Royal Mail 2D Mailmark Input Fields">
<tr> <tr>
<td style="text-align: left;">Destination+DPS</td> <td style="text-align: left;">Destination+DPS</td>
<td style="text-align: left;">9</td> <td style="text-align: left;">9</td>
<td style="text-align: left;">Alphanumeric (1 of 6 patterns)</td> <td style="text-align: left;">Alphanumeric (1 of 13 patterns)</td>
</tr> </tr>
<tr> <tr>
<td style="text-align: left;">Service Type</td> <td style="text-align: left;">Service Type</td>
@ -6310,7 +6308,7 @@ data-tag=": Royal Mail 2D Mailmark Input Fields">
<tr> <tr>
<td style="text-align: left;">RTS Post Code</td> <td style="text-align: left;">RTS Post Code</td>
<td style="text-align: left;">7</td> <td style="text-align: left;">7</td>
<td style="text-align: left;">Alphanumeric (1 of 6 patterns)</td> <td style="text-align: left;">Alphanumeric (1 of 7 patterns)</td>
</tr> </tr>
<tr> <tr>
<td style="text-align: left;">Reserved</td> <td style="text-align: left;">Reserved</td>
@ -6325,12 +6323,43 @@ data-tag=": Royal Mail 2D Mailmark Input Fields">
</tbody> </tbody>
</table> </table>
</div> </div>
<p>The 6 Destination+DPS (Destination Post Code plus Delivery Point <p>The 13 Destination+DPS (Destination Post Code plus Delivery Point
Suffix) patterns are the same as for the 4-state - see Table <a Suffix) patterns are similar to those for the 4-state except that the
href="#tbl:mailmark_destination_dps">: Royal Mail Mailmark alphabetic limitation (<code>'L'</code> versus <code>'A'</code>) does
Destination+DPS Patterns</a>. The 6 RTS (Return to Sender) Post Code not apply, only the initial “outward” part is required (the rest can be
patterns are the same also except without the additional DPS blank), and the whole field can be blank:</p>
<code>'NL'</code>, i.e.</p> <div id="tbl:mailmark_2d_destination_dps" class="tablenos">
<table id="tbl:mailmark_2d_destination_dps"
data-tag=": Royal Mail 2D Mailmark Destination+DPS Patterns">
<caption><span>Table : Royal Mail 2D Mailmark Destination+DPS
Patterns:</span> </caption>
<tbody>
<tr>
<td><code>ANNAANASS</code></td>
<td><code>AANNAANAS</code></td>
<td><code>ANNNAANAS</code></td>
<td><code>AANNNAANA</code></td>
<td><code>ANANAANAS</code></td>
<td><code>AANANAANA</code></td>
<td><code>SSSSSSSSS</code></td>
</tr>
<tr>
<td><code>ANSSSSSSS</code></td>
<td><code>AANSSSSSS</code></td>
<td><code>ANNSSSSSS</code></td>
<td><code>AANNSSSSS</code></td>
<td><code>ANASSSSSS</code></td>
<td><code>AANASSSSS</code></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<p>where <code>'A'</code> is alphabetic (A-Z), <code>'N'</code> numeric
(0-9), and <code>'S'</code> space.</p>
<p>The 7 RTS (Return to Sender) Post Code patterns are similar to above
except without the DPS (<code>'NA'</code>), and the trailing “inward”
part cannot be blank (although the whole field can be):</p>
<div id="tbl:mailmark_2d_rts" class="tablenos"> <div id="tbl:mailmark_2d_rts" class="tablenos">
<table id="tbl:mailmark_2d_rts" <table id="tbl:mailmark_2d_rts"
data-tag=": Royal Mail 2D Mailmark RTS Patterns"> data-tag=": Royal Mail 2D Mailmark RTS Patterns">
@ -6338,21 +6367,17 @@ data-tag=": Royal Mail 2D Mailmark RTS Patterns">
</caption> </caption>
<tbody> <tbody>
<tr> <tr>
<td><code>FNFNLLS</code></td> <td><code>ANNAASS</code></td>
<td><code>FFNNLLS</code></td> <td><code>AANNAAS</code></td>
<td><code>FFNNNLL</code></td> <td><code>ANNNAAS</code></td>
</tr> <td><code>AANNNAA</code></td>
<tr> <td><code>ANANAAS</code></td>
<td><code>FFNFNLL</code></td> <td><code>AANANAA</code></td>
<td><code>FNNLLSS</code></td> <td><code>SSSSSSS</code></td>
<td><code>FNNNLLS</code></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
<p>where <code>'F'</code> is full alphabetic (A-Z), <code>'L'</code>
limited alphabetic (A-Z less <code>'CIKMOV'</code>), <code>'N'</code>
numeric (0-9), and <code>'S'</code> space.</p>
<p>Three sizes are defined, one rectangular, with varying maximum <p>Three sizes are defined, one rectangular, with varying maximum
amounts of optional customer data:</p> amounts of optional customer data:</p>
<div id="tbl:mailmark_2d_sizes" class="tablenos"> <div id="tbl:mailmark_2d_sizes" class="tablenos">

View file

@ -3974,15 +3974,14 @@ tag=": Royal Mail 4-State Mailmark Input Fields"}
The 6 Destination+DPS (Destination Post Code plus Delivery Point Suffix) The 6 Destination+DPS (Destination Post Code plus Delivery Point Suffix)
patterns are: patterns are:
----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
`FNFNLLNLS` `FFNNLLNLS` `FFNNNLLNL` `ANNLLNLSS` `AANNLLNLS` `ANNNLLNLS` `AANNNLLNL` `ANANLLNLS` `AANANLLNL`
`FFNFNLLNL` `FNNLLNLSS` `FNNNLLNLS` ----------- ----------- ----------- ----------- ----------- -----------
----------- ----------- -----------
Table: {#tbl:mailmark_destination_dps Table: {#tbl:mailmark_4s_destination_dps
tag=": Royal Mail Mailmark Destination+DPS Patterns"} tag=": Royal Mail 4-State Mailmark Destination+DPS Patterns"}
where `'F'` stands for full alphabetic (A-Z), `'L'` for limited alphabetic (A-Z where `'A'` stands for full alphabetic (A-Z), `'L'` for limited alphabetic (A-Z
less `'CIKMOV'`), `'N'` for numeric (0-9), and `'S'` for space. less `'CIKMOV'`), `'N'` for numeric (0-9), and `'S'` for space.
Four of the permitted patterns include a number of trailing space characters - Four of the permitted patterns include a number of trailing space characters -
@ -4142,31 +4141,41 @@ Version ID 1 `"1"`
Class 1 Alphanumeric Class 1 Alphanumeric
Supply Chain ID 7 Numeric Supply Chain ID 7 Numeric
Item ID 8 Numeric Item ID 8 Numeric
Destination+DPS 9 Alphanumeric (1 of 6 patterns) Destination+DPS 9 Alphanumeric (1 of 13 patterns)
Service Type 1 Numeric Service Type 1 Numeric
RTS Post Code 7 Alphanumeric (1 of 6 patterns) RTS Post Code 7 Alphanumeric (1 of 7 patterns)
Reserved 6 Spaces Reserved 6 Spaces
Customer Data 6, 45 or 29 Anything (Latin-1) Customer Data 6, 45 or 29 Anything (Latin-1)
Table: {#tbl:mailmark_2d_input_fields Table: {#tbl:mailmark_2d_input_fields
tag=": Royal Mail 2D Mailmark Input Fields"} tag=": Royal Mail 2D Mailmark Input Fields"}
The 6 Destination+DPS (Destination Post Code plus Delivery Point Suffix) The 13 Destination+DPS (Destination Post Code plus Delivery Point Suffix)
patterns are the same as for the 4-state - see Table patterns are similar to those for the 4-state except that the alphabetic
{@tbl:mailmark_destination_dps}. The 6 RTS (Return to Sender) Post Code patterns limitation (`'L'` versus `'A'`) does not apply, only the initial "outward" part
are the same also except without the additional DPS `'NL'`, i.e. is required (the rest can be blank), and the whole field can be blank:
--------- --------- --------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
`FNFNLLS` `FFNNLLS` `FFNNNLL` `ANNAANASS` `AANNAANAS` `ANNNAANAS` `AANNNAANA` `ANANAANAS` `AANANAANA` `SSSSSSSSS`
`FFNFNLL` `FNNLLSS` `FNNNLLS` `ANSSSSSSS` `AANSSSSSS` `ANNSSSSSS` `AANNSSSSS` `ANASSSSSS` `AANASSSSS`
--------- --------- --------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
Table: {#tbl:mailmark_2d_destination_dps
tag=": Royal Mail 2D Mailmark Destination+DPS Patterns"}
where `'A'` is alphabetic (A-Z), `'N'` numeric (0-9), and `'S'` space.
The 7 RTS (Return to Sender) Post Code patterns are similar to above except
without the DPS (`'NA'`), and the trailing "inward" part cannot be blank
(although the whole field can be):
--------- --------- --------- --------- --------- --------- ---------
`ANNAASS` `AANNAAS` `ANNNAAS` `AANNNAA` `ANANAAS` `AANANAA` `SSSSSSS`
--------- --------- --------- --------- --------- --------- ---------
Table: {#tbl:mailmark_2d_rts Table: {#tbl:mailmark_2d_rts
tag=": Royal Mail 2D Mailmark RTS Patterns"} tag=": Royal Mail 2D Mailmark RTS Patterns"}
where `'F'` is full alphabetic (A-Z), `'L'` limited alphabetic (A-Z less
`'CIKMOV'`), `'N'` numeric (0-9), and `'S'` space.
Three sizes are defined, one rectangular, with varying maximum amounts of Three sizes are defined, one rectangular, with varying maximum amounts of
optional customer data: optional customer data:

View file

@ -3792,15 +3792,14 @@ the following table.
The 6 Destination+DPS (Destination Post Code plus Delivery Point Suffix) The 6 Destination+DPS (Destination Post Code plus Delivery Point Suffix)
patterns are: patterns are:
----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
FNFNLLNLS FFNNLLNLS FFNNNLLNL ANNLLNLSS AANNLLNLS ANNNLLNLS AANNNLLNL ANANLLNLS AANANLLNL
FFNFNLLNL FNNLLNLSS FNNNLLNLS ----------- ----------- ----------- ----------- ----------- -----------
----------- ----------- -----------
Table : Royal Mail Mailmark Destination+DPS Patterns Table : Royal Mail 4-State Mailmark Destination+DPS Patterns
where 'F' stands for full alphabetic (A-Z), 'L' for limited alphabetic (A-Z less where 'A' stands for full alphabetic (A-Z), 'L' for limited alphabetic (A-Z less
'CIKMOV'), 'N' for numeric (0-9), and 'S' for space. 'CIKMOV'), 'N' for numeric (0-9), and 'S' for space.
Four of the permitted patterns include a number of trailing space characters - Four of the permitted patterns include a number of trailing space characters -
@ -3943,37 +3942,49 @@ offers space for customer data following an initial pre-formatted 45 character
section, as summarized below. section, as summarized below.
Field Name Length Values Field Name Length Values
------------------ ------------- -------------------------------- ------------------ ------------- ---------------------------------
UPU Country ID 4 "JGB " UPU Country ID 4 "JGB "
Information Type 1 Alphanumeric Information Type 1 Alphanumeric
Version ID 1 "1" Version ID 1 "1"
Class 1 Alphanumeric Class 1 Alphanumeric
Supply Chain ID 7 Numeric Supply Chain ID 7 Numeric
Item ID 8 Numeric Item ID 8 Numeric
Destination+DPS 9 Alphanumeric (1 of 6 patterns) Destination+DPS 9 Alphanumeric (1 of 13 patterns)
Service Type 1 Numeric Service Type 1 Numeric
RTS Post Code 7 Alphanumeric (1 of 6 patterns) RTS Post Code 7 Alphanumeric (1 of 7 patterns)
Reserved 6 Spaces Reserved 6 Spaces
Customer Data 6, 45 or 29 Anything (Latin-1) Customer Data 6, 45 or 29 Anything (Latin-1)
Table : Royal Mail 2D Mailmark Input Fields Table : Royal Mail 2D Mailmark Input Fields
The 6 Destination+DPS (Destination Post Code plus Delivery Point Suffix) The 13 Destination+DPS (Destination Post Code plus Delivery Point Suffix)
patterns are the same as for the 4-state - see Table patterns are similar to those for the 4-state except that the alphabetic
: Royal Mail Mailmark Destination+DPS Patterns. The 6 RTS (Return to Sender) limitation ('L' versus 'A') does not apply, only the initial “outward” part is
Post Code patterns are the same also except without the additional DPS 'NL', required (the rest can be blank), and the whole field can be blank:
i.e.
--------- --------- --------- ----------- ----------- ----------- ----------- ----------- ----------- ------
FNFNLLS FFNNLLS FFNNNLL -----
FFNFNLL FNNLLSS FNNNLLS ANNAANASS AANNAANAS ANNNAANAS AANNNAANA ANANAANAS AANANAANA SSSSSS
--------- --------- --------- SSS
ANSSSSSSS AANSSSSSS ANNSSSSSS AANNSSSSS ANASSSSSS AANASSSSS
----------- ----------- ----------- ----------- ----------- ----------- ------
-----
Table : Royal Mail 2D Mailmark Destination+DPS Patterns
where 'A' is alphabetic (A-Z), 'N' numeric (0-9), and 'S' space.
The 7 RTS (Return to Sender) Post Code patterns are similar to above except
without the DPS ('NA'), and the trailing “inward” part cannot be blank (although
the whole field can be):
--------- --------- --------- --------- --------- --------- ---------
ANNAASS AANNAAS ANNNAAS AANNNAA ANANAAS AANANAA SSSSSSS
--------- --------- --------- --------- --------- --------- ---------
Table : Royal Mail 2D Mailmark RTS Patterns Table : Royal Mail 2D Mailmark RTS Patterns
where 'F' is full alphabetic (A-Z), 'L' limited alphabetic (A-Z less 'CIKMOV'),
'N' numeric (0-9), and 'S' space.
Three sizes are defined, one rectangular, with varying maximum amounts of Three sizes are defined, one rectangular, with varying maximum amounts of
optional customer data: optional customer data: