26 Commits
Author SHA1 Message Date
Enrique Zamudio cc1fe845ed Version 1.8.0 2013-06-25 12:39:13 -05:00
Enrique Zamudio 61fded16d2 Fix debugString for variable-length fields 2013-06-25 12:37:41 -05:00
Enrique Zamudio 6bdd26fadf update site version to 1.8.0 2013-06-12 13:18:05 -05:00
Enrique Zamudio 0a85393b87 Simplify test code 2013-06-12 13:17:34 -05:00
Enrique Zamudio 1ccf3596d8 Test parsing a complete message with EBCDIC 2013-06-12 13:17:18 -05:00
Enrique Zamudio 470d492da2 Propagate char encoding and forceStringEncoding after parsing config 2013-06-12 13:16:28 -05:00
Enrique Zamudio a543212d1e debugString uses substrings for bitmap hex chars 2013-06-12 13:10:35 -05:00
Enrique Zamudio 096faeeda0 indexOf -> contains 2013-06-12 13:09:22 -05:00
Enrique Zamudio 406eb91d4b Simplify hex char array creation 2013-06-12 13:08:58 -05:00
Enrique Zamudio 8f91cb768c Test debugString with binary/ascii messages 2013-06-12 10:42:27 -05:00
Enrique Zamudio 078eeb6ee5 Add debugString() method 2013-06-12 10:42:09 -05:00
Enrique Zamudio 1b38a648f5 Set forceStringEncoding property on new messages 2013-06-12 10:41:50 -05:00
Enrique Zamudio 29357b8dd2 set jdk to 7 (with java6 compat) 2013-06-12 10:39:30 -05:00
Enrique Zamudio 1ce67c621c Encode text bitmap in EBCDIC with forceStringEncoding=true #13 2013-05-13 23:13:44 -05:00
Enrique Zamudio 1787dfb0d5 Test EBCDIC bitmap 2013-05-13 23:12:59 -05:00
Enrique Zamudio 2b1f9628bf Parse text bitmap for #13 2013-05-13 20:03:15 -05:00
Enrique Zamudio 2a38ac2491 force radix 10 2013-05-13 19:48:12 -05:00
Enrique Zamudio 63e89e708b add forceStringEncoding property to pass to messages for #13 2013-05-13 19:47:48 -05:00
Enrique Zamudio a086cad36d Test message parsing for #13 2013-05-13 19:47:27 -05:00
Enrique Zamudio 11e10bc1eb Implement #13 in these parsers 2013-05-13 19:34:21 -05:00
Enrique Zamudio e5aa694a45 More tests for #13 2013-05-13 19:34:04 -05:00
Enrique Zamudio 38df434d0a raise version number 2013-05-13 18:59:29 -05:00
Enrique Zamudio 89d8fce075 Test proper encoding of message type for #13 2013-05-13 18:59:09 -05:00
Enrique Zamudio 06700670ea update API calls 2013-05-13 18:55:01 -05:00
Enrique Zamudio 2e521c2b6d Implement #13 2013-05-13 18:54:44 -05:00
Enrique Zamudio 160f780309 Tests for #13 2013-05-13 18:53:20 -05:00
21 changed files with 483 additions and 148 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
apply plugin:'java'
apply plugin: 'maven'
defaultTasks 'build'
version='1.7.0'
version='1.8.0'
description='Java implementation of the ISO 8583 protocol, focused on making the creation, edition and reading of ISO8583 messages as simple and flexible as possible.'
sourceCompatibility=6
targetCompatibility=6
+1 -1
View File
@@ -271,7 +271,7 @@
<module fileurl="file://$PROJECT_DIR$/j8583.iml" filepath="$PROJECT_DIR$/j8583.iml" />
</modules>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="Java 6" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="Java 7" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="SvnConfiguration" maxAnnotateRevisions="500" myUseAcceleration="nothing" myAutoUpdateAfterCommit="false" cleanupOnStartRun="false">
+88 -17
View File
@@ -51,6 +51,7 @@ public class IsoMessage {
/** Flag to enforce secondary bitmap even if empty. */
private boolean forceb2;
private boolean binBitmap;
private boolean forceStringEncoding;
private String encoding = System.getProperty("file.encoding");
/** Creates a new empty message with no values set. */
@@ -96,7 +97,15 @@ public class IsoMessage {
return encoding;
}
/** Sets the string to be sent as ISO header, that is, after the length header but before the message type.
/** Specified whether the variable-length fields should encode their length
* headers using string conversion with the proper character encoding. Default
* is false, which is the old behavior (encoding as ASCII). This is only useful
* for text format. */
public void setForceStringEncoding(boolean flag) {
forceStringEncoding = flag;
}
/** Sets the string to be sent as ISO header, that is, after the length header but before the message type.
* This is useful in case an application needs some custom data in the ISO header of each message (very rare). */
public void setIsoHeader(String value) {
isoHeader = value;
@@ -309,6 +318,26 @@ public class IsoMessage {
return buf;
}
/** Creates a BitSet for the bitmap. */
protected BitSet createBitmapBitSet() {
BitSet bs = new BitSet(forceb2 ? 128 : 64);
for (int i = 2 ; i < 129; i++) {
if (fields[i] != null) {
bs.set(i - 1);
}
}
if (forceb2) {
bs.set(0);
} else if (bs.length() > 64) {
//Extend to 128 if needed
BitSet b2 = new BitSet(128);
b2.or(bs);
bs = b2;
bs.set(0);
}
return bs;
}
/** This calls writeInternal(), allowing applications to get the byte buffer containing the
* message data, without the length header. */
public byte[] writeData() {
@@ -333,21 +362,7 @@ public class IsoMessage {
}
//Bitmap
BitSet bs = new BitSet(forceb2 ? 128 : 64);
for (int i = 2 ; i < 129; i++) {
if (fields[i] != null) {
bs.set(i - 1);
}
}
if (forceb2) {
bs.set(0);
} else if (bs.length() > 64) {
//Extend to 128 if needed
BitSet b2 = new BitSet(128);
b2.or(bs);
bs = b2;
bs.set(0);
}
BitSet bs = createBitmapBitSet();
//Write bitmap to stream
if (binary || binBitmap) {
int pos = 128;
@@ -364,6 +379,11 @@ public class IsoMessage {
}
}
} else {
ByteArrayOutputStream bout2 = null;
if (forceStringEncoding) {
bout2 = bout;
bout = new ByteArrayOutputStream();
}
int pos = 0;
int lim = bs.size() / 4;
for (int i = 0; i < lim; i++) {
@@ -378,6 +398,15 @@ public class IsoMessage {
nibble |= 1;
bout.write(HEX[nibble]);
}
if (forceStringEncoding) {
final String _hb = new String(bout.toByteArray());
bout = bout2;
try {
bout.write(_hb.getBytes(encoding));
} catch (IOException ignore) {
//never happen
}
}
}
//Fields
@@ -385,7 +414,7 @@ public class IsoMessage {
IsoValue<?> v = fields[i];
if (v != null) {
try {
v.write(bout, binary);
v.write(bout, binary, forceStringEncoding);
} catch (IOException ex) {
//should never happen, writing to a ByteArrayOutputStream
}
@@ -394,6 +423,48 @@ public class IsoMessage {
return bout.toByteArray();
}
/** Returns a string representation of the message, as if it were encoded
* in ASCII with no binary bitmap. */
public String debugString() {
StringBuilder sb = new StringBuilder();
if (isoHeader != null) {
sb.append(isoHeader);
}
sb.append(String.format("%04x", type));
//Bitmap
BitSet bs = createBitmapBitSet();
int pos = 0;
int lim = bs.size() / 4;
for (int i = 0; i < lim; i++) {
int nibble = 0;
if (bs.get(pos++))
nibble |= 8;
if (bs.get(pos++))
nibble |= 4;
if (bs.get(pos++))
nibble |= 2;
if (bs.get(pos++))
nibble |= 1;
sb.append(new String(HEX, nibble, 1));
}
//Fields
for (int i = 2; i < 129; i++) {
IsoValue<?> v = fields[i];
if (v != null) {
String desc = v.toString();
if (v.getType() == IsoType.LLBIN || v.getType() == IsoType.LLVAR) {
sb.append(String.format("%02d", desc.length()));
} else if (v.getType() == IsoType.LLLBIN || v.getType() == IsoType.LLLVAR) {
sb.append(String.format("%03d", desc.length()));
}
sb.append(desc);
}
}
return sb.toString();
}
//These are for Groovy compat
/** Sets the specified value in the specified field, just like {@link #setField(int, IsoValue)}. */
public <T> void putAt(int i, IsoValue<T> v) {
+41 -39
View File
@@ -245,48 +245,50 @@ public class IsoValue<T> implements Cloneable {
return encoder;
}
protected void writeLengthHeader(final int l, final OutputStream outs, final int digits,
final boolean binary, final boolean forceStringEncoding)
throws IOException {
if (binary) {
if (digits == 3) {
outs.write(l / 100); //00 to 09 automatically in BCD
}
//BCD encode the rest of the length
outs.write((((l % 100) / 10) << 4) | (l % 10));
} else if (forceStringEncoding) {
String lhead = Integer.toString(l);
final int ldiff = digits - lhead.length();
if (ldiff == 1) {
lhead = '0' + lhead;
} else if (ldiff == 2) {
lhead = "00" + lhead;
}
outs.write(lhead.getBytes(encoding));
} else {
//write the length in ASCII
if (digits == 3) {
outs.write((l / 100) + 48);
}
if (l >= 10) {
outs.write(((l % 100) / 10) + 48);
} else {
outs.write(48);
}
outs.write((l % 10) + 48);
}
}
/** Writes the formatted value to a stream, with the length header
* if it's a variable length type. */
public void write(OutputStream outs, boolean binary) throws IOException {
* if it's a variable length type.
* @param outs The stream to which the value will be written.
* @param binary Specifies whether the value should be written in binary or text format.
* @param forceStringEncoding When using text format, force the encoding of length headers
* for variable-length fields to be done with the proper character encoding. When false,
* the length headers are encoded as ASCII; this used to be the only behavior. */
public void write(final OutputStream outs, final boolean binary, final boolean forceStringEncoding) throws IOException {
if (type == IsoType.LLLVAR || type == IsoType.LLVAR) {
if (binary) {
if (type == IsoType.LLLVAR) {
outs.write(length / 100); //00 to 09 automatically in BCD
}
//BCD encode the rest of the length
outs.write((((length % 100) / 10) << 4) | (length % 10));
} else {
//write the length in ASCII
if (type == IsoType.LLLVAR) {
outs.write((length / 100) + 48);
}
if (length >= 10) {
outs.write(((length % 100) / 10) + 48);
} else {
outs.write(48);
}
outs.write((length % 10) + 48);
}
writeLengthHeader(length, outs, type == IsoType.LLLVAR ? 3 : 2, binary, forceStringEncoding);
} else if (type == IsoType.LLBIN || type == IsoType.LLLBIN) {
if (binary) {
if (type == IsoType.LLLBIN ) {
outs.write(length / 100); //00 to 09 automatically in BCD
}
//BCD encode the rest of the length
outs.write((((length % 100) / 10) << 4) | (length % 10));
} else {
int _l = length*2;
//write the length in ASCII
if (type == IsoType.LLLBIN) {
outs.write((_l / 100) + 48);
}
if (_l >= 10) {
outs.write(((_l % 100) / 10) + 48);
} else {
outs.write(48);
}
outs.write((_l % 10) + 48);
}
writeLengthHeader(binary ? length : length*2, outs, type == IsoType.LLLBIN ? 3 : 2, binary, forceStringEncoding);
} else if (binary) {
//numeric types in binary are coded like this
byte[] buf = null;
@@ -75,8 +75,23 @@ public class MessageFactory<T extends IsoMessage> {
private boolean ignoreLast;
private boolean forceb2;
private boolean binBitmap;
private boolean forceStringEncoding;
private String encoding = System.getProperty("file.encoding");
/** This flag gets passed on to newly created messages and also sets this value for all
* field parsers in parsing guides. */
public void setForceStringEncoding(boolean flag) {
forceStringEncoding = flag;
for (Map<Integer,FieldParseInfo> pm : parseMap.values()) {
for (FieldParseInfo parser : pm.values()) {
parser.setForceStringDecoding(flag);
}
}
}
public boolean isForceStringEncoding() {
return forceStringEncoding;
}
/** Tells the factory to create messages that encode their bitmaps in binary format
* even when they're encoded as text. Has no effect on binary messages. */
public void setUseBinaryBitmap(boolean flag) {
@@ -94,13 +109,24 @@ public class MessageFactory<T extends IsoMessage> {
throw new IllegalArgumentException("Cannot set null encoding.");
}
encoding = value;
if (parseMap.size() > 0) {
if (!parseMap.isEmpty()) {
for (Map<Integer, FieldParseInfo> pt : parseMap.values()) {
for (FieldParseInfo fpi : pt.values()) {
fpi.setCharacterEncoding(encoding);
}
}
}
if (!typeTemplates.isEmpty()) {
for (T tmpl : typeTemplates.values()) {
tmpl.setCharacterEncoding(encoding);
for (int i = 2 ; i<129; i++) {
IsoValue<?> v = tmpl.getField(i);
if (v != null) {
v.setCharacterEncoding(encoding);
}
}
}
}
}
/** Returns the encoding used to parse ALPHA, LLVAR and LLLVAR fields. The default is the file.encoding
@@ -113,7 +139,7 @@ public class MessageFactory<T extends IsoMessage> {
public void setForceSecondaryBitmap(boolean flag) {
forceb2 = flag;
}
public boolean getForceSecondaryBitmap() {
public boolean isForceSecondaryBitmap() {
return forceb2;
}
@@ -143,12 +169,12 @@ public class MessageFactory<T extends IsoMessage> {
}
/** Returns a custom field encoder/decoder for the specified field number, if one is available. */
@SuppressWarnings("unchecked")
public <T> CustomField<T> getCustomField(int index) {
public <F> CustomField<F> getCustomField(int index) {
return customFields.get(index);
}
/** Returns a custom field encoder/decoder for the specified field number, if one is available. */
@SuppressWarnings("unchecked")
public <T> CustomField<T> getCustomField(Integer index) {
public <F> CustomField<F> getCustomField(Integer index) {
return customFields.get(index);
}
@@ -157,6 +183,9 @@ public class MessageFactory<T extends IsoMessage> {
* but is really convenient in case the MessageFactory is being configured from within, say, Spring. */
public void setConfigPath(String path) throws IOException {
ConfigParser.configureFromClasspathConfig(this, path);
//Now re-set some properties that need to be propagated down to the recently assigned objects
setCharacterEncoding(encoding);
setForceStringEncoding(forceStringEncoding);
}
/** Tells the receiver to create and parse binary messages if the flag is true.
@@ -192,6 +221,7 @@ public class MessageFactory<T extends IsoMessage> {
m.setForceSecondaryBitmap(forceb2);
m.setBinaryBitmap(binBitmap);
m.setCharacterEncoding(encoding);
m.setForceStringEncoding(forceStringEncoding);
//Copy the values from the template
IsoMessage templ = typeTemplates.get(type);
@@ -257,11 +287,13 @@ public class MessageFactory<T extends IsoMessage> {
if (buf.length < minlength) {
throw new ParseException("Insufficient buffer length, needs to be at least " + minlength, 0);
}
final T m = createIsoMessage(isoHeaderLength > 0 ? new String(buf, 0, isoHeaderLength) : null);
final T m = createIsoMessage(isoHeaderLength > 0 ? new String(buf, 0, isoHeaderLength, encoding) : null);
m.setCharacterEncoding(encoding);
final int type;
if (useBinary) {
type = ((buf[isoHeaderLength] & 0xff) << 8) | (buf[isoHeaderLength + 1] & 0xff);
} else if (forceStringEncoding) {
type = Integer.parseInt(new String(buf, isoHeaderLength, 4, encoding), 16);
} else {
type = ((buf[isoHeaderLength] - 48) << 12)
| ((buf[isoHeaderLength + 1] - 48) << 8)
@@ -300,45 +332,57 @@ public class MessageFactory<T extends IsoMessage> {
} else {
//ASCII parsing
try {
for (int i = isoHeaderLength + 4; i < isoHeaderLength + 20; i++) {
if (buf[i] >= '0' && buf[i] <= '9') {
bs.set(pos++, ((buf[i] - 48) & 8) > 0);
bs.set(pos++, ((buf[i] - 48) & 4) > 0);
bs.set(pos++, ((buf[i] - 48) & 2) > 0);
bs.set(pos++, ((buf[i] - 48) & 1) > 0);
} else if (buf[i] >= 'A' && buf[i] <= 'F') {
bs.set(pos++, ((buf[i] - 55) & 8) > 0);
bs.set(pos++, ((buf[i] - 55) & 4) > 0);
bs.set(pos++, ((buf[i] - 55) & 2) > 0);
bs.set(pos++, ((buf[i] - 5) & 1) > 0);
} else if (buf[i] >= 'a' && buf[i] <= 'f') {
bs.set(pos++, ((buf[i] - 87) & 8) > 0);
bs.set(pos++, ((buf[i] - 87) & 4) > 0);
bs.set(pos++, ((buf[i] - 87) & 2) > 0);
bs.set(pos++, ((buf[i] - 87) & 1) > 0);
}
}
final byte[] bitmapBuffer;
if (forceStringEncoding) {
byte[] _bb = new String(buf, isoHeaderLength+4, 16, encoding).getBytes();
bitmapBuffer = new byte[36+isoHeaderLength];
System.arraycopy(_bb, 0, bitmapBuffer, 4+isoHeaderLength, 16);
} else {
bitmapBuffer = buf;
}
for (int i = isoHeaderLength + 4; i < isoHeaderLength + 20; i++) {
if (bitmapBuffer[i] >= '0' && bitmapBuffer[i] <= '9') {
bs.set(pos++, ((bitmapBuffer[i] - 48) & 8) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 48) & 4) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 48) & 2) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 48) & 1) > 0);
} else if (bitmapBuffer[i] >= 'A' && bitmapBuffer[i] <= 'F') {
bs.set(pos++, ((bitmapBuffer[i] - 55) & 8) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 55) & 4) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 55) & 2) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 5) & 1) > 0);
} else if (bitmapBuffer[i] >= 'a' && bitmapBuffer[i] <= 'f') {
bs.set(pos++, ((bitmapBuffer[i] - 87) & 8) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 87) & 4) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 87) & 2) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 87) & 1) > 0);
}
}
//Check for secondary bitmap and parse it if necessary
if (bs.get(0)) {
if (buf.length < minlength + 16) {
throw new ParseException("Insufficient length for secondary bitmap", minlength);
}
if (forceStringEncoding) {
byte[] _bb = new String(buf, isoHeaderLength+4, 16, encoding).getBytes();
System.arraycopy(_bb, 0, bitmapBuffer, 20+isoHeaderLength, 16);
}
for (int i = isoHeaderLength + 20; i < isoHeaderLength + 36; i++) {
if (buf[i] >= '0' && buf[i] <= '9') {
bs.set(pos++, ((buf[i] - 48) & 8) > 0);
bs.set(pos++, ((buf[i] - 48) & 4) > 0);
bs.set(pos++, ((buf[i] - 48) & 2) > 0);
bs.set(pos++, ((buf[i] - 48) & 1) > 0);
} else if (buf[i] >= 'A' && buf[i] <= 'F') {
bs.set(pos++, ((buf[i] - 55) & 8) > 0);
bs.set(pos++, ((buf[i] - 55) & 4) > 0);
bs.set(pos++, ((buf[i] - 55) & 2) > 0);
bs.set(pos++, ((buf[i] - 5) & 1) > 0);
} else if (buf[i] >= 'a' && buf[i] <= 'f') {
bs.set(pos++, ((buf[i] - 87) & 8) > 0);
bs.set(pos++, ((buf[i] - 87) & 4) > 0);
bs.set(pos++, ((buf[i] - 87) & 2) > 0);
bs.set(pos++, ((buf[i] - 87) & 1) > 0);
if (bitmapBuffer[i] >= '0' && bitmapBuffer[i] <= '9') {
bs.set(pos++, ((bitmapBuffer[i] - 48) & 8) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 48) & 4) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 48) & 2) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 48) & 1) > 0);
} else if (bitmapBuffer[i] >= 'A' && bitmapBuffer[i] <= 'F') {
bs.set(pos++, ((bitmapBuffer[i] - 55) & 8) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 55) & 4) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 55) & 2) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 5) & 1) > 0);
} else if (bitmapBuffer[i] >= 'a' && bitmapBuffer[i] <= 'f') {
bs.set(pos++, ((bitmapBuffer[i] - 87) & 8) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 87) & 4) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 87) & 2) > 0);
bs.set(pos++, ((bitmapBuffer[i] - 87) & 1) > 0);
}
}
pos = 16 + minlength;
@@ -426,7 +470,7 @@ public class MessageFactory<T extends IsoMessage> {
/** Creates a Iso message, override this method in the subclass to provide your
* own implementations of IsoMessage.
* @param header
* @param header The optional ISO header that goes before the message type
* @return IsoMessage
*/
@SuppressWarnings("unchecked")
@@ -120,7 +120,7 @@ public class ConfigParser {
@Override
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
if (systemId.indexOf("j8583.dtd") >= 0) {
if (systemId.contains("j8583.dtd")) {
URL dtd = getClass().getResource("j8583.dtd");
if (dtd == null) {
log.warn("Cannot find j8583.dtd in classpath. j8583 config files will not be validated.");
@@ -210,7 +210,6 @@ public class ConfigParser {
}
mfact.setParseMap(type, parseMap);
}
}
/** Configures a MessageFactory using the default configuration file j8583.xml. This is useful
@@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package com.solab.iso8583.parse;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
@@ -44,7 +45,7 @@ public class Date10ParseInfo extends FieldParseInfo {
@Override
public <T> IsoValue<Date> parse(final int field, final byte[] buf,
final int pos, final CustomField<T> custom)
throws ParseException {
throws ParseException, UnsupportedEncodingException {
if (pos < 0) {
throw new ParseException(String.format("Invalid DATE10 field %d position %d",
field, pos), pos);
@@ -57,12 +58,20 @@ public class Date10ParseInfo extends FieldParseInfo {
//we have to use the current date for reference and change what comes in the buffer
Calendar cal = Calendar.getInstance();
//Set the month in the date
cal.set(Calendar.MONTH, ((buf[pos] - 48) * 10) + buf[pos + 1] - 49);
cal.set(Calendar.DATE, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48);
cal.set(Calendar.HOUR_OF_DAY, ((buf[pos + 4] - 48) * 10) + buf[pos + 5] - 48);
cal.set(Calendar.MINUTE, ((buf[pos + 6] - 48) * 10) + buf[pos + 7] - 48);
cal.set(Calendar.SECOND, ((buf[pos + 8] - 48) * 10) + buf[pos + 9] - 48);
cal.set(Calendar.MILLISECOND,0);
if (forceStringDecoding) {
cal.set(Calendar.MONTH, Integer.parseInt(new String(buf, pos, 2, getCharacterEncoding()), 10)-1);
cal.set(Calendar.DATE, Integer.parseInt(new String(buf, pos+2, 2, getCharacterEncoding()), 10));
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(new String(buf, pos+4, 2, getCharacterEncoding()), 10));
cal.set(Calendar.MINUTE, Integer.parseInt(new String(buf, pos+6, 2, getCharacterEncoding()), 10));
cal.set(Calendar.SECOND, Integer.parseInt(new String(buf, pos+8, 2, getCharacterEncoding()), 10));
} else {
cal.set(Calendar.MONTH, ((buf[pos] - 48) * 10) + buf[pos + 1] - 49);
cal.set(Calendar.DATE, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48);
cal.set(Calendar.HOUR_OF_DAY, ((buf[pos + 4] - 48) * 10) + buf[pos + 5] - 48);
cal.set(Calendar.MINUTE, ((buf[pos + 6] - 48) * 10) + buf[pos + 7] - 48);
cal.set(Calendar.SECOND, ((buf[pos + 8] - 48) * 10) + buf[pos + 9] - 48);
}
cal.set(Calendar.MILLISECOND,0);
adjustWithFutureTolerance(cal);
return new IsoValue<Date>(type, cal.getTime(), null);
}
@@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package com.solab.iso8583.parse;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
@@ -38,7 +39,8 @@ public class Date4ParseInfo extends FieldParseInfo {
@Override
public <T> IsoValue<Date> parse(final int field, final byte[] buf, final int pos,
final CustomField<T> custom) throws ParseException {
final CustomField<T> custom)
throws ParseException, UnsupportedEncodingException {
if (pos < 0) {
throw new ParseException(String.format("Invalid DATE4 field %d position %d",
field, pos), pos);
@@ -53,8 +55,13 @@ public class Date4ParseInfo extends FieldParseInfo {
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
//Set the month in the date
cal.set(Calendar.MONTH, ((buf[pos] - 48) * 10) + buf[pos + 1] - 49);
cal.set(Calendar.DATE, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48);
if (forceStringDecoding) {
cal.set(Calendar.MONTH, Integer.parseInt(new String(buf, pos, 2, getCharacterEncoding()), 10)-1);
cal.set(Calendar.DATE, Integer.parseInt(new String(buf, pos+2, 2, getCharacterEncoding()), 10));
} else {
cal.set(Calendar.MONTH, ((buf[pos] - 48) * 10) + buf[pos + 1] - 49);
cal.set(Calendar.DATE, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48);
}
Date10ParseInfo.adjustWithFutureTolerance(cal);
return new IsoValue<Date>(type, cal.getTime(), null);
}
@@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package com.solab.iso8583.parse;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
@@ -39,7 +40,7 @@ public class DateExpParseInfo extends FieldParseInfo {
@Override
public <T> IsoValue<Date> parse(final int field, final byte[] buf,
final int pos, final CustomField<T> custom)
throws ParseException {
throws ParseException, UnsupportedEncodingException {
if (pos < 0) {
throw new ParseException(String.format("Invalid DATE_EXP field %d position %d",
field, pos), pos);
@@ -54,9 +55,15 @@ public class DateExpParseInfo extends FieldParseInfo {
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.DATE, 1);
//Set the month in the date
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) - (cal.get(Calendar.YEAR) % 100)
+ ((buf[pos] - 48) * 10) + buf[pos + 1] - 48);
cal.set(Calendar.MONTH, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 49);
if (forceStringDecoding) {
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) - (cal.get(Calendar.YEAR) % 100)
+ Integer.parseInt(new String(buf, pos, 2, getCharacterEncoding()), 10));
cal.set(Calendar.MONTH, Integer.parseInt(new String(buf, pos+2, 2, getCharacterEncoding()), 10)-1);
} else {
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) - (cal.get(Calendar.YEAR) % 100)
+ ((buf[pos] - 48) * 10) + buf[pos + 1] - 48);
cal.set(Calendar.MONTH, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 49);
}
return new IsoValue<Date>(type, cal.getTime(), null);
}
@@ -34,6 +34,7 @@ public abstract class FieldParseInfo {
protected IsoType type;
protected int length;
private String encoding = System.getProperty("file.encoding");
protected boolean forceStringDecoding;
/** Creates a new instance that parses a value of the specified type, with the specified length.
* The length is only useful for ALPHA and NUMERIC types.
@@ -47,6 +48,13 @@ public abstract class FieldParseInfo {
length = len;
}
/** Specified whether length headers for variable-length fields in text mode should
* be decoded using proper string conversion with the character encoding. Default is false,
* which means use the old behavior of decoding as ASCII. */
public void setForceStringDecoding(boolean flag) {
forceStringDecoding = flag;
}
public void setCharacterEncoding(String value) {
encoding = value;
}
@@ -119,4 +127,14 @@ public abstract class FieldParseInfo {
return fpi;
}
protected int decodeLength(byte[] buf, int pos, int digits) throws UnsupportedEncodingException {
if (forceStringDecoding) {
return Integer.parseInt(new String(buf, pos, digits, encoding));
} else if (digits == 3) {
return ((buf[pos] - 48) * 100) + ((buf[pos + 1] - 48) * 10) + (buf[pos + 2] - 48);
} else {
return ((buf[pos] - 48) * 10) + (buf[pos + 1] - 48);
}
}
}
@@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package com.solab.iso8583.parse;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import com.solab.iso8583.CustomBinaryField;
@@ -40,7 +41,7 @@ public class LlbinParseInfo extends FieldParseInfo {
@Override
public <T> IsoValue<?> parse(final int field, final byte[] buf,
final int pos, final CustomField<T> custom)
throws ParseException {
throws ParseException, UnsupportedEncodingException {
if (pos < 0) {
throw new ParseException(String.format("Invalid LLBIN field %d position %d",
field, pos), pos);
@@ -48,7 +49,7 @@ public class LlbinParseInfo extends FieldParseInfo {
throw new ParseException(String.format("Insufficient LLBIN header field %d",
field), pos);
}
length = ((buf[pos] - 48) * 10) + (buf[pos + 1] - 48);
length = decodeLength(buf, pos, 2);
if (length < 0) {
throw new ParseException(String.format("Invalid LLBIN field %d length %d pos %d",
field, length, pos), pos);
@@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package com.solab.iso8583.parse;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import com.solab.iso8583.CustomBinaryField;
@@ -40,7 +41,7 @@ public class LllbinParseInfo extends FieldParseInfo {
@Override
public <T> IsoValue<?> parse(final int field, final byte[] buf,
final int pos, final CustomField<T> custom)
throws ParseException {
throws ParseException, UnsupportedEncodingException {
if (pos < 0) {
throw new ParseException(String.format("Invalid LLLBIN field %d pos %d",
field, pos), pos);
@@ -48,11 +49,7 @@ public class LllbinParseInfo extends FieldParseInfo {
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' field %d pos %d",
new String(buf, pos, 3), field, pos), pos);
}
final int l = ((buf[pos] - 48) * 100) + ((buf[pos + 1] - 48) * 10) + (buf[pos + 2] - 48);
final int l = decodeLength(buf, pos, 3);
if (l < 0) {
throw new ParseException(String.format("Invalid LLLBIN length %d field %d pos %d",
l, field, pos), pos);
@@ -46,11 +46,7 @@ public class LllvarParseInfo extends FieldParseInfo {
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' 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);
length = decodeLength(buf, pos, 3);
if (length < 0) {
throw new ParseException(String.format("Invalid LLLVAR length %d field %d pos %d",
length, field, pos), pos);
@@ -44,7 +44,7 @@ public class LlvarParseInfo extends FieldParseInfo {
} 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);
length = decodeLength(buf, pos, 2);
if (length < 0) {
throw new ParseException(String.format(
"Invalid LLVAR length %d, field %d pos %d", length, field, pos), pos);
@@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package com.solab.iso8583.parse;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
@@ -40,7 +41,7 @@ public class TimeParseInfo extends FieldParseInfo {
@Override
public <T> IsoValue<Date> parse(final int field, final byte[] buf,
final int pos, final CustomField<T> custom)
throws ParseException {
throws ParseException, UnsupportedEncodingException {
if (pos < 0) {
throw new ParseException(String.format("Invalid TIME field %d pos %d",
field, pos), pos);
@@ -49,9 +50,15 @@ public class TimeParseInfo extends FieldParseInfo {
"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);
cal.set(Calendar.MINUTE, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48);
cal.set(Calendar.SECOND, ((buf[pos + 4] - 48) * 10) + buf[pos + 5] - 48);
if (forceStringDecoding) {
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(new String(buf, pos, 2, getCharacterEncoding()), 10));
cal.set(Calendar.MINUTE, Integer.parseInt(new String(buf, pos+2, 2, getCharacterEncoding()), 10));
cal.set(Calendar.SECOND, Integer.parseInt(new String(buf, pos+4, 2, getCharacterEncoding()), 10));
} else {
cal.set(Calendar.HOUR_OF_DAY, ((buf[pos] - 48) * 10) + buf[pos + 1] - 48);
cal.set(Calendar.MINUTE, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48);
cal.set(Calendar.SECOND, ((buf[pos + 4] - 48) * 10) + buf[pos + 5] - 48);
}
return new IsoValue<Date>(type, cal.getTime(), null);
}
@@ -3,7 +3,7 @@ package com.solab.iso8583.util;
/** Utility class to perform HEX encoding/decoding of values. */
public final class HexCodec {
static final char[] HEX = new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
static final char[] HEX = "0123456789ABCDEF".toCharArray();
private HexCodec(){}
+1 -1
View File
@@ -15,7 +15,7 @@
<item name="Download" href="http://sourceforge.net/projects/j8583/files/j8583/"/>
</links>
<menu name="j8583 1.5.7">
<menu name="j8583 1.8.0">
<item name="Introduction" href="index.html"/>
<item name="API docs" href="javadoc/index.html" />
<item name="Beginner's Guide" href="guide.html"/>
+1 -1
View File
@@ -87,7 +87,7 @@ public class CustomBinCodecs {
}
//Test parsing
tmpl = mfact.parseMessage(buf, 0);
Assert.assertEquals(new Long(1234567890l), tmpl.getObjectValue(2));
Assert.assertEquals(1234567890l, tmpl.getObjectValue(2));
Assert.assertEquals(b29, tmpl.getObjectValue(3));
}
+6
View File
@@ -5,6 +5,7 @@ import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.ParseException;
import com.solab.iso8583.IsoType;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -83,6 +84,11 @@ public class TestBinaries {
//Compare values, should be the same
testParsed(bin2);
Assert.assertEquals(bin.getObjectValue(7).toString(), bin2.getObjectValue(7).toString());
//Test the debug string
ascii.setValue(60, "XXX", IsoType.LLVAR, 0);
bin.setValue(60, "XXX", IsoType.LLVAR, 0);
Assert.assertEquals("Debug strings differ", ascii.debugString(), bin.debugString());
Assert.assertTrue("LLVAR fields wrong", ascii.debugString().contains("03XXX"));
}
@Test
+2 -14
View File
@@ -6,12 +6,10 @@ import java.text.ParseException;
import java.util.Date;
import java.util.GregorianCalendar;
import com.solab.iso8583.IsoMessage;
import org.junit.*;
import com.solab.iso8583.IsoType;
import com.solab.iso8583.IsoValue;
import com.solab.iso8583.MessageFactory;
import com.solab.iso8583.parse.Date10ParseInfo;
import com.solab.iso8583.parse.Date4ParseInfo;
@@ -21,16 +19,6 @@ import com.solab.iso8583.parse.Date4ParseInfo;
*/
public class TestDates {
private MessageFactory<IsoMessage> mf;
@Before
public void init() throws IOException {
mf = new MessageFactory<IsoMessage>();
mf.setCharacterEncoding("UTF-8");
mf.setCustomField(48, new CustomField48());
mf.setConfigPath("config.xml");
}
@Test
public void testDate4FutureTolerance() throws ParseException, IOException {
GregorianCalendar today = new GregorianCalendar();
@@ -44,7 +32,7 @@ public class TestDates {
Assert.assertEquals(comp.getValue(), today.getTime());
//Now with the binary
ByteArrayOutputStream bout = new ByteArrayOutputStream();
comp.write(bout, true);
comp.write(bout, true, false);
IsoValue<Date> bin = new Date4ParseInfo().parseBinary(0, bout.toByteArray(), 0, null);
Assert.assertEquals(comp.getValue().getTime(), bin.getValue().getTime());
}
@@ -57,7 +45,7 @@ public class TestDates {
assert comp.getValue().after(new Date());
//Now with the binary
ByteArrayOutputStream bout = new ByteArrayOutputStream();
comp.write(bout, true);
comp.write(bout, true, false);
IsoValue<Date> bin = new Date10ParseInfo().parseBinary(0, bout.toByteArray(), 0, null);
Assert.assertEquals(comp.getValue().getTime(), bin.getValue().getTime());
}
+183
View File
@@ -0,0 +1,183 @@
package j8583;
import com.solab.iso8583.IsoMessage;
import com.solab.iso8583.IsoType;
import com.solab.iso8583.IsoValue;
import com.solab.iso8583.MessageFactory;
import com.solab.iso8583.parse.*;
import com.solab.iso8583.util.HexCodec;
import org.junit.Assert;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
/**
* Test for EBCDIC support.
*
* @author Enrique Zamudio
* Date: 13/05/13 18:12
*/
public class TestEbcdic {
private IsoValue<String> llvar = new IsoValue<String>(IsoType.LLVAR, "Testing, testing, 123");
@Test
public void testAscii() throws IOException, ParseException {
llvar.setCharacterEncoding("UTF-8");
final ByteArrayOutputStream bout = new ByteArrayOutputStream();
llvar.write(bout, false, false);
byte[] buf = bout.toByteArray();
Assert.assertEquals(50, buf[0]);
Assert.assertEquals(49, buf[1]);
final LlvarParseInfo parser = new LlvarParseInfo();
parser.setCharacterEncoding("UTF-8");
IsoValue<?> field = parser.parse(1, buf, 0, null);
Assert.assertEquals(llvar.getValue(), field.getValue());
}
@Test
public void testEbcdic() throws IOException, ParseException {
llvar.setCharacterEncoding("Cp1047");
final ByteArrayOutputStream bout = new ByteArrayOutputStream();
llvar.write(bout, false, true);
byte[] buf = bout.toByteArray();
Assert.assertEquals((byte)242, buf[0]);
Assert.assertEquals((byte) 241, buf[1]);
final LlvarParseInfo parser = new LlvarParseInfo();
parser.setCharacterEncoding("Cp1047");
parser.setForceStringDecoding(true);
IsoValue<?> field = parser.parse(1, buf, 0, null);
Assert.assertEquals(llvar.getValue(), field.getValue());
}
@Test
public void testParsers() throws UnsupportedEncodingException, ParseException {
final byte[] stringA = "A".getBytes("Cp1047");
final LllvarParseInfo lllvar = new LllvarParseInfo();
lllvar.setCharacterEncoding("Cp1047");
lllvar.setForceStringDecoding(true);
IsoValue<?> field = lllvar.parse(1, new byte[]{(byte)240, (byte)240, (byte)241, (byte)193}, 0, null);
Assert.assertEquals(new String(stringA, "Cp1047"), field.getValue());
final LllbinParseInfo lllbin = new LllbinParseInfo();
lllbin.setCharacterEncoding("Cp1047");
lllbin.setForceStringDecoding(true);
field = lllbin.parse(1, new byte[]{(byte)240, (byte)240, (byte)242, 67, 49}, 0, null);
Assert.assertArrayEquals(stringA, (byte[]) field.getValue());
final LlbinParseInfo llbin = new LlbinParseInfo();
llbin.setCharacterEncoding("Cp1047");
llbin.setForceStringDecoding(true);
field = llbin.parse(1, new byte[]{(byte)240, (byte)242, 67, 49}, 0, null);
Assert.assertArrayEquals(stringA, (byte[]) field.getValue());
}
@Test
public void testMessageType() throws UnsupportedEncodingException, ParseException {
final IsoMessage msg = new IsoMessage();
msg.setType(0x1100);
msg.setBinaryBitmap(true);
msg.setCharacterEncoding("Cp1047");
final byte[] enc = msg.writeData();
Assert.assertEquals(12, enc.length);
Assert.assertEquals((byte) 241, enc[0]);
Assert.assertEquals((byte) 241, enc[1]);
Assert.assertEquals((byte)240, enc[2]);
Assert.assertEquals((byte) 240, enc[3]);
MessageFactory<IsoMessage> mf = new MessageFactory<IsoMessage>();
HashMap<Integer, FieldParseInfo> pmap = new HashMap<Integer, FieldParseInfo>();
mf.setForceStringEncoding(true);
mf.setUseBinaryBitmap(true);
mf.setCharacterEncoding("Cp1047");
mf.setParseMap(0x1100, pmap);
IsoMessage m2 = mf.parseMessage(enc, 0);
Assert.assertEquals(msg.getType(), m2.getType());
//Now with text bitmap
msg.setBinaryBitmap(false);
msg.setForceStringEncoding(true);
final byte[] enc2 = msg.writeData();
Assert.assertEquals(20, enc2.length);
mf.setUseBinaryBitmap(false);
m2 = mf.parseMessage(enc2, 0);
Assert.assertEquals(msg.getType(), m2.getType());
}
@Test
public void testDate4() throws UnsupportedEncodingException, ParseException {
final Date4ParseInfo parser = new Date4ParseInfo();
parser.setCharacterEncoding("Cp1047");
parser.setForceStringDecoding(true);
final IsoValue<Date> v = parser.parse(1, new byte[]{(byte)240, (byte)241, (byte)242, (byte)245}, 0, null);
Assert.assertEquals("01", String.format("%Tm", v.getValue()));
Assert.assertEquals("25", String.format("%Td", v.getValue()));
}
@Test
public void testDate10() throws UnsupportedEncodingException, ParseException {
final Date10ParseInfo parser = new Date10ParseInfo();
parser.setCharacterEncoding("Cp1047");
parser.setForceStringDecoding(true);
final IsoValue<Date> v = parser.parse(1, new byte[]{(byte)240, (byte)241, (byte)242, (byte)245, (byte)242, (byte)243, (byte)245, (byte)249, (byte)245, (byte)249}, 0, null);
Assert.assertEquals("01", String.format("%Tm", v.getValue()));
Assert.assertEquals("25", String.format("%Td", v.getValue()));
Assert.assertEquals("23:59:59", String.format("%TT", v.getValue()));
}
@Test
public void testDateExp() throws UnsupportedEncodingException, ParseException {
final DateExpParseInfo parser = new DateExpParseInfo();
parser.setCharacterEncoding("Cp1047");
parser.setForceStringDecoding(true);
final IsoValue<Date> v = parser.parse(1, new byte[]{(byte)241, (byte)247, (byte)241, (byte)242}, 0, null);
Assert.assertEquals("12", String.format("%Tm", v.getValue()));
Assert.assertEquals("2017", String.format("%TY", v.getValue()));
}
@Test
public void testTime() throws UnsupportedEncodingException, ParseException {
final TimeParseInfo parser = new TimeParseInfo();
parser.setCharacterEncoding("Cp1047");
parser.setForceStringDecoding(true);
final IsoValue<Date> v = parser.parse(1, new byte[]{(byte)242, (byte)241, (byte)243, (byte)244, (byte)245, (byte)246}, 0, null);
Assert.assertEquals("21:34:56", String.format("%TT", v.getValue()));
}
@Test
public void testAmount() throws UnsupportedEncodingException, ParseException {
final AmountParseInfo parser = new AmountParseInfo();
parser.setCharacterEncoding("Cp1047");
parser.setForceStringDecoding(true);
IsoValue<BigDecimal> v = parser.parse(4, new byte[]{(byte)240, (byte)240, (byte)240, (byte)241, (byte)242, (byte)243, (byte)244, (byte)245, (byte)246, (byte)247, (byte)248, (byte)249}, 0, null);
Assert.assertEquals(new BigDecimal("1234567.89"), v.getValue());
}
@Test
public void testMessage() throws ParseException, UnsupportedEncodingException {
final byte[] trama = HexCodec.hexDecode("f1f8f1f42030010002000000f0f0f0f0f0f0f0f1f5f9f5f5f1f3f0f6f1f2f1f1f2f9f0f8f8f3f1f8f0f0");
MessageFactory<IsoMessage> mfact = new MessageFactory<IsoMessage>();
mfact.setUseBinaryBitmap(true);
HashMap<Integer, FieldParseInfo> pinfo = new HashMap<Integer, FieldParseInfo>();
pinfo.put(3, new AlphaParseInfo(6));
pinfo.put(11, new AlphaParseInfo(6));
pinfo.put(12, new AlphaParseInfo(12));
pinfo.put(24, new AlphaParseInfo(3));
pinfo.put(39, new AlphaParseInfo(3));
mfact.setParseMap(0x1814, pinfo);
mfact.setCharacterEncoding("Cp1047");
mfact.setForceStringEncoding(true);
IsoMessage iso = mfact.parseMessage(trama, 0);
Assert.assertNotNull(iso);
Assert.assertEquals("000000", iso.getObjectValue(3));
Assert.assertEquals("015955", iso.getObjectValue(11));
Assert.assertEquals("130612112908", iso.getObjectValue(12));
Assert.assertEquals("831", iso.getObjectValue(24));
Assert.assertEquals("800", iso.getObjectValue(39));
}
}