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 }