/*
* jPOS Project [http://jpos.org]
* Copyright (C) 2000-2017 jPOS Software SRL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.jpos.fsdpackager;
import java.util.Map;
import org.jpos.fsdpackager.compliance.APCICompliance;
import org.jpos.fsdpackager.compliance.NoCompliance;
import org.jpos.iso.AsciiInterpreter;
import org.jpos.iso.ISOException;
import org.jpos.iso.Interpreter;
public class VariableFieldPackager extends AFSDFieldPackager {
String value;
Byte delimiter;
Interpreter interpreter = AsciiInterpreter.INSTANCE;
private int maxSize = Integer.MAX_VALUE;
int size;
boolean mandatory = false;
private APCICompliance compliance = new NoCompliance();
@Override
public int unpack(byte[] inStream, int offset, Map<String, String> fields) throws ISOException {
boolean delimiterFound = false;
int i = offset;
int lengthTotraverse;
if (maxSize <= inStream.length - offset) // length-offset = remaining
// bytes
lengthTotraverse = maxSize + offset + 1;// to include th delimiter
else
lengthTotraverse = inStream.length;
while (i < lengthTotraverse) { // there is no point traversing to the
// end, if we can we should traverse to
// the maxsize
if (inStream[i] == delimiter.byteValue()) {
delimiterFound = true;
break;
}
i++;
}
if (delimiterFound || i == inStream.length) {
byte[] dest = new byte[i - offset];
if ((i - offset) == 0) {
// Means there is no data and its terminated by delimiter
value = "";
} else if ((i - offset) <= maxSize) {
System.arraycopy(inStream, offset, dest, 0, i - offset);
value = interpreter.uninterpret(dest, 0, i - offset);
} else
throw new ISOException(
String.format("Field size [%d] is greater than max size [%d] of field ", i - offset, maxSize));
} else {
throw new ISOException(String.format("Field [%s]: Delimiter %x not present after max size %d", getName(),
delimiter.byteValue(), maxSize));
}
setValue(value);
return i + 1;
}
@Override
public byte[] pack(Map<String, String> fields) throws ISOException {
if (value == null || value.equals("")) {
// if field is not set, make sure to send the delimiter to indicate
// its presence.
return new byte[] { delimiter.byteValue() };
}
if (value.length() <= maxSize) {
byte[] b = new byte[interpreter.getPackedLength(value.length() + 1)];
interpreter.interpret(value, b, 0);
b[b.length - 1] = delimiter.byteValue();
return b;
}
throw new ISOException(String.format("Size [%d] is greater than maxSize[%d] ", value.length(), maxSize));
}
public VariableFieldPackager(String name, int maxSize, Byte delimiter, Interpreter interpretter) {
this.maxSize = maxSize;
this.interpreter = interpretter;
this.delimiter = delimiter;
this.setName(name);
}
public VariableFieldPackager(String name, int maxSize, Byte delimiter, Interpreter interpretter,
APCICompliance compliance) {
this(name, maxSize, delimiter, interpretter);
this.compliance = compliance;
}
public VariableFieldPackager(String name, Byte delimiter, Interpreter interpretter) {
this.interpreter = interpretter;
this.delimiter = delimiter;
this.setName(name);
}
public VariableFieldPackager(String name, Byte delimiter, Interpreter interpretter, APCICompliance compliance) {
this.interpreter = interpretter;
this.delimiter = delimiter;
this.setName(name);
this.compliance = compliance;
}
public VariableFieldPackager(String name, int maxSize, Byte delimiter, Interpreter interpretter,
boolean mandatory) {
this(name, maxSize, delimiter, interpretter);
this.mandatory = mandatory;
}
@Override
public String getValue() {
// TODO Auto-generated method stub
return value;
}
@Override
public void setValue(String value) {
this.value = value;
// TODO Auto-generated method stub
}
@Override
public String dump(String prefix, Map<String, String> setfields) {
if (getValue()!=null)
return String.format("%s<field id=\"%s\" value=\"%s\"/>%n", prefix, getName(),
compliance.makeCompliant(getValue()));
return "";
}
@Override
public byte[] hexDump(String prefix, Map<String, String> setfields) {
int numberOfPackedBytes = interpreter.getPackedLength(getValue().length());
String compliant = compliance.makeCompliant(getValue());
byte[] temp = new byte[numberOfPackedBytes+1];// +1 for the delimiter
try {
interpreter.interpret(compliant, temp, 0);
temp[temp.length-1]= delimiter.byteValue();
} catch (ISOException e) {
return null;
}
return temp;
}
@Override
public String getParserTree(String prefix) {
return String.format("%sField [%s] : VAR[0..%d] delimiter[0x%X] or EOM %s%n", prefix, getName(),maxSize, delimiter.byteValue(), getValue()==null?"":": "+getValue());
}
}