001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2026 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.tlv.packager; 020 021import org.jpos.iso.ISOComponent; 022import org.jpos.iso.ISOException; 023import org.jpos.iso.ISOField; 024import org.jpos.iso.ISOFieldPackager; 025import org.jpos.iso.TaggedFieldPackager; 026 027import java.io.IOException; 028import java.io.InputStream; 029import java.nio.ByteBuffer; 030 031/** 032 * Field Separator Terminated packager 033 * 034 * @author Vishnu Pillai 035 */ 036public class IF_FSTBINARY extends ISOFieldPackager implements TaggedFieldPackager { 037 038 private byte terminator = (byte) 0xFF; 039 private String token; 040 041 public IF_FSTBINARY() { 042 super(); 043 } 044 045 @Override 046 public void setToken(String token) { 047 if (token == null || token.length() != 2) { 048 throw new IllegalArgumentException("IF_FSTBINARY needs a HEX token of 2 characters."); 049 } 050 this.token = token; 051 this.terminator = (byte) Integer.parseInt(token, 16); 052 } 053 054 @Override 055 public String getToken() { 056 return token; 057 } 058 059 /** 060 * @param len - field len 061 * @param description symbolic descrption 062 */ 063 public IF_FSTBINARY(int len, String description) { 064 super(len, description); 065 } 066 067 /** 068 * @param c - a component 069 * @return packed component 070 * @throws org.jpos.iso.ISOException 071 */ 072 public byte[] pack(ISOComponent c) throws ISOException { 073 int len; 074 byte[] s = c.getBytes(); 075 076 if ((len = s.length) > getLength()) { 077 throw new ISOException( 078 "Invalid length " + len + " packing IF_FSTBINARY field " 079 + c.getKey() + " max length=" + getLength() 080 ); 081 } 082 byte[] b = new byte[s.length + 1]; 083 System.arraycopy(s, 0, b, 0, s.length); 084 b[b.length - 2] = terminator; 085 return b; 086 } 087 088 /** 089 * @param c - the Component to unpack 090 * @param b - binary image 091 * @param offset - starting offset within the binary image 092 * @return consumed bytes 093 * @throws org.jpos.iso.ISOException 094 */ 095 public int unpack(ISOComponent c, byte[] b, int offset) 096 throws ISOException { 097 if (!(c instanceof ISOField)) 098 throw new ISOException 099 (c.getClass().getName() + " is not an ISOField"); 100 int length = -1; 101 for (int i = 0; i < getMaxPackedLength(); i++) { 102 byte dataByte = b[offset + i]; 103 if (dataByte == terminator) { 104 length = i; 105 break; 106 } 107 } 108 if (length >= 0) { 109 byte[] value = new byte[length]; 110 System.arraycopy(b, offset, value, 0, length); 111 c.setValue(value); 112 return length + 1; 113 } else { 114 throw new ISOException("Terminating Backslash does not exist"); 115 } 116 } 117 118 public void unpack(ISOComponent c, InputStream in) 119 throws IOException, ISOException { 120 121 if (!(c instanceof ISOField)) 122 throw new ISOException 123 (c.getClass().getName() + " is not an ISOField"); 124 125 boolean endFound = false; 126 if (in.markSupported()) { 127 in.mark(getMaxPackedLength()); 128 } 129 ByteBuffer buf = ByteBuffer.allocate(getMaxPackedLength()); 130 131 for (int i = 0; i < getMaxPackedLength() && in.available() > 0; i++) { 132 byte dataByte = (byte) in.read(); 133 if (dataByte == terminator) { 134 endFound = true; 135 break; 136 } else { 137 buf.put(dataByte); 138 } 139 } 140 if (endFound) { 141 byte[] data = byteBufferToBytes(buf); 142 c.setValue(data); 143 } else { 144 if (in.markSupported()) { 145 in.reset(); 146 } 147 throw new ISOException("Terminating Backslash does not exist"); 148 } 149 } 150 151 private byte[] byteBufferToBytes(ByteBuffer buffer) { 152 int dataLength = buffer.position(); 153 byte[] bytes = new byte[dataLength]; 154 buffer.position(0); 155 buffer.get(bytes); 156 buffer.position(dataLength); 157 return bytes; 158 } 159 160 public int getMaxPackedLength() { 161 return getLength() + 1; 162 } 163} 164