// code39.cpp //////////////////////////////////////////////////////////////// // // Routines for producing Code 3-of-9 barcodes // // Call Encode39 to convert a character string to a sequence of bytes // whose bits encode the barcode pattern. The bits are logically // arranged within each byte in order of decreasing significance. // // Example // // * = 8BBA (hex) = 1000101110111010 (binary) // A = EA2E (hex) = 1110101000101110 (binary) // B = BA2E (hex) = 1011101000101110 (binary) // // AB = ||| | | | ||| | ||| | | ||| // ||| | | | ||| | ||| | | ||| // AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB // // // typedef unsigned short word; // typedef unsigned char byte; // // // ENTRY POINTS: // // word Code39 (char) // bool Check39 (const char*) // int Encode39(const char*, byte*) // ////////////////////////////////////////////////////////////////////////////// #include #include #include #include "code39.h" typedef unsigned short word; typedef unsigned char byte; //#define hi(w) (byte)((w)>>8) //#define lo(w) (byte)((w)&0xff) inline byte hi(word w) { return static_cast(w >> 8); } inline byte lo(word w) { return static_cast(w & 0xff); } ////////////////////////////////////////////////////////////////////////////// // Code39 ////////////////////////////////////////////////////////////////////////////// // Return the code for a given text character. word Code39(char ch) { word p; #if 0 // Portable switch (ch) { case '1': p = 0xE8AE; break; case '2': p = 0xB8AE; break; case '3': p = 0xEE2A; break; case '4': p = 0xA3AE; break; case '5': p = 0xE8EA; break; case '6': p = 0xB8EA; break; case '7': p = 0xA2EE; break; case '8': p = 0xE8BA; break; case '9': p = 0xB8BA; break; case '0': p = 0xA3BA; break; case 'A': p = 0xEA2E; break; case 'B': p = 0xBA2E; break; case 'C': p = 0xEE8A; break; case 'D': p = 0xAE2E; break; case 'E': p = 0xEB8A; break; case 'F': p = 0xBB8A; break; case 'G': p = 0xA8EE; break; case 'H': p = 0xEA3A; break; case 'I': p = 0xBA3A; break; case 'J': p = 0xAE3A; break; case 'K': p = 0xEA8E; break; case 'L': p = 0xBA8E; break; case 'M': p = 0xEEA2; break; case 'N': p = 0xAE8E; break; case 'O': p = 0xEBA2; break; case 'P': p = 0xBBA2; break; case 'Q': p = 0xAB8E; break; case 'R': p = 0xEAE2; break; case 'S': p = 0xBAE2; break; case 'T': p = 0xAEE2; break; case 'U': p = 0xE2AE; break; case 'V': p = 0x8EAE; break; case 'W': p = 0xE3AA; break; case 'X': p = 0x8BAE; break; case 'Y': p = 0xE2EA; break; case 'Z': p = 0x8EEA; break; case '-': p = 0x8AEE; break; case '.': p = 0xE2BA; break; case ' ': p = 0x8EBA; break; case '$': p = 0x888A; break; case '/': p = 0x88A2; break; case '+': p = 0x8A22; break; case '%': p = 0xA222; break; case '*': p = 0x8BBA; break; default : p = 0; } #else // Not fully portable word Digit[] = { 0xA3BA, 0xE8AE, 0xB8AE, 0xEE2A, 0xA3AE, 0xE8EA, 0xB8EA, 0xA2EE, 0xE8BA, 0xB8BA }; word Letter[] = { 0xEA2E,0xBA2E,0xEE8A,0xAE2E,0xEB8A,0xBB8A,0xA8EE,0xEA3A,0xBA3A, 0xAE3A,0xEA8E,0xBA8E,0xEEA2,0xAE8E,0xEBA2,0xBBA2,0xAB8E,0xEAE2, 0xBAE2,0xAEE2,0xE2AE,0x8EAE,0xE3AA,0x8BAE,0xE2EA,0x8EEA }; if (isdigit(ch)) { p = Digit[ch-'0']; } else if (isupper(ch)) { p = Letter[ch-'A']; } else { switch (ch) { case '-': p = 0x8AEE; break; case '.': p = 0xE2BA; break; case ' ': p = 0x8EBA; break; case '$': p = 0x888A; break; case '/': p = 0x88A2; break; case '+': p = 0x8A22; break; case '%': p = 0xA222; break; case '*': p = 0x8BBA; break; default : p = 0; } // end switch } // end if-else #endif return p; } // end Code39 ////////////////////////////////////////////////////////////////////////////// // Check39 ////////////////////////////////////////////////////////////////////////////// // Tell whether a character string is a valid 3-of-9 string. bool Check39(const char* psz) { char c; if (!*psz) return false; while ((c = *psz++) != 0) if (!isdigit(c) && !isupper(c) && !strchr(" *+-.$%/", c)) return false; return true; } // end Check39 ////////////////////////////////////////////////////////////////////////////// // Encode39 ////////////////////////////////////////////////////////////////////////////// // Convert a string to its corresponding barcode bit pattern. // Return 0 if string is invalid; O.W., return length of output. int Encode39(const char* psz, byte* barcode) { int k; // loop variable word w; // barcode word byte* bc; // pointer to barcode byte // Write a "*" at the beginning of the barcode bc = barcode; w = Code39('*'); *bc++ = hi(w); *bc++ = lo(w); for (k = 0; psz[k]; ++k) { if ((w = Code39(psz[k])) == 0) return 0; *bc++ = hi(w); *bc++ = lo(w); } // end for (k) // Append a "*" to the end *bc++ = barcode[0]; *bc++ = barcode[1]; // Return number of bytes written return bc - barcode; } // end Encode39 ////////////////////////// end of code39.cpp /////////////////////////////////