mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
Move escape character processing into library
And expand to include all 8-bit values.
This commit is contained in:
parent
1fb99fff8c
commit
0314ca65a8
@ -43,7 +43,11 @@ size_t ustrlen(const unsigned char data[]) {
|
|||||||
int ctoi(const char source) {
|
int ctoi(const char source) {
|
||||||
if ((source >= '0') && (source <= '9'))
|
if ((source >= '0') && (source <= '9'))
|
||||||
return (source - '0');
|
return (source - '0');
|
||||||
return (source - 'A' + 10);
|
if ((source >= 'A') && (source <= 'F'))
|
||||||
|
return (source - 'A' + 10);
|
||||||
|
if ((source >= 'a') && (source <= 'f'))
|
||||||
|
return (source - 'a' + 10);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ struct zint_symbol *ZBarcode_Create() {
|
|||||||
symbol->width = 0;
|
symbol->width = 0;
|
||||||
strcpy(symbol->fgcolour, "000000");
|
strcpy(symbol->fgcolour, "000000");
|
||||||
strcpy(symbol->bgcolour, "ffffff");
|
strcpy(symbol->bgcolour, "ffffff");
|
||||||
strcpy(symbol->outfile, "");
|
strcpy(symbol->outfile, "out.png");
|
||||||
symbol->scale = 1.0;
|
symbol->scale = 1.0;
|
||||||
symbol->option_1 = -1;
|
symbol->option_1 = -1;
|
||||||
symbol->option_2 = 0;
|
symbol->option_2 = 0;
|
||||||
@ -792,7 +792,96 @@ void strip_bom(unsigned char *source, int *input_length) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source,int in_length) {
|
int escape_char_process(struct zint_symbol *symbol, unsigned char *input_string, int *length) {
|
||||||
|
int error_number;
|
||||||
|
int in_posn, out_posn;
|
||||||
|
int hex1, hex2;
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
unsigned char escaped_string[*length + 1];
|
||||||
|
#else
|
||||||
|
unsigned char* escaped_string = (unsigned char*) _alloca(length + 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
in_posn = 0;
|
||||||
|
out_posn = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (input_string[in_posn] == '\\') {
|
||||||
|
switch (input_string[in_posn + 1]) {
|
||||||
|
case '0': escaped_string[out_posn] = 0x00; /* Null */
|
||||||
|
in_posn += 2;
|
||||||
|
break;
|
||||||
|
case 'E': escaped_string[out_posn] = 0x04; /* End of Transmission */
|
||||||
|
in_posn += 2;
|
||||||
|
break;
|
||||||
|
case 'a': escaped_string[out_posn] = 0x07; /* Bell */
|
||||||
|
in_posn += 2;
|
||||||
|
break;
|
||||||
|
case 'b': escaped_string[out_posn] = 0x08; /* Backspace */
|
||||||
|
in_posn += 2;
|
||||||
|
break;
|
||||||
|
case 't': escaped_string[out_posn] = 0x09; /* Horizontal tab */
|
||||||
|
in_posn += 2;
|
||||||
|
break;
|
||||||
|
case 'n': escaped_string[out_posn] = 0x0a; /* Line feed */
|
||||||
|
in_posn += 2;
|
||||||
|
break;
|
||||||
|
case 'v': escaped_string[out_posn] = 0x0b; /* Vertical tab */
|
||||||
|
in_posn += 2;
|
||||||
|
break;
|
||||||
|
case 'f': escaped_string[out_posn] = 0x0c; /* Form feed */
|
||||||
|
in_posn += 2;
|
||||||
|
break;
|
||||||
|
case 'r': escaped_string[out_posn] = 0x0d; /* Carriage return */
|
||||||
|
in_posn += 2;
|
||||||
|
break;
|
||||||
|
case 'e': escaped_string[out_posn] = 0x1b; /* Escape */
|
||||||
|
in_posn += 2;
|
||||||
|
break;
|
||||||
|
case 'G': escaped_string[out_posn] = 0x1d; /* Group Separator */
|
||||||
|
in_posn += 2;
|
||||||
|
break;
|
||||||
|
case 'R': escaped_string[out_posn] = 0x1e; /* Record Separator */
|
||||||
|
in_posn += 2;
|
||||||
|
break;
|
||||||
|
case 'x': if (in_posn + 4 > *length) {
|
||||||
|
strcpy(symbol->errtxt, "232: Incomplete escape character in input data");
|
||||||
|
return ZINT_ERROR_INVALID_DATA;
|
||||||
|
}
|
||||||
|
hex1 = ctoi(input_string[in_posn + 2]);
|
||||||
|
hex2 = ctoi(input_string[in_posn + 3]);
|
||||||
|
if ((hex1 >= 0) && (hex2 >= 0)) {
|
||||||
|
escaped_string[out_posn] += (hex1 << 4) + hex2;
|
||||||
|
in_posn += 4;
|
||||||
|
} else {
|
||||||
|
strcpy(symbol->errtxt, "233: Corrupt escape character in input data");
|
||||||
|
return ZINT_ERROR_INVALID_DATA;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\\': escaped_string[out_posn] = '\\';
|
||||||
|
in_posn += 2;
|
||||||
|
break;
|
||||||
|
default: strcpy(symbol->errtxt, "234: Unrecognised escape character in input data");
|
||||||
|
return ZINT_ERROR_INVALID_DATA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
escaped_string[out_posn] = input_string[in_posn];
|
||||||
|
in_posn++;
|
||||||
|
}
|
||||||
|
out_posn++;
|
||||||
|
} while (in_posn < *length);
|
||||||
|
|
||||||
|
memcpy(input_string, escaped_string, out_posn);
|
||||||
|
*length = out_posn;
|
||||||
|
|
||||||
|
error_number = 0;
|
||||||
|
|
||||||
|
return error_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int in_length) {
|
||||||
int error_number, error_buffer, i;
|
int error_number, error_buffer, i;
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
unsigned char* local_source;
|
unsigned char* local_source;
|
||||||
@ -967,14 +1056,7 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source,int
|
|||||||
error_number = ZINT_ERROR_INVALID_OPTION;
|
error_number = ZINT_ERROR_INVALID_OPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((symbol->input_mode < 0) || (symbol->input_mode > 2)) {
|
/* Start acting on input mode */
|
||||||
symbol->input_mode = DATA_MODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((symbol->eci != 3) && (symbol->eci != 26)) {
|
|
||||||
symbol->input_mode = DATA_MODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (symbol->input_mode == GS1_MODE) {
|
if (symbol->input_mode == GS1_MODE) {
|
||||||
for (i = 0; i < in_length; i++) {
|
for (i = 0; i < in_length; i++) {
|
||||||
if (source[i] == '\0') {
|
if (source[i] == '\0') {
|
||||||
@ -997,6 +1079,22 @@ int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source,int
|
|||||||
local_source[in_length] = '\0';
|
local_source[in_length] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (symbol->input_mode &= ESCAPE_MODE) {
|
||||||
|
error_number = escape_char_process(symbol, local_source, &in_length);
|
||||||
|
if (error_number != 0) {
|
||||||
|
return error_number;
|
||||||
|
}
|
||||||
|
symbol->input_mode -= ESCAPE_MODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((symbol->input_mode < 0) || (symbol->input_mode > 2)) {
|
||||||
|
symbol->input_mode = DATA_MODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((symbol->eci != 3) && (symbol->eci != 26)) {
|
||||||
|
symbol->input_mode = DATA_MODE;
|
||||||
|
}
|
||||||
|
|
||||||
if (symbol->input_mode == UNICODE_MODE) {
|
if (symbol->input_mode == UNICODE_MODE) {
|
||||||
strip_bom(local_source, &in_length);
|
strip_bom(local_source, &in_length);
|
||||||
}
|
}
|
||||||
|
@ -220,6 +220,7 @@ extern "C" {
|
|||||||
#define GS1_MODE 2
|
#define GS1_MODE 2
|
||||||
#define KANJI_MODE 3
|
#define KANJI_MODE 3
|
||||||
#define SJIS_MODE 4
|
#define SJIS_MODE 4
|
||||||
|
#define ESCAPE_MODE 8
|
||||||
|
|
||||||
// Data Matrix specific options
|
// Data Matrix specific options
|
||||||
#define DM_SQUARE 100
|
#define DM_SQUARE 100
|
||||||
|
@ -179,12 +179,12 @@ Unicode then you will need to set the appropriate input options as shown in
|
|||||||
section 4.11 below.
|
section 4.11 below.
|
||||||
|
|
||||||
Non-printing characters can be entered on the command line using the backslash
|
Non-printing characters can be entered on the command line using the backslash
|
||||||
(\) as an escape character. Permissible characters are shown in the table
|
(\) as an escape character in combination with the --esc switch. Permissible
|
||||||
below. Note that this only applies on the command line.
|
characters are shown in the table below.
|
||||||
|
|
||||||
-------------------------------------------------------------
|
--------------------------------------------------------------------
|
||||||
Escape Character | ASCII Equivalent | Interpretation
|
Escape Character | ASCII Equivalent | Interpretation
|
||||||
-------------------------------------------------------------
|
--------------------------------------------------------------------
|
||||||
\0 | 0x00 | Null
|
\0 | 0x00 | Null
|
||||||
\E | 0x04 | End of Transmission
|
\E | 0x04 | End of Transmission
|
||||||
\a | 0x07 | Bell
|
\a | 0x07 | Bell
|
||||||
@ -197,7 +197,9 @@ Escape Character | ASCII Equivalent | Interpretation
|
|||||||
\e | 0x1B | Escape
|
\e | 0x1B | Escape
|
||||||
\G | 0x1D | Group Selector
|
\G | 0x1D | Group Selector
|
||||||
\R | 0x1E | Record Selector
|
\R | 0x1E | Record Selector
|
||||||
-------------------------------------------------------------
|
\xNN | 0xNN | Any other 8-bit character
|
||||||
|
| | where NN is hexadecimal
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
|
||||||
Input data can be read directly from file using the -i switch as shown below.
|
Input data can be read directly from file using the -i switch as shown below.
|
||||||
The input file is assumed to be Unicode (UTF-8) formatted unless an alternative
|
The input file is assumed to be Unicode (UTF-8) formatted unless an alternative
|
||||||
@ -1042,8 +1044,21 @@ Value | Effect
|
|||||||
DATA_MODE | Uses full ASCII range interpreted as Latin-1 or binary data.
|
DATA_MODE | Uses full ASCII range interpreted as Latin-1 or binary data.
|
||||||
UNICODE_MODE | Uses pre-formatted UTF-8 input.
|
UNICODE_MODE | Uses pre-formatted UTF-8 input.
|
||||||
GS1_MODE | Encodes GS1 data using FNC1 characters.
|
GS1_MODE | Encodes GS1 data using FNC1 characters.
|
||||||
|
ESCAPE_MODE | Process input data for escape sequences
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
DATA_MODE, UNICODE_MODE and GS1_MODE are mutually exclusive, whereas
|
||||||
|
ESCAPE_MODE is optional. So, for example, you can set
|
||||||
|
|
||||||
|
my_symbol->input_mode = UNICODE_MODE + ESCAPE_MODE;
|
||||||
|
|
||||||
|
whereas
|
||||||
|
|
||||||
|
my_symbol->input_mode = DATA_MODE + GS1_MODE;
|
||||||
|
|
||||||
|
is not valid. Permissable escape sequences are listed in section 4.1.
|
||||||
|
|
||||||
|
|
||||||
5.10 Verifying Symbology Availability
|
5.10 Verifying Symbology Availability
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
An additional function available in the API is defined as:
|
An additional function available in the API is defined as:
|
||||||
|
@ -92,6 +92,7 @@ void usage(void) {
|
|||||||
" --dump Dump hexadecimal representation to stdout\n"
|
" --dump Dump hexadecimal representation to stdout\n"
|
||||||
" -e, --ecinos Display table of ECI character encodings\n"
|
" -e, --ecinos Display table of ECI character encodings\n"
|
||||||
" --eci=NUMBER Set the ECI mode for raw data\n"
|
" --eci=NUMBER Set the ECI mode for raw data\n"
|
||||||
|
" --esc Process escape characters in input data\n"
|
||||||
" --filetype=TYPE Set output file type (PNG/EPS/SVG/PNG/EPS/GIF/TXT)\n"
|
" --filetype=TYPE Set output file type (PNG/EPS/SVG/PNG/EPS/GIF/TXT)\n"
|
||||||
" --fg=COLOUR Specify a foreground colour (in hex)\n"
|
" --fg=COLOUR Specify a foreground colour (in hex)\n"
|
||||||
" --gs1 Treat input as GS1 compatible data\n"
|
" --gs1 Treat input as GS1 compatible data\n"
|
||||||
@ -168,78 +169,6 @@ int validator(char test_string[], char source[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int escape_char_process(struct zint_symbol *my_symbol, unsigned char input_string[], int length) {
|
|
||||||
int error_number;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
|
||||||
unsigned char escaped_string[length + 1];
|
|
||||||
#else
|
|
||||||
unsigned char* escaped_string = (unsigned char*) _alloca(length + 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
j = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (input_string[i] == '\\') {
|
|
||||||
switch (input_string[i + 1]) {
|
|
||||||
case '0': escaped_string[j] = 0x00; /* Null */
|
|
||||||
i += 2;
|
|
||||||
break;
|
|
||||||
case 'E': escaped_string[j] = 0x04; /* End of Transmission */
|
|
||||||
i += 2;
|
|
||||||
break;
|
|
||||||
case 'a': escaped_string[j] = 0x07; /* Bell */
|
|
||||||
i += 2;
|
|
||||||
break;
|
|
||||||
case 'b': escaped_string[j] = 0x08; /* Backspace */
|
|
||||||
i += 2;
|
|
||||||
break;
|
|
||||||
case 't': escaped_string[j] = 0x09; /* Horizontal tab */
|
|
||||||
i += 2;
|
|
||||||
break;
|
|
||||||
case 'n': escaped_string[j] = 0x0a; /* Line feed */
|
|
||||||
i += 2;
|
|
||||||
break;
|
|
||||||
case 'v': escaped_string[j] = 0x0b; /* Vertical tab */
|
|
||||||
i += 2;
|
|
||||||
break;
|
|
||||||
case 'f': escaped_string[j] = 0x0c; /* Form feed */
|
|
||||||
i += 2;
|
|
||||||
break;
|
|
||||||
case 'r': escaped_string[j] = 0x0d; /* Carriage return */
|
|
||||||
i += 2;
|
|
||||||
break;
|
|
||||||
case 'e': escaped_string[j] = 0x1b; /* Escape */
|
|
||||||
i += 2;
|
|
||||||
break;
|
|
||||||
case 'G': escaped_string[j] = 0x1d; /* Group Separator */
|
|
||||||
i += 2;
|
|
||||||
break;
|
|
||||||
case 'R': escaped_string[j] = 0x1e; /* Record Separator */
|
|
||||||
i += 2;
|
|
||||||
break;
|
|
||||||
case '\\': escaped_string[j] = '\\';
|
|
||||||
i += 2;
|
|
||||||
break;
|
|
||||||
default: escaped_string[j] = input_string[i];
|
|
||||||
i++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
escaped_string[j] = input_string[i];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
} while (i < length);
|
|
||||||
escaped_string[j] = '\0';
|
|
||||||
|
|
||||||
error_number = ZBarcode_Encode(my_symbol, escaped_string, j);
|
|
||||||
|
|
||||||
return error_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Converts an integer value to its hexadecimal character */
|
/* Converts an integer value to its hexadecimal character */
|
||||||
static char itoc(int source) {
|
static char itoc(int source) {
|
||||||
if ((source >= 0) && (source <= 9)) {
|
if ((source >= 0) && (source <= 9)) {
|
||||||
@ -500,6 +429,7 @@ int main(int argc, char **argv) {
|
|||||||
{"dotsize", 1, 0, 0},
|
{"dotsize", 1, 0, 0},
|
||||||
{"eci", 1, 0, 0},
|
{"eci", 1, 0, 0},
|
||||||
{"filetype", 1, 0, 0},
|
{"filetype", 1, 0, 0},
|
||||||
|
{"esc", 0, 0, 0},
|
||||||
{"verbose", 0, 0, 0}, // Currently undocumented, output some debug info
|
{"verbose", 0, 0, 0}, // Currently undocumented, output some debug info
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
@ -696,6 +626,11 @@ int main(int argc, char **argv) {
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!strcmp(long_options[option_index].name, "esc")) {
|
||||||
|
if (!(my_symbol->input_mode &= ESCAPE_MODE)) {
|
||||||
|
my_symbol->input_mode += ESCAPE_MODE;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!strcmp(long_options[option_index].name, "verbose")) {
|
if (!strcmp(long_options[option_index].name, "verbose")) {
|
||||||
my_symbol->debug = 1;
|
my_symbol->debug = 1;
|
||||||
}
|
}
|
||||||
@ -742,7 +677,7 @@ int main(int argc, char **argv) {
|
|||||||
strcat(my_symbol->outfile, ".");
|
strcat(my_symbol->outfile, ".");
|
||||||
strcat(my_symbol->outfile, filetype);
|
strcat(my_symbol->outfile, filetype);
|
||||||
}
|
}
|
||||||
error_number = escape_char_process(my_symbol, (unsigned char*) optarg, strlen(optarg));
|
error_number = ZBarcode_Encode(my_symbol, (unsigned char*) optarg, strlen(optarg));
|
||||||
if (error_number < 5) {
|
if (error_number < 5) {
|
||||||
if (error_number != 0) {
|
if (error_number != 0) {
|
||||||
fprintf(stderr, "%s\n", my_symbol->errtxt);
|
fprintf(stderr, "%s\n", my_symbol->errtxt);
|
||||||
|
Loading…
Reference in New Issue
Block a user