001 /** 002 * This library is free software; you can redistribute it and/or modify it 003 * under the terms of the GNU Lesser General Public License (LGPL) as 004 * published by the Free Software Foundation; either version 3.0 of the 005 * License, or (at your option) any later version. 006 * 007 * This library is distributed in the hope that it will be useful, but 008 * WITHOUT ANY WARRANTY; without even the implied warranty of 009 * MERCHANTABILITY of FITNESS FOR A PARTICULAR PURPOSE. See the GNU 010 * Lesser General Public License for more details. 011 */ 012 013 /** 014 * Title: JBarcodeBean 015 * Description: Barcode JavaBeans Component 016 * Copyright: Copyright (C) 2004 017 * Company: Dafydd Walters 018 */ 019 package net.sourceforge.jbarcodebean.model; 020 021 import net.sourceforge.jbarcodebean.BarcodeException; 022 023 /** 024 * Base class for Code39 variants. 025 */ 026 public abstract class BaseCode39 extends AbstractBarcodeStrategy { 027 028 /** 029 * A static array of 030 * {@link AbstractBarcodeStrategy.CharacterCode CharacterCode} objects 031 * for the 3:1 (wide) variants of Code 39. The 032 * {@link AbstractBarcodeStrategy#getCodes() getCodes()} method of the wide 033 * Code 39 subclasses ({@link Code39} and {@link ExtendedCode39}) 034 * return this array. 035 */ 036 protected static CharacterCode[] codes = { 037 new CharacterCode('0', new byte[] {1,1,1,3,3,1,3,1,1,1}, 0), 038 new CharacterCode('1', new byte[] {3,1,1,3,1,1,1,1,3,1}, 1), 039 new CharacterCode('2', new byte[] {1,1,3,3,1,1,1,1,3,1}, 2), 040 new CharacterCode('3', new byte[] {3,1,3,3,1,1,1,1,1,1}, 3), 041 new CharacterCode('4', new byte[] {1,1,1,3,3,1,1,1,3,1}, 4), 042 new CharacterCode('5', new byte[] {3,1,1,3,3,1,1,1,1,1}, 5), 043 new CharacterCode('6', new byte[] {1,1,3,3,3,1,1,1,1,1}, 6), 044 new CharacterCode('7', new byte[] {1,1,1,3,1,1,3,1,3,1}, 7), 045 new CharacterCode('8', new byte[] {3,1,1,3,1,1,3,1,1,1}, 8), 046 new CharacterCode('9', new byte[] {1,1,3,3,1,1,3,1,1,1}, 9), 047 new CharacterCode('A', new byte[] {3,1,1,1,1,3,1,1,3,1}, 10), 048 new CharacterCode('B', new byte[] {1,1,3,1,1,3,1,1,3,1}, 11), 049 new CharacterCode('C', new byte[] {3,1,3,1,1,3,1,1,1,1}, 12), 050 new CharacterCode('D', new byte[] {1,1,1,1,3,3,1,1,3,1}, 13), 051 new CharacterCode('E', new byte[] {3,1,1,1,3,3,1,1,1,1}, 14), 052 new CharacterCode('F', new byte[] {1,1,3,1,3,3,1,1,1,1}, 15), 053 new CharacterCode('G', new byte[] {1,1,1,1,1,3,3,1,3,1}, 16), 054 new CharacterCode('H', new byte[] {3,1,1,1,1,3,3,1,1,1}, 17), 055 new CharacterCode('I', new byte[] {1,1,3,1,1,3,3,1,1,1}, 18), 056 new CharacterCode('J', new byte[] {1,1,1,1,3,3,3,1,1,1}, 19), 057 new CharacterCode('K', new byte[] {3,1,1,1,1,1,1,3,3,1}, 20), 058 new CharacterCode('L', new byte[] {1,1,3,1,1,1,1,3,3,1}, 21), 059 new CharacterCode('M', new byte[] {3,1,3,1,1,1,1,3,1,1}, 22), 060 new CharacterCode('N', new byte[] {1,1,1,1,3,1,1,3,3,1}, 23), 061 new CharacterCode('O', new byte[] {3,1,1,1,3,1,1,3,1,1}, 24), 062 new CharacterCode('P', new byte[] {1,1,3,1,3,1,1,3,1,1}, 25), 063 new CharacterCode('Q', new byte[] {1,1,1,1,1,1,3,3,3,1}, 26), 064 new CharacterCode('R', new byte[] {3,1,1,1,1,1,3,3,1,1}, 27), 065 new CharacterCode('S', new byte[] {1,1,3,1,1,1,3,3,1,1}, 28), 066 new CharacterCode('T', new byte[] {1,1,1,1,3,1,3,3,1,1}, 29), 067 new CharacterCode('U', new byte[] {3,3,1,1,1,1,1,1,3,1}, 30), 068 new CharacterCode('V', new byte[] {1,3,3,1,1,1,1,1,3,1}, 31), 069 new CharacterCode('W', new byte[] {3,3,3,1,1,1,1,1,1,1}, 32), 070 new CharacterCode('X', new byte[] {1,3,1,1,3,1,1,1,3,1}, 33), 071 new CharacterCode('Y', new byte[] {3,3,1,1,3,1,1,1,1,1}, 34), 072 new CharacterCode('Z', new byte[] {1,3,3,1,3,1,1,1,1,1}, 35), 073 new CharacterCode('-', new byte[] {1,3,1,1,1,1,3,1,3,1}, 36), 074 new CharacterCode('.', new byte[] {3,3,1,1,1,1,3,1,1,1}, 37), 075 new CharacterCode(' ', new byte[] {1,3,3,1,1,1,3,1,1,1}, 38), 076 new CharacterCode('*', new byte[] {1,3,1,1,3,1,3,1,1,1}, -1), // Start and End Sentinel 077 new CharacterCode('$', new byte[] {1,3,1,3,1,3,1,1,1,1}, 39), 078 new CharacterCode('/', new byte[] {1,3,1,3,1,1,1,3,1,1}, 40), 079 new CharacterCode('+', new byte[] {1,3,1,1,1,3,1,3,1,1}, 41), 080 new CharacterCode('%', new byte[] {1,1,1,3,1,3,1,3,1,1}, 42) 081 }; 082 083 /** 084 * A static array of 085 * {@link AbstractBarcodeStrategy.CharacterCode CharacterCode} objects 086 * for the 2:1 (narrow) variants of Code 39. The 087 * {@link AbstractBarcodeStrategy#getCodes() getCodes()} method of the narrow 088 * Code 39 subclasses ({@link Code39_2to1} and {@link ExtendedCode39_2to1}) 089 * return this array. 090 */ 091 protected static CharacterCode[] codes2to1 = { 092 new CharacterCode('0', new byte[] {1,1,1,2,2,1,2,1,1,1}, 0), 093 new CharacterCode('1', new byte[] {2,1,1,2,1,1,1,1,2,1}, 1), 094 new CharacterCode('2', new byte[] {1,1,2,2,1,1,1,1,2,1}, 2), 095 new CharacterCode('3', new byte[] {2,1,2,2,1,1,1,1,1,1}, 3), 096 new CharacterCode('4', new byte[] {1,1,1,2,2,1,1,1,2,1}, 4), 097 new CharacterCode('5', new byte[] {2,1,1,2,2,1,1,1,1,1}, 5), 098 new CharacterCode('6', new byte[] {1,1,2,2,2,1,1,1,1,1}, 6), 099 new CharacterCode('7', new byte[] {1,1,1,2,1,1,2,1,2,1}, 7), 100 new CharacterCode('8', new byte[] {2,1,1,2,1,1,2,1,1,1}, 8), 101 new CharacterCode('9', new byte[] {1,1,2,2,1,1,2,1,1,1}, 9), 102 new CharacterCode('A', new byte[] {2,1,1,1,1,2,1,1,2,1}, 10), 103 new CharacterCode('B', new byte[] {1,1,2,1,1,2,1,1,2,1}, 11), 104 new CharacterCode('C', new byte[] {2,1,2,1,1,2,1,1,1,1}, 12), 105 new CharacterCode('D', new byte[] {1,1,1,1,2,2,1,1,2,1}, 13), 106 new CharacterCode('E', new byte[] {2,1,1,1,2,2,1,1,1,1}, 14), 107 new CharacterCode('F', new byte[] {1,1,2,1,2,2,1,1,1,1}, 15), 108 new CharacterCode('G', new byte[] {1,1,1,1,1,2,2,1,2,1}, 16), 109 new CharacterCode('H', new byte[] {2,1,1,1,1,2,2,1,1,1}, 17), 110 new CharacterCode('I', new byte[] {1,1,2,1,1,2,2,1,1,1}, 18), 111 new CharacterCode('J', new byte[] {1,1,1,1,2,2,2,1,1,1}, 19), 112 new CharacterCode('K', new byte[] {2,1,1,1,1,1,1,2,2,1}, 20), 113 new CharacterCode('L', new byte[] {1,1,2,1,1,1,1,2,2,1}, 21), 114 new CharacterCode('M', new byte[] {2,1,2,1,1,1,1,2,1,1}, 22), 115 new CharacterCode('N', new byte[] {1,1,1,1,2,1,1,2,2,1}, 23), 116 new CharacterCode('O', new byte[] {2,1,1,1,2,1,1,2,1,1}, 24), 117 new CharacterCode('P', new byte[] {1,1,2,1,2,1,1,2,1,1}, 25), 118 new CharacterCode('Q', new byte[] {1,1,1,1,1,1,2,2,2,1}, 26), 119 new CharacterCode('R', new byte[] {2,1,1,1,1,1,2,2,1,1}, 27), 120 new CharacterCode('S', new byte[] {1,1,2,1,1,1,2,2,1,1}, 28), 121 new CharacterCode('T', new byte[] {1,1,1,1,2,1,2,2,1,1}, 29), 122 new CharacterCode('U', new byte[] {2,2,1,1,1,1,1,1,2,1}, 30), 123 new CharacterCode('V', new byte[] {1,2,2,1,1,1,1,1,2,1}, 31), 124 new CharacterCode('W', new byte[] {2,2,2,1,1,1,1,1,1,1}, 32), 125 new CharacterCode('X', new byte[] {1,2,1,1,2,1,1,1,2,1}, 33), 126 new CharacterCode('Y', new byte[] {2,2,1,1,2,1,1,1,1,1}, 34), 127 new CharacterCode('Z', new byte[] {1,2,2,1,2,1,1,1,1,1}, 35), 128 new CharacterCode('-', new byte[] {1,2,1,1,1,1,2,1,2,1}, 36), 129 new CharacterCode('.', new byte[] {2,2,1,1,1,1,2,1,1,1}, 37), 130 new CharacterCode(' ', new byte[] {1,2,2,1,1,1,2,1,1,1}, 38), 131 new CharacterCode('*', new byte[] {1,2,1,1,2,1,2,1,1,1}, -1), // Start and End Sentinel 132 new CharacterCode('$', new byte[] {1,2,1,2,1,2,1,1,1,1}, 39), 133 new CharacterCode('/', new byte[] {1,2,1,2,1,1,1,2,1,1}, 40), 134 new CharacterCode('+', new byte[] {1,2,1,1,1,2,1,2,1,1}, 41), 135 new CharacterCode('%', new byte[] {1,1,1,2,1,2,1,2,1,1}, 42) 136 }; 137 138 /** 139 * Always returns {@link BarcodeStrategy#OPTIONAL_CHECKSUM}. 140 */ 141 public int requiresChecksum() { 142 // Checksum is not mandatory 143 return OPTIONAL_CHECKSUM; 144 } 145 146 /** 147 * Always returns 11 (eleven). 148 */ 149 protected byte getMarginWidth() { 150 return 11; 151 } 152 153 /** 154 * Always returns '*' (asterisk). 155 */ 156 protected char getStartSentinel() { 157 return '*'; 158 } 159 160 /** 161 * Always returns '*' (asterisk). 162 */ 163 protected char getStopSentinel() { 164 return '*'; 165 } 166 167 /** 168 * Always returns <tt>false</tt>. 169 */ 170 protected boolean isInterleaved() { 171 return false; 172 } 173 174 /** 175 * Does nothing except return the String passed to the method. 176 */ 177 protected String postprocess(String text) { 178 return text; 179 } 180 181 /** 182 * Returns a String containing the checksum-encoded version of the text passed 183 * to the method. 184 * Start and End sentinels must NOT be included in the text passed to this method. 185 */ 186 protected String augmentWithChecksum(String text) throws BarcodeException { 187 int checkTotal = 0; 188 CharacterCode cc; 189 for (int i = 0; i < text.length(); i++) { 190 char ch = text.charAt(i); 191 cc = getCharacterCode(ch); // get code by character 192 if (cc == null) { 193 throw new BarcodeException("Invalid character in barcode"); 194 } 195 // Exclude start and end sentinels from checksum 196 if (cc.check > 0) { 197 checkTotal += cc.check; 198 } 199 } 200 cc = getCharacterCode(checkTotal % 43); // get code by check number 201 return text + cc.character; 202 } 203 204 205 }