1 58 package org.krysalis.barcode.impl; 59 60 import org.krysalis.barcode.BarGroup; 61 import org.krysalis.barcode.ChecksumMode; 62 import org.krysalis.barcode.ClassicBarcodeLogicHandler; 63 64 69 public abstract class UPCEANLogicImpl { 70 71 72 protected static final byte LEFT_HAND_A = 0; 73 74 protected static final byte LEFT_HAND_B = 1; 75 76 protected static final byte RIGHT_HAND = 2; 77 78 protected static final byte ODD_PARITY = LEFT_HAND_A; 79 80 protected static final byte EVEN_PARITY = LEFT_HAND_B; 81 82 private static final byte[][] CHARSET = {{3, 2, 1, 1}, 83 {2, 2, 2, 1}, 84 {2, 1, 2, 2}, 85 {1, 4, 1, 1}, 86 {1, 1, 3, 2}, 87 {1, 2, 3, 1}, 88 {1, 1, 1, 4}, 89 {1, 3, 1, 2}, 90 {1, 2, 1, 3}, 91 {3, 1, 1, 2}}; 92 93 private static final byte O = ODD_PARITY; 94 private static final byte E = EVEN_PARITY; 95 96 private static final byte[][] SUPP2_PARITY = 97 {{O, O}, {O, E}, {E, O}, {E, E}}; 98 99 private static final byte[][] SUPP5_PARITY = 100 {{E, E, O, O, O}, 101 {E, O, E, O, O}, 102 {E, O, O, E, O}, 103 {E, O, O, O, E}, 104 {O, E, E, O, O}, 105 {O, O, E, E, O}, 106 {O, O, O, E, E}, 107 {O, E, O, E, O}, 108 {O, E, O, O, E}, 109 {O, O, E, O, E}}; 110 111 private ChecksumMode checksumMode = ChecksumMode.CP_AUTO; 112 113 114 118 public UPCEANLogicImpl(ChecksumMode mode) { 119 this.checksumMode = mode; 120 } 121 122 126 public ChecksumMode getChecksumMode() { 127 return this.checksumMode; 128 } 129 130 135 public static void validateMessage(String msg) { 136 for (int i = 0; i < msg.length(); i++) { 137 final char c = msg.charAt(i); 138 if ((c < '0') || (c > '9')) { 139 throw new IllegalArgumentException ("Invalid characters found. " 140 + "Valid are 0-9 only. Message: " + msg); 141 } 142 } 143 } 144 145 150 public static char calcChecksum(String msg) { 151 int oddsum = 0; 152 int evensum = 0; 153 for (int i = msg.length() - 1; i >= 0; i--) { 154 if ((msg.length() - i) % 2 == 0) { 155 evensum += Character.digit(msg.charAt(i), 10); 156 } else { 157 oddsum += Character.digit(msg.charAt(i), 10); 158 } 159 } 160 int check = 10 - ((evensum + 3 * oddsum) % 10); 161 if (check >= 10) check = 0; 162 return Character.forDigit(check, 10); 163 } 164 165 private int widthAt(char ch, int index) { 166 if (Character.isDigit(ch)) { 167 int digit = Character.digit(ch, 10); 168 int width = CHARSET[digit][index]; 169 return width; 170 } else { 171 throw new IllegalArgumentException ("Invalid character '" + ch + "'. Expected a digit."); 172 } 173 } 174 175 181 protected void encodeChar(ClassicBarcodeLogicHandler logic, char c, int charset) { 182 logic.startBarGroup(BarGroup.MSG_CHARACTER, new Character (c).toString()); 183 if (charset == LEFT_HAND_B) { 184 for (byte i = 0; i < 4; i++) { 185 final int width = widthAt(c, 3 - i); 186 final boolean black = (i % 2 != 0); 187 logic.addBar(black, width); 188 } 189 } else { 190 for (byte i = 0; i < 4; i++) { 191 final int width = widthAt(c, i); 192 final boolean black = ((i % 2 == 0 && charset == RIGHT_HAND) 193 || (i % 2 != 0 && charset == LEFT_HAND_A)); 194 logic.addBar(black, width); 195 } 196 } 197 logic.endBarGroup(); 198 } 199 200 204 protected void drawSideGuard(ClassicBarcodeLogicHandler logic) { 205 logic.startBarGroup(BarGroup.UPC_EAN_GUARD, null); 207 logic.addBar(true, 1); 208 logic.addBar(false, 1); 209 logic.addBar(true, 1); 210 logic.endBarGroup(); 211 } 212 213 217 protected void drawCenterGuard(ClassicBarcodeLogicHandler logic) { 218 logic.startBarGroup(BarGroup.UPC_EAN_GUARD, null); 220 logic.addBar(false, 1); 221 logic.addBar(true, 1); 222 logic.addBar(false, 1); 223 logic.addBar(true, 1); 224 logic.addBar(false, 1); 225 logic.endBarGroup(); 226 } 227 228 232 private void drawSuppLeftGuard(ClassicBarcodeLogicHandler logic) { 233 logic.startBarGroup(BarGroup.UPC_EAN_GUARD, null); 235 logic.addBar(true, 1); 236 logic.addBar(false, 1); 237 logic.addBar(true, 2); 238 logic.endBarGroup(); 239 } 240 241 245 private void drawSuppSeparator(ClassicBarcodeLogicHandler logic) { 246 logic.startBarGroup(BarGroup.UPC_EAN_GUARD, null); 248 logic.addBar(false, 1); 249 logic.addBar(true, 1); 250 logic.endBarGroup(); 251 } 252 253 258 private void drawSupplemental2(ClassicBarcodeLogicHandler logic, String supp) { 259 int suppValue = Integer.parseInt(supp); 260 int remainder = suppValue % 4; 261 logic.startBarGroup(BarGroup.UPC_EAN_SUPP, supp); 262 drawSuppLeftGuard(logic); 263 encodeChar(logic, supp.charAt(0), SUPP2_PARITY[remainder][0]); 264 drawSuppSeparator(logic); 265 encodeChar(logic, supp.charAt(1), SUPP2_PARITY[remainder][1]); 266 logic.endBarGroup(); 267 } 268 269 274 private void drawSupplemental5(ClassicBarcodeLogicHandler logic, String supp) { 275 int suppValue = Integer.parseInt(supp); 276 int weightedSum = 277 3 * ((suppValue / 10000) % 10) 278 + 9 * ((suppValue / 1000) % 10) 279 + 3 * ((suppValue / 100) % 10) 280 + 9 * ((suppValue / 10) % 10) 281 + 3 * (suppValue % 10); 282 byte checksum = (byte)(weightedSum % 10); 283 logic.startBarGroup(BarGroup.UPC_EAN_SUPP, supp); 284 drawSuppLeftGuard(logic); 285 for (byte i = 0; i < 5; i++) { 286 if (i > 0) { 287 drawSuppSeparator(logic); 288 } 289 encodeChar(logic, supp.charAt(i), SUPP5_PARITY[checksum][i]); 290 } 291 logic.endBarGroup(); 292 } 293 294 299 protected void drawSupplemental(ClassicBarcodeLogicHandler logic, String supp) { 300 if (supp == null) { 301 throw new NullPointerException ("Supplemental message must not be null"); 302 } 303 if (supp.length() == 2) { 304 drawSupplemental2(logic, supp); 305 } else if (supp.length() == 5) { 306 drawSupplemental5(logic, supp); 307 } else { 308 throw new IllegalArgumentException ( 309 "Only supplemental lengths 2 and 5 are allowed: " + supp.length()); 310 } 311 } 312 313 320 protected static int getSupplementalLength(String msg) { 321 String supp = retrieveSupplemental(msg); 322 if (supp == null) { 323 return 0; 324 } else if (supp.length() == 2) { 325 return 2; 326 } else if (supp.length() == 5) { 327 return 5; 328 } else { 329 throw new IllegalArgumentException ( 330 "Illegal supplemental length (valid: 2 or 5): " + supp); 331 } 332 } 333 334 339 protected static String removeSupplemental(String msg) { 340 int pos = msg.indexOf('+'); 341 if (pos >= 0) { 342 return msg.substring(0, pos); 343 } else { 344 return msg; 345 } 346 } 347 348 354 protected static String retrieveSupplemental(String msg) { 355 int pos = msg.indexOf('+'); 356 if (pos >= 0) { 357 return msg.substring(pos + 1); 358 } else { 359 return null; 360 } 361 } 362 363 368 public abstract void generateBarcodeLogic(ClassicBarcodeLogicHandler logic, String msg); 369 370 } 371 | Popular Tags |