org.krysalis.barcode4j.impl.fourstate.RoyalMailCBCLogicImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of barcode4j-fop-ext-0.20.5-complete Show documentation
Show all versions of barcode4j-fop-ext-0.20.5-complete Show documentation
Barcode4J is a flexible generator for barcodes written in Java inclusive
extensions to support Apache FOP 0.20.5.
The newest version!
/*
* Copyright 2006-2007 Jeremias Maerki.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.krysalis.barcode4j.impl.fourstate;
import org.krysalis.barcode4j.ChecksumMode;
/**
* Implements the Royal Mail Customer Barcode (CBC).
*
* @version $Id: RoyalMailCBCLogicImpl.java,v 1.2 2008/05/13 13:00:43 jmaerki Exp $
*/
public class RoyalMailCBCLogicImpl extends AbstractRMCBCKIXLogicImpl {
/**
* Main constructor
* @param mode checksum mode
*/
public RoyalMailCBCLogicImpl(ChecksumMode mode) {
super(mode);
}
/** {@inheritDoc} */
public char calcChecksum(String msg) {
String[] codewords = encodeHighLevel(removeStartStop(msg));
final int[] multiplier = new int[] {4, 2, 1, 0};
int upperSum = 0;
int lowerSum = 0;
for (int i = 0; i < codewords.length; i++) {
int upper = 0;
int lower = 0;
for (int j = 0; j < 4; j++) {
int v = codewords[i].charAt(j) - '0';
upper += (v & 1) * multiplier[j];
lower += ((v & 2) >> 1) * multiplier[j];
}
upperSum += upper % 6;
lowerSum += lower % 6;
}
int row = upperSum % 6;
if (row == 0) {
row = 5;
} else {
row -= 1;
}
int col = lowerSum % 6;
if (col == 0) {
col = 5;
} else {
col -= 1;
}
int idx = row * 6 + col;
if (idx < 10) {
return (char)('0' + idx);
} else {
return (char)('A' + idx - 10);
}
}
/**
* Handles the checksum, either checking if the right value was specified or adding the
* missing checksum depending on the settings.
* @param msg the message
* @return the (possibly) modified message
*/
protected String handleChecksum(String msg) {
if (getChecksumMode() == ChecksumMode.CP_ADD
|| getChecksumMode() == ChecksumMode.CP_AUTO) {
return msg + calcChecksum(msg);
} else if (getChecksumMode() == ChecksumMode.CP_CHECK) {
if (!validateChecksum(msg)) {
throw new IllegalArgumentException("Message '"
+ msg
+ "' has a bad checksum. Expected: "
+ calcChecksum(msg.substring(0, msg.length() - 1)));
}
return msg;
} else if (getChecksumMode() == ChecksumMode.CP_IGNORE) {
return msg;
} else {
throw new UnsupportedOperationException(
"Unknown checksum mode: " + getChecksumMode());
}
}
/**
* Removes the start and stop characters from the message.
* @param msg the message
* @return the modified message
*/
public static String removeStartStop(String msg) {
StringBuffer sb = new StringBuffer(msg.length());
for (int i = 0, c = msg.length(); i < c; i++) {
char ch = msg.charAt(i);
switch (ch) {
case '(':
case '[':
case ')':
case ']':
break;
default:
sb.append(ch);
}
}
return sb.toString();
}
/** {@inheritDoc} */
public String normalizeMessage(String msg) {
String s = removeStartStop(msg);
s = handleChecksum(s);
return "(" + s + ")";
}
}