[glabels] Some cleanup of built-in barcode code.
- From: Jim Evins <jimevins src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glabels] Some cleanup of built-in barcode code.
- Date: Mon, 27 Dec 2010 20:52:37 +0000 (UTC)
commit 677ce8eedc473d132ca15fef0e92d8d7dcfe1003
Author: Jim Evins <evins snaught com>
Date: Mon Dec 27 15:47:56 2010 -0500
Some cleanup of built-in barcode code.
- Validate data rather than filtering it into something canonical
- Reconcile style and design patterns between all built-in backends
libglbarcode/lgl-barcode-code39.c | 233 ++++++++++++++++++++++--------------
libglbarcode/lgl-barcode-onecode.c | 204 ++++++++++++++++----------------
libglbarcode/lgl-barcode-postnet.c | 91 ++++++++-------
3 files changed, 292 insertions(+), 236 deletions(-)
---
diff --git a/libglbarcode/lgl-barcode-code39.c b/libglbarcode/lgl-barcode-code39.c
index 723d90f..31e7f2a 100644
--- a/libglbarcode/lgl-barcode-code39.c
+++ b/libglbarcode/lgl-barcode-code39.c
@@ -49,62 +49,60 @@
/* Private types. */
/*========================================================*/
-typedef struct {
- gchar c;
- gchar *sym;
-} Code39Symbol;
-
/*===========================================*/
/* Private globals */
/*===========================================*/
-static Code39Symbol symbols[] = {
- /* BsBsBsBsB */
- { '0', "NnNwWnWnN" },
- { '1', "WnNwNnNnW" },
- { '2', "NnWwNnNnW" },
- { '3', "WnWwNnNnN" },
- { '4', "NnNwWnNnW" },
- { '5', "WnNwWnNnN" },
- { '6', "NnWwWnNnN" },
- { '7', "NnNwNnWnW" },
- { '8', "WnNwNnWnN" },
- { '9', "NnWwNnWnN" },
- { 'A', "WnNnNwNnW" },
- { 'B', "NnWnNwNnW" },
- { 'C', "WnWnNwNnN" },
- { 'D', "NnNnWwNnW" },
- { 'E', "WnNnWwNnN" },
- { 'F', "NnWnWwNnN" },
- { 'G', "NnNnNwWnW" },
- { 'H', "WnNnNwWnN" },
- { 'I', "NnWnNwWnN" },
- { 'J', "NnNnWwWnN" },
- { 'K', "WnNnNnNwW" },
- { 'L', "NnWnNnNwW" },
- { 'M', "WnWnNnNwN" },
- { 'N', "NnNnWnNwW" },
- { 'O', "WnNnWnNwN" },
- { 'P', "NnWnWnNwN" },
- { 'Q', "NnNnNnWwW" },
- { 'R', "WnNnNnWwN" },
- { 'S', "NnWnNnWwN" },
- { 'T', "NnNnWnWwN" },
- { 'U', "WwNnNnNnW" },
- { 'V', "NwWnNnNnW" },
- { 'W', "WwWnNnNnN" },
- { 'X', "NwNnWnNnW" },
- { 'Y', "WwNnWnNnN" },
- { 'Z', "NwWnWnNnN" },
- { '-', "NwNnNnWnW" },
- { '.', "WwNnNnWnN" },
- { ' ', "NwWnNnWnN" },
- { '$', "NwNwNwNnN" },
- { '/', "NwNwNnNwN" },
- { '+', "NwNnNwNwN" },
- { '%', "NnNwNwNwN" },
- { 0, NULL }
+/* Code 39 alphabet. Position indicates value. */
+static gchar *alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%";
+
+/* Code 39 symbols. Position must match position in alphabet. */
+static gchar* symbols[43] = {
+ /* BsBsBsBsB */
+ /* 0 */ "NnNwWnWnN",
+ /* 1 */ "WnNwNnNnW",
+ /* 2 */ "NnWwNnNnW",
+ /* 3 */ "WnWwNnNnN",
+ /* 4 */ "NnNwWnNnW",
+ /* 5 */ "WnNwWnNnN",
+ /* 6 */ "NnWwWnNnN",
+ /* 7 */ "NnNwNnWnW",
+ /* 8 */ "WnNwNnWnN",
+ /* 9 */ "NnWwNnWnN",
+ /* A */ "WnNnNwNnW",
+ /* B */ "NnWnNwNnW",
+ /* C */ "WnWnNwNnN",
+ /* D */ "NnNnWwNnW",
+ /* E */ "WnNnWwNnN",
+ /* F */ "NnWnWwNnN",
+ /* G */ "NnNnNwWnW",
+ /* H */ "WnNnNwWnN",
+ /* I */ "NnWnNwWnN",
+ /* J */ "NnNnWwWnN",
+ /* K */ "WnNnNnNwW",
+ /* L */ "NnWnNnNwW",
+ /* M */ "WnWnNnNwN",
+ /* N */ "NnNnWnNwW",
+ /* O */ "WnNnWnNwN",
+ /* P */ "NnWnWnNwN",
+ /* Q */ "NnNnNnWwW",
+ /* R */ "WnNnNnWwN",
+ /* S */ "NnWnNnWwN",
+ /* T */ "NnNnWnWwN",
+ /* U */ "WwNnNnNnW",
+ /* V */ "NwWnNnNnW",
+ /* W */ "WwWnNnNnN",
+ /* X */ "NwNnWnNnW",
+ /* Y */ "WwNnWnNnN",
+ /* Z */ "NwWnWnNnN",
+ /* - */ "NwNnNnWnW",
+ /* . */ "WwNnNnWnN",
+ /* */ "NwWnNnWnN",
+ /* $ */ "NwNwNwNnN",
+ /* / */ "NwNwNnNwN",
+ /* + */ "NwNnNwNwN",
+ /* % */ "NnNwNwNwN",
};
static gchar *frame_symbol = "NwNnWnWnN";
@@ -150,20 +148,23 @@ static gchar *ascii_map[128] =
/* Local function prototypes */
/*===========================================*/
-static gchar *code39_encode (const gchar *data,
- gboolean checksum_flag);
+static gboolean code39_is_data_valid (const gchar *data);
+static gboolean code39_ext_is_data_valid (const gchar *data);
-static lglBarcode *code39_vectorize (const gchar *code,
- gdouble w,
- gdouble h,
- gboolean text_flag,
- gboolean checksum_flag,
- const gchar *data,
- const gchar *string);
+static gchar *code39_encode (const gchar *data,
+ gboolean checksum_flag);
+
+static lglBarcode *code39_vectorize (const gchar *code,
+ gdouble w,
+ gdouble h,
+ gboolean text_flag,
+ gboolean checksum_flag,
+ const gchar *data,
+ const gchar *string);
/****************************************************************************/
-/* Generate list of lines that form the barcode for the given digits. */
+/* Generate new Code 39 barcode structure from data. */
/****************************************************************************/
lglBarcode *
lgl_barcode_code39_new (lglBarcodeType type,
@@ -186,37 +187,39 @@ lgl_barcode_code39_new (lglBarcodeType type,
}
- /* Canonicalize data. */
- if ( data[0] == '\0' )
+ /* Validate data. */
+ if (type == LGL_BARCODE_TYPE_CODE39)
{
- return NULL;
+ if ( !code39_is_data_valid (data) )
+ {
+ return NULL;
+ }
+ canon_data = g_ascii_strup (data, -1);
+ display_data = g_strdup (canon_data);
}
- if (type == LGL_BARCODE_TYPE_CODE39_EXT)
+ else
{
GString *canon_data_str;
- GString *display_data_str;
+
+ if ( !code39_ext_is_data_valid (data) )
+ {
+ return NULL;
+ }
canon_data_str = g_string_new ("");
- display_data_str = g_string_new ("");
for ( p = (gchar *)data; *p != '\0'; p++ )
{
- canon_data_str = g_string_append (canon_data_str, ascii_map[(*p) & 0x7F]);
- display_data_str = g_string_append_c (display_data_str, (*p) & 0x7F);
+ canon_data_str = g_string_append (canon_data_str, ascii_map[(int)*p]);
}
-
canon_data = g_string_free (canon_data_str, FALSE);
- display_data = g_string_free (display_data_str, FALSE);
- }
- else
- {
- canon_data = g_ascii_strup (data, -1);
- g_strcanon (canon_data, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%", ' ');
- display_data = g_strdup (canon_data);
+
+ display_data = g_strdup (data);
}
/* First get code string */
code = code39_encode (canon_data, checksum_flag);
- if (code == NULL) {
+ if (code == NULL)
+ {
g_free (canon_data);
g_free (display_data);
return NULL;
@@ -234,6 +237,59 @@ lgl_barcode_code39_new (lglBarcodeType type,
/*--------------------------------------------------------------------------*/
+/* PRIVATE. Validate data for Code 39. */
+/*--------------------------------------------------------------------------*/
+static gboolean
+code39_is_data_valid (const gchar *data)
+{
+ gchar *p;
+ gchar c;
+
+ if (!data || (*data == '\0'))
+ {
+ return FALSE;
+ }
+
+ for ( p = (gchar *)data; *p != 0; p++ )
+ {
+ c = g_ascii_toupper (*p);
+
+ if ( strchr(alphabet, c) == NULL )
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE. Validate data for Extended Code 39. */
+/*--------------------------------------------------------------------------*/
+static gboolean
+code39_ext_is_data_valid (const gchar *data)
+{
+ gchar *p;
+
+ if (!data || (*data == '\0'))
+ {
+ return FALSE;
+ }
+
+ for ( p = (gchar *)data; *p != 0; p++ )
+ {
+ if ( (*p < 0) || (*p > 0x7f) )
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*--------------------------------------------------------------------------*/
/* PRIVATE. Generate string of symbols, representing barcode. */
/*--------------------------------------------------------------------------*/
static gchar *
@@ -241,7 +297,7 @@ code39_encode (const gchar *data,
gboolean checksum_flag)
{
gchar *p, c;
- gint i, sum;
+ gint c_value, sum;
GString *code;
@@ -252,22 +308,17 @@ code39_encode (const gchar *data,
sum = 0;
for ( p=(gchar *)data; *p != 0; p++ )
{
- c = toupper( *p );
- for ( i = 0; symbols[i].c != 0; i++ )
- {
- if ( c == symbols[i].c )
- {
- sum += i;
- code = g_string_append (code, symbols[i].sym);
- break;
- }
- }
+ c = g_ascii_toupper( *p );
+ c_value = strchr(alphabet, c) - alphabet;
+ code = g_string_append (code, symbols[c_value]);
code = g_string_append (code, "i");
+
+ sum += c_value;
}
if ( checksum_flag )
{
- code = g_string_append (code, symbols[sum % 43].sym);
+ code = g_string_append (code, symbols[sum % 43]);
code = g_string_append (code, "i");
}
@@ -279,7 +330,7 @@ code39_encode (const gchar *data,
/*--------------------------------------------------------------------------*/
-/* Generate list of rectangles that form the barcode for the given digits. */
+/* PRIVATE. Vectorize encoded barcode. */
/*--------------------------------------------------------------------------*/
static lglBarcode *
code39_vectorize (const gchar *code,
diff --git a/libglbarcode/lgl-barcode-onecode.c b/libglbarcode/lgl-barcode-onecode.c
index 8f4308a..ab744f6 100644
--- a/libglbarcode/lgl-barcode-onecode.c
+++ b/libglbarcode/lgl-barcode-onecode.c
@@ -293,34 +293,32 @@ static guint character_table[] = {
};
-
-
/*===========================================*/
/* Local function prototypes */
/*===========================================*/
-static gboolean is_string_valid (const gchar *data);
-
-static gchar *onecode_encode (const gchar *data);
-
-static void int104_mult_uint (Int104 *x,
- guint y);
-static void int104_add_uint (Int104 *x,
- guint y);
-static void int104_add_uint64 (Int104 *x,
- guint64 y);
-static guint int104_div_uint (Int104 *x,
- guint y);
+static gboolean onecode_is_data_valid (const gchar *data);
+
+static gchar *onecode_encode (const gchar *data);
+
+static lglBarcode *onecode_vectorize (const gchar *code);
+
+static void int104_mult_uint (Int104 *x,
+ guint y);
+static void int104_add_uint (Int104 *x,
+ guint y);
+static void int104_add_uint64 (Int104 *x,
+ guint64 y);
+static guint int104_div_uint (Int104 *x,
+ guint y);
#ifdef DEBUG
-static void int104_print (Int104 *x);
+static void int104_print (Int104 *x);
#endif
static unsigned short USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr );
-static lglBarcode *onecode_vectorize (const gchar *code);
-
/****************************************************************************/
-/* Generate list of lines that form the barcode for the given digits. */
+/* Generate new One Code barcode structure from data. */
/****************************************************************************/
lglBarcode *
lgl_barcode_onecode_new (lglBarcodeType type,
@@ -339,7 +337,14 @@ lgl_barcode_onecode_new (lglBarcodeType type,
return NULL;
}
- /* First get code string */
+
+ /* Validate data */
+ if ( !onecode_is_data_valid (data) )
+ {
+ return NULL;
+ }
+
+ /* Now get code string */
code = onecode_encode (data);
if (code == NULL) {
return NULL;
@@ -355,6 +360,46 @@ lgl_barcode_onecode_new (lglBarcodeType type,
/*--------------------------------------------------------------------------*/
+/* Validate if string is of proper length & contains only valid characters. */
+/*--------------------------------------------------------------------------*/
+static gboolean
+onecode_is_data_valid (const gchar *data)
+{
+ gchar *p;
+ gint str_length;
+
+ if (!data)
+ {
+ return FALSE;
+ }
+
+ str_length = strlen (data);
+ if ( (str_length != 20) &&
+ (str_length != 25) &&
+ (str_length != 29) &&
+ (str_length != 31) )
+ {
+ return FALSE;
+ }
+
+ for ( p = (gchar *)data; *p != 0; p++ )
+ {
+ if (!g_ascii_isdigit (*p))
+ {
+ return FALSE;
+ }
+ }
+
+ if (data[1] > '4')
+ {
+ return FALSE; /* Invalid Barcode Identifier. */
+ }
+
+ return TRUE;
+}
+
+
+/*--------------------------------------------------------------------------*/
/* PRIVATE. Generate string of symbols, representing barcode. */
/*--------------------------------------------------------------------------*/
static gchar *
@@ -368,12 +413,6 @@ onecode_encode (const gchar *data)
gint d, a;
GString *code;
- if ( !is_string_valid (data) )
- {
- return NULL;
- }
-
-
/*-----------------------------------------------------------*/
/* Step 1 -- Conversion of Data Fields into Binary Data */
/*-----------------------------------------------------------*/
@@ -479,41 +518,54 @@ onecode_encode (const gchar *data)
/*--------------------------------------------------------------------------*/
-/* Validate if string is of proper length & contains only valid characters. */
+/* Vectorize encoded data. */
/*--------------------------------------------------------------------------*/
-static gboolean
-is_string_valid (const gchar *data)
+static lglBarcode *
+onecode_vectorize (const gchar *code)
{
- gchar *p;
- gint str_length;
-
- if (!data) {
- return FALSE;
- }
+ lglBarcode *bc;
+ gchar *p;
+ gdouble x, y, length, width;
- str_length = strlen (data);
- if ( (str_length != 20) &&
- (str_length != 25) &&
- (str_length != 29) &&
- (str_length != 31) )
- {
- return FALSE;
- }
+ bc = lgl_barcode_new ();
- for ( p = (gchar *)data; *p != 0; p++ )
+ /* Now traverse the code string and create a list of lines */
+ x = ONECODE_HORIZ_MARGIN;
+ for (p = (gchar *)code; *p != 0; p++)
{
- if (!g_ascii_isdigit (*p))
+ y = ONECODE_VERT_MARGIN;
+ switch ( *p )
{
- return FALSE;
+ case 'T':
+ y += ONECODE_TRACKER_OFFSET;
+ length = ONECODE_TRACKER_HEIGHT;
+ break;
+ case 'D':
+ y += ONECODE_DESCENDER_OFFSET;
+ length = ONECODE_DESCENDER_HEIGHT;
+ break;
+ case 'A':
+ y += ONECODE_ASCENDER_OFFSET;
+ length = ONECODE_ASCENDER_HEIGHT;
+ break;
+ case 'F':
+ y += ONECODE_FULL_OFFSET;
+ length = ONECODE_FULL_HEIGHT;
+ break;
+ default:
+ break;
}
- }
+ width = ONECODE_BAR_WIDTH;
- if (data[1] > '4')
- {
- return FALSE; /* Invalid Barcode Identifier. */
+ lgl_barcode_add_box (bc, x, y, width, length);
+
+ x += ONECODE_BAR_PITCH;
}
- return TRUE;
+ bc->width = x + ONECODE_HORIZ_MARGIN;
+ bc->height = ONECODE_FULL_HEIGHT + 2 * ONECODE_VERT_MARGIN;
+
+ return bc;
}
@@ -683,58 +735,6 @@ USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr )
}
-/*--------------------------------------------------------------------------*/
-/* Vectorize encoded data. */
-/*--------------------------------------------------------------------------*/
-static lglBarcode *
-onecode_vectorize (const gchar *code)
-{
- lglBarcode *bc;
- gchar *p;
- gdouble x, y, length, width;
-
- bc = lgl_barcode_new ();
-
- /* Now traverse the code string and create a list of lines */
- x = ONECODE_HORIZ_MARGIN;
- for (p = (gchar *)code; *p != 0; p++)
- {
- y = ONECODE_VERT_MARGIN;
- switch ( *p )
- {
- case 'T':
- y += ONECODE_TRACKER_OFFSET;
- length = ONECODE_TRACKER_HEIGHT;
- break;
- case 'D':
- y += ONECODE_DESCENDER_OFFSET;
- length = ONECODE_DESCENDER_HEIGHT;
- break;
- case 'A':
- y += ONECODE_ASCENDER_OFFSET;
- length = ONECODE_ASCENDER_HEIGHT;
- break;
- case 'F':
- y += ONECODE_FULL_OFFSET;
- length = ONECODE_FULL_HEIGHT;
- break;
- default:
- break;
- }
- width = ONECODE_BAR_WIDTH;
-
- lgl_barcode_add_box (bc, x, y, width, length);
-
- x += ONECODE_BAR_PITCH;
- }
-
- bc->width = x + ONECODE_HORIZ_MARGIN;
- bc->height = ONECODE_FULL_HEIGHT + 2 * ONECODE_VERT_MARGIN;
-
- return bc;
-}
-
-
/*
diff --git a/libglbarcode/lgl-barcode-postnet.c b/libglbarcode/lgl-barcode-postnet.c
index 6de6900..6308483 100644
--- a/libglbarcode/lgl-barcode-postnet.c
+++ b/libglbarcode/lgl-barcode-postnet.c
@@ -67,17 +67,16 @@ static gchar *frame_symbol = "1";
/*===========================================*/
/* Local function prototypes */
/*===========================================*/
-static gchar *postnet_encode (const gchar *digits);
+static gint postnet_validate_data (const gchar *data);
-static gboolean is_length_valid (const gchar *digits,
- gint n);
+static gchar *postnet_encode (const gchar *digits);
-static lglBarcode *postnet_vectorize (const gchar *code);
+static lglBarcode *postnet_vectorize (const gchar *code);
/****************************************************************************/
-/* Generate list of lines that form the barcode for the given digits. */
+/* Generate new Postnet barcode structure from data. */
/****************************************************************************/
lglBarcode *
lgl_barcode_postnet_new (lglBarcodeType type,
@@ -87,45 +86,47 @@ lgl_barcode_postnet_new (lglBarcodeType type,
gdouble h,
const gchar *data)
{
+ gint n_digits;
gchar *code;
lglBarcode *bc;
- /* Validate code length for all subtypes. */
+ /* Validate data and length for all subtypes. */
+ n_digits = postnet_validate_data (data);
switch (type)
{
case LGL_BARCODE_TYPE_POSTNET:
- if (!is_length_valid (data, 5) &&
- !is_length_valid (data, 9) &&
- !is_length_valid (data, 11))
+ if ( (n_digits != 5) &&
+ (n_digits != 9) &&
+ (n_digits != 11) )
{
return NULL;
}
break;
case LGL_BARCODE_TYPE_POSTNET_5:
- if (!is_length_valid (data, 5))
+ if ( n_digits != 5 )
{
return NULL;
}
break;
case LGL_BARCODE_TYPE_POSTNET_9:
- if (!is_length_valid (data, 9))
+ if ( n_digits != 9 )
{
return NULL;
}
break;
case LGL_BARCODE_TYPE_POSTNET_11:
- if (!is_length_valid (data, 11))
+ if ( n_digits != 11 )
{
return NULL;
}
break;
case LGL_BARCODE_TYPE_CEPNET:
- if (!is_length_valid (data, 8))
+ if ( n_digits != 8 )
{
return NULL;
}
@@ -154,6 +155,37 @@ lgl_barcode_postnet_new (lglBarcodeType type,
/*--------------------------------------------------------------------------*/
+/* PRIVATE. Validate data, returning number of digits if valid. */
+/*--------------------------------------------------------------------------*/
+static gint
+postnet_validate_data (const gchar *data)
+{
+ gchar *p;
+ gint i;
+
+ if (!data)
+ {
+ return 0;
+ }
+
+ for ( p = (gchar *)data, i=0; *p != 0; p++ )
+ {
+ if (g_ascii_isdigit (*p))
+ {
+ i++;
+ }
+ else if ( (*p != '-') && (*p != ' ') )
+ {
+ /* Only allow digits, dashes, and spaces. */
+ return 0;
+ }
+ }
+
+ return i;
+}
+
+
+/*--------------------------------------------------------------------------*/
/* PRIVATE. Generate string of symbols, representing barcode. */
/*--------------------------------------------------------------------------*/
static gchar *
@@ -168,11 +200,11 @@ postnet_encode (const gchar *data)
code = g_string_new (frame_symbol);
sum = 0;
- for (p = (gchar *)data, len = 0; (*p != 0) && (len < 11); p++)
+ for ( p = (gchar *)data, len = 0; (*p != 0) && (len < 11); p++ )
{
if (g_ascii_isdigit (*p))
{
- /* Only translate valid characters (0-9) */
+ /* Only translate the digits (0-9) */
d = (*p) - '0';
sum += d;
code = g_string_append (code, symbols[d]);
@@ -192,33 +224,6 @@ postnet_encode (const gchar *data)
/*--------------------------------------------------------------------------*/
-/* PRIVATE. Validate specific length of string (for subtypes). */
-/*--------------------------------------------------------------------------*/
-static gboolean
-is_length_valid (const gchar *data,
- gint n)
-{
- gchar *p;
- gint i;
-
- if (!data)
- {
- return FALSE;
- }
-
- for (p = (gchar *)data, i=0; *p != 0; p++)
- {
- if (g_ascii_isdigit (*p))
- {
- i++;
- }
- }
-
- return (i == n);
-}
-
-
-/*--------------------------------------------------------------------------*/
/* PRIVATE. Vectorize encoded barcode. */
/*--------------------------------------------------------------------------*/
static lglBarcode *
@@ -232,7 +237,7 @@ postnet_vectorize (const gchar *code)
/* Now traverse the code string and create a list of lines */
x = POSTNET_HORIZ_MARGIN;
- for (p = (gchar *)code; *p != 0; p++)
+ for ( p = (gchar *)code; *p != 0; p++ )
{
y = POSTNET_VERT_MARGIN;
switch (*p)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]