Fix #5 - Add field number to parse error messages
This commit is contained in:
@@ -35,12 +35,15 @@ public abstract class AlphaNumericFieldParseInfo extends FieldParseInfo {
|
||||
super(t, len);
|
||||
}
|
||||
|
||||
public IsoValue<?> parse(byte[] buf, int pos, CustomField<?> custom) throws ParseException, UnsupportedEncodingException {
|
||||
public IsoValue<?> parse(final int field, final byte[] buf, final int pos,
|
||||
final CustomField<?> custom)
|
||||
throws ParseException, UnsupportedEncodingException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid ALPHA/NUM position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid ALPHA/NUM field %d position %d",
|
||||
field, pos), pos);
|
||||
} else if (pos+length > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for %s field of length %d, pos %d",
|
||||
type, length, pos), pos);
|
||||
throw new ParseException(String.format("Insufficient data for %s field %d of length %d, pos %d",
|
||||
type, field, length, pos), pos);
|
||||
}
|
||||
try {
|
||||
String _v = new String(buf, pos, length, getCharacterEncoding());
|
||||
@@ -58,7 +61,9 @@ public abstract class AlphaNumericFieldParseInfo extends FieldParseInfo {
|
||||
return v;
|
||||
}
|
||||
} catch (StringIndexOutOfBoundsException ex) {
|
||||
throw new ParseException(String.format("Insufficient data for %s field of length %d, pos %d", type, length, pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for %s field %d of length %d, pos %d",
|
||||
type, field, length, pos), pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,13 +35,16 @@ public class AlphaParseInfo extends AlphaNumericFieldParseInfo {
|
||||
super(IsoType.ALPHA, len);
|
||||
}
|
||||
|
||||
public IsoValue<?> parseBinary(byte[] buf, int pos, CustomField<?> custom)
|
||||
throws ParseException, UnsupportedEncodingException {
|
||||
public IsoValue<?> parseBinary(final int field, final byte[] buf, final int pos,
|
||||
final CustomField<?> custom)
|
||||
throws ParseException, UnsupportedEncodingException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid bin ALPHA position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid bin ALPHA field %d position %d",
|
||||
field, pos), pos);
|
||||
} else if (pos+length > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for bin %s field of length %d, pos %d",
|
||||
type, length, pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for bin %s field %d of length %d, pos %d",
|
||||
type, field, length, pos), pos);
|
||||
}
|
||||
try {
|
||||
if (custom == null) {
|
||||
@@ -55,8 +58,9 @@ public class AlphaParseInfo extends AlphaNumericFieldParseInfo {
|
||||
return v;
|
||||
}
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
throw new ParseException(String.format("Insufficient data for bin %s field of length %d, pos %d",
|
||||
type, length, pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for bin %s field %d of length %d, pos %d",
|
||||
type, field, length, pos), pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,25 +37,32 @@ public class AmountParseInfo extends FieldParseInfo {
|
||||
super(IsoType.AMOUNT, 12);
|
||||
}
|
||||
|
||||
public IsoValue<BigDecimal> parse(byte[] buf, int pos, CustomField<?> custom)
|
||||
public IsoValue<BigDecimal> parse(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException, UnsupportedEncodingException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid AMOUNT position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid AMOUNT field %d position %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
if (pos+12 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for AMOUNT field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format("Insufficient data for AMOUNT field %d, pos %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
String c = new String(buf, pos, 12, getCharacterEncoding());
|
||||
try {
|
||||
return new IsoValue<BigDecimal>(type, new BigDecimal(c).movePointLeft(2), null);
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new ParseException(String.format("Cannot read amount '%s' pos %d", c, pos), pos);
|
||||
throw new ParseException(String.format("Cannot read amount '%s' field %d pos %d",
|
||||
c, field, pos), pos);
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
throw new ParseException(String.format("Insufficient data for AMOUNT field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for AMOUNT field %d, pos %d", field, pos), pos);
|
||||
}
|
||||
}
|
||||
|
||||
public IsoValue<BigDecimal> parseBinary(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<BigDecimal> parseBinary(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException {
|
||||
char[] digits = new char[13];
|
||||
digits[10] = '.';
|
||||
int start = 0;
|
||||
@@ -69,9 +76,11 @@ public class AmountParseInfo extends FieldParseInfo {
|
||||
try {
|
||||
return new IsoValue<BigDecimal>(IsoType.AMOUNT, new BigDecimal(new String(digits)), null);
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new ParseException(String.format("Cannot read amount '%s' pos %d", new String(digits), pos), pos);
|
||||
throw new ParseException(String.format("Cannot read amount '%s' field %d pos %d",
|
||||
new String(digits), field, pos), pos);
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
throw new ParseException(String.format("Insufficient data for AMOUNT field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for AMOUNT field %d, pos %d", field, pos), pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,14 +38,17 @@ public class BinaryParseInfo extends FieldParseInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<?> parse(byte[] buf, int pos, CustomField<?> custom)
|
||||
public IsoValue<?> parse(final int field, final byte[] buf, final int pos,
|
||||
final CustomField<?> custom)
|
||||
throws ParseException, UnsupportedEncodingException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid BINARY position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid BINARY field %d position %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
if (pos+(length*2) > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for BINARY field of length %d, pos %d",
|
||||
length, pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for BINARY field %d of length %d, pos %d",
|
||||
field, length, pos), pos);
|
||||
}
|
||||
byte[] binval = HexCodec.hexDecode(new String(buf, pos, length*2));
|
||||
if (custom == null) {
|
||||
@@ -61,14 +64,24 @@ public class BinaryParseInfo extends FieldParseInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<?> parseBinary(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<?> parseBinary(final int field, final byte[] buf, final int pos,
|
||||
final CustomField<?> custom) throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid BINARY field %d position %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
if (pos+length > buf.length) {
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for BINARY field %d of length %d, pos %d",
|
||||
field, length, pos), pos);
|
||||
}
|
||||
byte[] _v = new byte[length];
|
||||
System.arraycopy(buf, pos, _v, 0, length);
|
||||
if (custom == null) {
|
||||
return new IsoValue<byte[]>(type, _v, length, null);
|
||||
} else {
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
IsoValue<?> v = new IsoValue(type, custom.decodeField(HexCodec.hexEncode(_v)), length, custom);
|
||||
IsoValue<?> v = new IsoValue(type, custom.decodeField(HexCodec.hexEncode(_v, 0, _v.length)), length, custom);
|
||||
if (v.getValue() == null) {
|
||||
return new IsoValue<byte[]>(type, _v, length, null);
|
||||
}
|
||||
|
||||
@@ -52,19 +52,19 @@ public class ConfigParser {
|
||||
|
||||
/** Creates a message factory configured from the default file, which is j8583.xml
|
||||
* located in the root of the classpath. */
|
||||
public static MessageFactory createDefault() throws IOException {
|
||||
public static <T extends IsoMessage> MessageFactory<T> createDefault() throws IOException {
|
||||
if (MessageFactory.class.getClassLoader().getResource("j8583.xml") == null) {
|
||||
log.warn("ISO8583 ConfigParser cannot find j8583.xml, returning empty message factory");
|
||||
return new MessageFactory();
|
||||
return new MessageFactory<T>();
|
||||
} else {
|
||||
return createFromClasspathConfig("j8583.xml");
|
||||
}
|
||||
}
|
||||
|
||||
/** Creates a message factory from the specified path inside the classpath. */
|
||||
public static MessageFactory createFromClasspathConfig(String path) throws IOException {
|
||||
public static <T extends IsoMessage> MessageFactory<T> createFromClasspathConfig(String path) throws IOException {
|
||||
InputStream ins = MessageFactory.class.getClassLoader().getResourceAsStream(path);
|
||||
MessageFactory mfact = new MessageFactory();
|
||||
MessageFactory<T> mfact = new MessageFactory<T>();
|
||||
if (ins != null) {
|
||||
log.debug("ISO8583 Parsing config from classpath file {}", path);
|
||||
try {
|
||||
@@ -79,8 +79,8 @@ public class ConfigParser {
|
||||
}
|
||||
|
||||
/** Creates a message factory from the file located at the specified URL. */
|
||||
public static MessageFactory createFromUrl(URL url) throws IOException {
|
||||
MessageFactory mfact = new MessageFactory();
|
||||
public static <T extends IsoMessage> MessageFactory<T> createFromUrl(URL url) throws IOException {
|
||||
MessageFactory<T> mfact = new MessageFactory<T>();
|
||||
InputStream stream = url.openStream();
|
||||
try {
|
||||
parse(mfact, stream);
|
||||
@@ -93,7 +93,8 @@ public class ConfigParser {
|
||||
/** Reads the XML from the stream and configures the message factory with its values.
|
||||
* @param mfact The message factory to be configured with the values read from the XML.
|
||||
* @param stream The InputStream containing the XML configuration. */
|
||||
protected static void parse(MessageFactory mfact, InputStream stream) throws IOException {
|
||||
protected static <T extends IsoMessage> void parse(
|
||||
MessageFactory<T> mfact, InputStream stream) throws IOException {
|
||||
final DocumentBuilderFactory docfact = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docb = null;
|
||||
Document doc = null;
|
||||
@@ -167,7 +168,7 @@ public class ConfigParser {
|
||||
CustomField<Object> _cf = mfact.getCustomField(num);
|
||||
m.setValue(num, _cf == null ? v : _cf.decodeField(v), _cf, itype, length);
|
||||
}
|
||||
mfact.addMessageTemplate(m);
|
||||
mfact.addMessageTemplate((T)m);
|
||||
}
|
||||
|
||||
//Read the parsing guides
|
||||
@@ -197,7 +198,8 @@ public class ConfigParser {
|
||||
|
||||
/** Configures a MessageFactory using the default configuration file j8583.xml. This is useful
|
||||
* if you have a MessageFactory created using Spring for example. */
|
||||
public static void configureFromDefault(MessageFactory mfact) throws IOException {
|
||||
public static <T extends IsoMessage> void configureFromDefault(
|
||||
MessageFactory<T> mfact) throws IOException {
|
||||
if (MessageFactory.class.getClassLoader().getResource("j8583.xml") == null) {
|
||||
log.warn("ISO8583 config file j8583.xml not found!");
|
||||
} else {
|
||||
@@ -207,7 +209,8 @@ public class ConfigParser {
|
||||
|
||||
/** This method attempts to open a stream from the XML configuration in the specified URL and
|
||||
* configure the message factory from that config. */
|
||||
public static void configureFromUrl(MessageFactory mfact, URL url) throws IOException {
|
||||
public static <T extends IsoMessage> void configureFromUrl(
|
||||
MessageFactory<T> mfact, URL url) throws IOException {
|
||||
InputStream stream = url.openStream();
|
||||
try {
|
||||
parse(mfact, stream);
|
||||
@@ -219,7 +222,8 @@ public class ConfigParser {
|
||||
/** Configures a MessageFactory using the configuration file at the path specified (will be searched
|
||||
* within the classpath using the MessageFactory's ClassLoader). This is useful for configuring
|
||||
* Spring-bound instances of MessageFactory for example. */
|
||||
public static void configureFromClasspathConfig(MessageFactory mfact, String path) throws IOException {
|
||||
public static <T extends IsoMessage> void configureFromClasspathConfig(
|
||||
MessageFactory<T> mfact, String path) throws IOException {
|
||||
InputStream ins = MessageFactory.class.getClassLoader().getResourceAsStream(path);
|
||||
if (ins != null) {
|
||||
log.debug("ISO8583 Parsing config from classpath file {}", path);
|
||||
|
||||
@@ -42,13 +42,16 @@ public class Date10ParseInfo extends FieldParseInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<Date> parse(byte[] buf, int pos, CustomField<?> custom)
|
||||
public IsoValue<Date> parse(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid DATE10 position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid DATE10 field %d position %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
if (pos+10 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for DATE10 field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format("Insufficient data for DATE10 field %d, pos %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
//A SimpleDateFormat in the case of dates won't help because of the missing data
|
||||
//we have to use the current date for reference and change what comes in the buffer
|
||||
@@ -65,7 +68,17 @@ public class Date10ParseInfo extends FieldParseInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<Date> parseBinary(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<Date> parseBinary(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid DATE10 field %d position %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
if (pos+5 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for DATE10 field %d, pos %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
int[] tens = new int[5];
|
||||
int start = 0;
|
||||
for (int i = pos; i < pos + tens.length; i++) {
|
||||
|
||||
@@ -37,12 +37,15 @@ public class Date4ParseInfo extends FieldParseInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<Date> parse(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<Date> parse(final int field, final byte[] buf, final int pos,
|
||||
final CustomField<?> custom) throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid DATE4 position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid DATE4 field %d position %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
if (pos+4 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for DATE4 field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for DATE4 field %d, pos %d", field, pos), pos);
|
||||
}
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Calendar.HOUR, 0);
|
||||
@@ -57,9 +60,15 @@ public class Date4ParseInfo extends FieldParseInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<Date> parseBinary(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<Date> parseBinary(final int field, final byte[] buf, final int pos,
|
||||
final CustomField<?> custom) throws ParseException {
|
||||
int[] tens = new int[2];
|
||||
int start = 0;
|
||||
if (buf.length-pos < 2) {
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data to parse binary DATE4 field %d pos %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
for (int i = pos; i < pos + tens.length; i++) {
|
||||
tens[start++] = (((buf[i] & 0xf0) >> 4) * 10) + (buf[i] & 0x0f);
|
||||
}
|
||||
|
||||
@@ -37,12 +37,16 @@ public class DateExpParseInfo extends FieldParseInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<Date> parse(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<Date> parse(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid DATE_EXP position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid DATE_EXP field %d position %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
if (pos+4 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for DATE_EXP field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for DATE_EXP field %d pos %d", field, pos), pos);
|
||||
}
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Calendar.HOUR, 0);
|
||||
@@ -57,7 +61,17 @@ public class DateExpParseInfo extends FieldParseInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<Date> parseBinary(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<Date> parseBinary(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid DATE_EXP field %d position %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
if (pos+2 > buf.length) {
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for DATE_EXP field %d pos %d", field, pos), pos);
|
||||
}
|
||||
int[] tens = new int[2];
|
||||
int start = 0;
|
||||
for (int i = pos; i < pos + tens.length; i++) {
|
||||
|
||||
@@ -65,13 +65,23 @@ public abstract class FieldParseInfo {
|
||||
}
|
||||
|
||||
/** Parses the character data from the buffer and returns the
|
||||
* IsoValue with the correct data type in it. */
|
||||
public abstract IsoValue<?> parse(byte[] buf, int pos, CustomField<?> custom)
|
||||
* IsoValue with the correct data type in it.
|
||||
* @param field The field index, useful for error reporting.
|
||||
* @param buf The full ISO message buffer.
|
||||
* @param pos The starting position for the field data.
|
||||
* @param custom A CustomField to decode the field. */
|
||||
public abstract IsoValue<?> parse(final int field, byte[] buf, int pos,
|
||||
CustomField<?> custom)
|
||||
throws ParseException, UnsupportedEncodingException;
|
||||
|
||||
/** Parses binary data from the buffer, creating and returning an IsoValue of the configured
|
||||
* type and length. */
|
||||
public abstract IsoValue<?> parseBinary(byte[] buf, int pos, CustomField<?> custom)
|
||||
* type and length.
|
||||
* @param field The field index, useful for error reporting.
|
||||
* @param buf The full ISO message buffer.
|
||||
* @param pos The starting position for the field data.
|
||||
* @param custom A CustomField to decode the field. */
|
||||
public abstract IsoValue<?> parseBinary(final int field, byte[] buf, int pos,
|
||||
CustomField<?> custom)
|
||||
throws ParseException, UnsupportedEncodingException;
|
||||
|
||||
/** Returns a new FieldParseInfo instance that can parse the specified type. */
|
||||
|
||||
@@ -37,18 +37,25 @@ public class LlbinParseInfo extends FieldParseInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<?> parse(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<?> parse(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid LLBIN position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid LLBIN field %d position %d",
|
||||
field, pos), pos);
|
||||
} else if (pos+2 > buf.length) {
|
||||
throw new ParseException("Insufficient LLBIN header", pos);
|
||||
throw new ParseException(String.format("Insufficient LLBIN header field %d",
|
||||
field), pos);
|
||||
}
|
||||
length = ((buf[pos] - 48) * 10) + (buf[pos + 1] - 48);
|
||||
if (length < 0) {
|
||||
throw new ParseException(String.format("Invalid LLBIN length %d pos %d", length, pos), pos);
|
||||
throw new ParseException(String.format("Invalid LLBIN field %d length %d pos %d",
|
||||
field, length, pos), pos);
|
||||
}
|
||||
if (length+pos+2 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for LLBIN field, pos %d (LEN states '%s')", pos, new String(buf, pos, 2)), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for LLBIN field %d, pos %d (LEN states '%s')",
|
||||
field, pos, new String(buf, pos, 2)), pos);
|
||||
}
|
||||
byte[] binval = length == 0 ? new byte[0] : HexCodec.hexDecode(new String(buf, pos + 2, length));
|
||||
if (custom == null) {
|
||||
@@ -63,24 +70,31 @@ public class LlbinParseInfo extends FieldParseInfo {
|
||||
}
|
||||
return v;
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
throw new ParseException(String.format("Insufficient data for LLBIN field, pos %d (LEN states '%s')", pos, new String(buf, pos, 2)), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for LLBIN field %d, pos %d (LEN states '%s')",
|
||||
field, pos, new String(buf, pos, 2)), pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<?> parseBinary(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<?> parseBinary(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid bin LLBIN position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid bin LLBIN field %d position %d",
|
||||
field, pos), pos);
|
||||
} else if (pos+1 > buf.length) {
|
||||
throw new ParseException("Insufficient bin LLBIN header", pos);
|
||||
throw new ParseException(String.format("Insufficient bin LLBIN header field %d",
|
||||
field), pos);
|
||||
}
|
||||
length = (((buf[pos] & 0xf0) >> 4) * 10) + (buf[pos] & 0x0f);
|
||||
if (length < 0) {
|
||||
throw new ParseException(String.format("Invalid bin LLBIN length %d pos %d", length, pos), pos);
|
||||
}
|
||||
if (length+pos+1 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for bin LLBIN field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for bin LLBIN field %d, pos %d", field, pos), pos);
|
||||
}
|
||||
byte[] _v = new byte[length];
|
||||
System.arraycopy(buf, pos+1, _v, 0, length);
|
||||
@@ -88,7 +102,7 @@ public class LlbinParseInfo extends FieldParseInfo {
|
||||
return new IsoValue<byte[]>(type, _v, null);
|
||||
} else {
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
IsoValue<?> v = new IsoValue(type, custom.decodeField(HexCodec.hexEncode(_v)), custom);
|
||||
IsoValue<?> v = new IsoValue(type, custom.decodeField(HexCodec.hexEncode(_v, 0, _v.length)), custom);
|
||||
if (v.getValue() == null) {
|
||||
return new IsoValue<byte[]>(type, _v, null);
|
||||
}
|
||||
|
||||
@@ -37,20 +37,27 @@ public class LllbinParseInfo extends FieldParseInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<?> parse(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<?> parse(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid LLLBIN position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid LLLBIN field %d pos %d",
|
||||
field, pos), pos);
|
||||
} else if (pos+3 > buf.length) {
|
||||
throw new ParseException("Insufficient LLLBIN header", pos);
|
||||
throw new ParseException(String.format("Insufficient LLLBIN header field %d",
|
||||
field), pos);
|
||||
}
|
||||
if (!(Character.isDigit(buf[pos]) && Character.isDigit(buf[pos+1]) && Character.isDigit(buf[pos+2]))) {
|
||||
throw new ParseException(String.format("Invalid LLLBIN length '%s' pos %d", new String(buf, pos, 3), pos), pos);
|
||||
throw new ParseException(String.format("Invalid LLLBIN length '%s' field %d pos %d",
|
||||
new String(buf, pos, 3), field, pos), pos);
|
||||
}
|
||||
length = ((buf[pos] - 48) * 100) + ((buf[pos + 1] - 48) * 10) + (buf[pos + 2] - 48);
|
||||
if (length < 0) {
|
||||
throw new ParseException(String.format("Invalid LLLBIN length %d pos %d", length, pos), pos);
|
||||
throw new ParseException(String.format("Invalid LLLBIN length %d field %d pos %d",
|
||||
length, field, pos), pos);
|
||||
} else if (length+pos+3 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for LLLBIN field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for LLLBIN field %d, pos %d", field, pos), pos);
|
||||
}
|
||||
byte[] binval = length == 0 ? new byte[0] : HexCodec.hexDecode(new String(buf, pos + 3, length));
|
||||
if (custom == null) {
|
||||
@@ -66,24 +73,31 @@ public class LllbinParseInfo extends FieldParseInfo {
|
||||
}
|
||||
return v;
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
throw new ParseException(String.format("Insufficient data for LLLBIN field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for LLLBIN field %d, pos %d", field, pos), pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<?> parseBinary(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<?> parseBinary(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid bin LLLBIN position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid bin LLLBIN field %d pos %d",
|
||||
field, pos), pos);
|
||||
} else if (pos+3 > buf.length) {
|
||||
throw new ParseException("Insufficient bin LLLBIN header", pos);
|
||||
throw new ParseException(String.format("Insufficient LLLBIN header field %d",
|
||||
field), pos);
|
||||
}
|
||||
length = ((buf[pos] & 0x0f) * 100) + (((buf[pos + 1] & 0xf0) >> 4) * 10) + (buf[pos + 1] & 0x0f);
|
||||
if (length < 0) {
|
||||
throw new ParseException(String.format("Invalid bin LLLBIN length %d pos %d", length, pos), pos);
|
||||
throw new ParseException(String.format("Invalid LLLBIN length %d field %d pos %d",
|
||||
length, field, pos), pos);
|
||||
}
|
||||
if (length+pos+2 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for bin LLLBIN field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for bin LLLBIN field %d, pos %d", field, pos), pos);
|
||||
}
|
||||
byte[] _v = new byte[length];
|
||||
System.arraycopy(buf, pos+2, _v, 0, length);
|
||||
@@ -91,7 +105,7 @@ public class LllbinParseInfo extends FieldParseInfo {
|
||||
return new IsoValue<byte[]>(type, _v, null);
|
||||
} else {
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
IsoValue<?> v = new IsoValue(type, custom.decodeField(HexCodec.hexEncode(_v)), custom);
|
||||
IsoValue<?> v = new IsoValue(type, custom.decodeField(HexCodec.hexEncode(_v, 0, _v.length)), custom);
|
||||
if (v.getValue() == null) {
|
||||
return new IsoValue<byte[]>(type, _v, null);
|
||||
}
|
||||
|
||||
@@ -36,28 +36,34 @@ public class LllvarParseInfo extends FieldParseInfo {
|
||||
super(IsoType.LLLVAR, 0);
|
||||
}
|
||||
|
||||
public IsoValue<?> parse(byte[] buf, int pos, CustomField<?> custom)
|
||||
public IsoValue<?> parse(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException, UnsupportedEncodingException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid LLLVAR position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid LLLVAR field %d pos %d",
|
||||
field, pos), pos);
|
||||
} else if (pos+3 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for LLLVAR header, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for LLLVAR header field %d pos %d", field, pos), pos);
|
||||
}
|
||||
if (!(Character.isDigit(buf[pos]) && Character.isDigit(buf[pos+1]) && Character.isDigit(buf[pos+2]))) {
|
||||
throw new ParseException(String.format("Invalid LLLVAR length '%s' pos %d",
|
||||
new String(buf, pos, 3), pos), pos);
|
||||
throw new ParseException(String.format("Invalid LLLVAR length '%s' field %d pos %d",
|
||||
new String(buf, pos, 3), field, pos), pos);
|
||||
}
|
||||
length = ((buf[pos] - 48) * 100) + ((buf[pos + 1] - 48) * 10) + (buf[pos + 2] - 48);
|
||||
if (length < 0) {
|
||||
throw new ParseException(String.format("Invalid LLLVAR length %d pos %d", length, pos), pos);
|
||||
throw new ParseException(String.format("Invalid LLLVAR length %d field %d pos %d",
|
||||
length, field, pos), pos);
|
||||
} else if (length+pos+3 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for LLLVAR field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format("Insufficient data for LLLVAR field %d, pos %d",
|
||||
field, pos), pos);
|
||||
}
|
||||
String _v;
|
||||
try {
|
||||
_v = length == 0 ? "" : new String(buf, pos + 3, length, getCharacterEncoding());
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
throw new ParseException(String.format("Insufficient data for LLLVAR header, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for LLLVAR header, field %d pos %d", field, pos), pos);
|
||||
}
|
||||
//This is new: if the String's length is different from the specified length in the buffer,
|
||||
//there are probably some extended characters. So we create a String from the rest of the buffer,
|
||||
@@ -74,18 +80,22 @@ public class LllvarParseInfo extends FieldParseInfo {
|
||||
}
|
||||
}
|
||||
|
||||
public IsoValue<?> parseBinary(byte[] buf, int pos, CustomField<?> custom)
|
||||
public IsoValue<?> parseBinary(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException, UnsupportedEncodingException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid bin LLLVAR position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid bin LLLVAR field %d pos %d", field, pos), pos);
|
||||
} else if (pos+3 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for bin LLLVAR header, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for bin LLLVAR header, field %d pos %d", field, pos), pos);
|
||||
}
|
||||
length = ((buf[pos] & 0x0f) * 100) + (((buf[pos + 1] & 0xf0) >> 4) * 10) + (buf[pos + 1] & 0x0f);
|
||||
if (length < 0) {
|
||||
throw new ParseException(String.format("Invalid bin LLLVAR length %d pos %d", length, pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Invalid bin LLLVAR length %d, field %d pos %d", length, field, pos), pos);
|
||||
} else if (length+pos+2 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for bin LLLVAR field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for bin LLLVAR field %d, pos %d", field, pos), pos);
|
||||
}
|
||||
if (custom == null) {
|
||||
return new IsoValue<String>(type, new String(buf, pos + 2, length, getCharacterEncoding()), null);
|
||||
|
||||
@@ -35,24 +35,28 @@ public class LlvarParseInfo extends FieldParseInfo {
|
||||
super(IsoType.LLVAR, 0);
|
||||
}
|
||||
|
||||
public IsoValue<?> parse(byte[] buf, int pos, CustomField<?> custom)
|
||||
public IsoValue<?> parse(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException, UnsupportedEncodingException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid LLVAR position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid LLVAR field %d %d", field, pos), pos);
|
||||
} else if (pos+2 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for LLVAR header, pos %d", pos), pos);
|
||||
}
|
||||
length = ((buf[pos] - 48) * 10) + (buf[pos + 1] - 48);
|
||||
if (length < 0) {
|
||||
throw new ParseException(String.format("Invalid LLVAR length %d pos %d", length, pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Invalid LLVAR length %d, field %d pos %d", length, field, pos), pos);
|
||||
} else if (length+pos+2 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for LLVAR field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for LLVAR field %d, pos %d", field, pos), pos);
|
||||
}
|
||||
String _v;
|
||||
try {
|
||||
_v = length == 0 ? "" : new String(buf, pos + 2, length, getCharacterEncoding());
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
throw new ParseException(String.format("Insufficient data for LLVAR header, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for LLVAR header, field %d pos %d", field, pos), pos);
|
||||
}
|
||||
//This is new: if the String's length is different from the specified length in the buffer,
|
||||
//there are probably some extended characters. So we create a String from the rest of the buffer,
|
||||
@@ -72,19 +76,24 @@ public class LlvarParseInfo extends FieldParseInfo {
|
||||
}
|
||||
}
|
||||
|
||||
public IsoValue<?> parseBinary(byte[] buf, int pos, CustomField<?> custom)
|
||||
public IsoValue<?> parseBinary(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException, UnsupportedEncodingException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid bin LLVAR position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid bin LLVAR field %d pos %d",
|
||||
field, pos), pos);
|
||||
} else if (pos+1 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for bin LLVAR header, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for bin LLVAR header, field %d pos %d", field, pos), pos);
|
||||
}
|
||||
length = (((buf[pos] & 0xf0) >> 4) * 10) + (buf[pos] & 0x0f);
|
||||
if (length < 0) {
|
||||
throw new ParseException(String.format("Invalid bin LLVAR length %d pos %d", length, pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Invalid bin LLVAR length %d, field %d pos %d", length, field, pos), pos);
|
||||
}
|
||||
if (length+pos+1 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for bin LLVAR field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for bin LLVAR field %d, pos %d", field, pos), pos);
|
||||
}
|
||||
if (custom == null) {
|
||||
return new IsoValue<String>(type, new String(buf, pos + 1, length, getCharacterEncoding()), null);
|
||||
|
||||
@@ -35,12 +35,16 @@ public class NumericParseInfo extends AlphaNumericFieldParseInfo {
|
||||
super(IsoType.NUMERIC, len);
|
||||
}
|
||||
|
||||
public IsoValue<Number> parseBinary(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<Number> parseBinary(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid bin NUMERIC position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid bin NUMERIC field %d pos %d",
|
||||
field, pos), pos);
|
||||
} else if (pos+(length/2) > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for bin %s field of length %d, pos %d",
|
||||
type, length, pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for bin %s field %d of length %d, pos %d",
|
||||
type, field, length, pos), pos);
|
||||
}
|
||||
//A long covers up to 18 digits
|
||||
if (length < 19) {
|
||||
@@ -63,8 +67,9 @@ public class NumericParseInfo extends AlphaNumericFieldParseInfo {
|
||||
digits[start++] = (char)((buf[i] & 0x0f) + 48);
|
||||
}
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
throw new ParseException(String.format("Insufficient data for bin %s field of length %d, pos %d",
|
||||
type, length, pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for bin %s field %d of length %d, pos %d",
|
||||
type, field, length, pos), pos);
|
||||
}
|
||||
return new IsoValue<Number>(IsoType.NUMERIC, new BigInteger(new String(digits)), length, null);
|
||||
}
|
||||
|
||||
@@ -38,11 +38,15 @@ public class TimeParseInfo extends FieldParseInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<Date> parse(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<Date> parse(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid TIME position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid TIME field %d pos %d",
|
||||
field, pos), pos);
|
||||
} else if (pos+6 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for TIME field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for TIME field %d, pos %d", field, pos), pos);
|
||||
}
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Calendar.HOUR_OF_DAY, ((buf[pos] - 48) * 10) + buf[pos + 1] - 48);
|
||||
@@ -52,11 +56,15 @@ public class TimeParseInfo extends FieldParseInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsoValue<Date> parseBinary(byte[] buf, int pos, CustomField<?> custom) throws ParseException {
|
||||
public IsoValue<Date> parseBinary(final int field, final byte[] buf,
|
||||
final int pos, final CustomField<?> custom)
|
||||
throws ParseException {
|
||||
if (pos < 0) {
|
||||
throw new ParseException(String.format("Invalid bin TIME position %d", pos), pos);
|
||||
throw new ParseException(String.format("Invalid bin TIME field %d pos %d",
|
||||
field, pos), pos);
|
||||
} else if (pos+3 > buf.length) {
|
||||
throw new ParseException(String.format("Insufficient data for bin TIME field, pos %d", pos), pos);
|
||||
throw new ParseException(String.format(
|
||||
"Insufficient data for bin TIME field %d, pos %d", field, pos), pos);
|
||||
}
|
||||
int[] tens = new int[3];
|
||||
int start = 0;
|
||||
|
||||
Reference in New Issue
Block a user