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.iso; 020import org.jpos.iso.packager.GenericPackagerParams; 021import org.xml.sax.Attributes; 022 023import java.io.IOException; 024import java.io.InputStream; 025 026/** EBCDIC LLLVAR binary field packager with a two-byte tag header. */ 027public class IFEP_LLLBINARY extends ISOBinaryFieldPackager implements GenericPackagerParams { 028 Integer fieldId = null; 029 030 private static final int TAG_HEADER_LENGTH = 2; 031 private final int prefixerPackedLength; 032 033 /** Default constructor. */ 034 public IFEP_LLLBINARY() { 035 super(); 036 prefixerPackedLength = 3; 037 } 038 039 /** 040 * Constructs a packager with the given length and description. 041 * @param length field length 042 * @param description field description 043 */ 044 public IFEP_LLLBINARY(int length, String description) { 045 super(length, description, LiteralBinaryInterpreter.INSTANCE, EbcdicPrefixer.LLL); 046 checkLength(length, 999); 047 prefixerPackedLength = EbcdicPrefixer.LLL.getPackedLength(); 048 } 049 050 /** 051 * Constructs a packager with custom interpreter and prefixer. 052 * @param length field length 053 * @param description field description 054 * @param binaryInterpreter binary interpreter 055 * @param prefixer length prefixer 056 */ 057 public IFEP_LLLBINARY(int length, String description, BinaryInterpreter binaryInterpreter, Prefixer prefixer) { 058 super(length, description, binaryInterpreter, prefixer); 059 checkLength(length, 999); 060 prefixerPackedLength = prefixer.getPackedLength(); 061 } 062 063 @Override 064 public void setGenericPackagerParams(Attributes atts) { 065 fieldId = Integer.parseInt(atts.getValue("id")); 066 } 067 068 /** 069 * @param c - a component 070 * @return packed component 071 * @exception ISOException on ISO processing error 072 */ 073 public byte[] pack (ISOComponent c) throws ISOException { 074 int len = ((byte[]) c.getValue()).length; 075 String key = fieldId != null ? fieldId.toString() : c.getKey().toString(); 076 if (len > getLength()) 077 throw new ISOException ( 078 "invalid len "+len +" packing IFEP_LLLBINARY field " 079 +c.getKey().toString() 080 ); 081 082 byte[] b = new byte[len + prefixerPackedLength + TAG_HEADER_LENGTH]; 083 byte[] llltt = 084 ISOUtil.asciiToEbcdic ( 085 ISOUtil.zeropad(Integer.toString(len+ TAG_HEADER_LENGTH), prefixerPackedLength) 086 +ISOUtil.zeropad(key, TAG_HEADER_LENGTH)); 087 088 System.arraycopy(llltt, 0, b, 0, TAG_HEADER_LENGTH + prefixerPackedLength); 089 System.arraycopy(c.getValue(), 0, b, TAG_HEADER_LENGTH + prefixerPackedLength, len); 090 return b; 091 } 092 093 /** 094 * @param c - the Component to unpack 095 * @param b - binary image 096 * @param offset - starting offset within the binary image 097 * @return consumed bytes 098 * @exception ISOException on ISO processing error 099 */ 100 public int unpack (ISOComponent c, byte[] b, int offset) 101 throws ISOException 102 { 103 int len = Integer.parseInt(ISOUtil.ebcdicToAscii(b, offset, prefixerPackedLength)) - TAG_HEADER_LENGTH; 104 if (!(c instanceof ISOBinaryField)) 105 throw new ISOException 106 (c.getClass().getName() + " is not an ISOBinaryField"); 107 108 c.setFieldNumber ( 109 Integer.parseInt(ISOUtil.ebcdicToAscii (b, offset+prefixerPackedLength, TAG_HEADER_LENGTH)) 110 ); 111 byte[] value = new byte[len]; 112 System.arraycopy(b, offset + prefixerPackedLength + TAG_HEADER_LENGTH , value, 0, len); 113 c.setValue (value); 114 return len + prefixerPackedLength + TAG_HEADER_LENGTH; 115 } 116 public void unpack (ISOComponent c, InputStream in) 117 throws IOException, ISOException 118 { 119 120 if (!(c instanceof ISOField)) 121 throw new ISOException 122 (c.getClass().getName() + " is not an ISOField"); 123 124 int len = Integer.parseInt(ISOUtil.ebcdicToAscii(readBytes (in, prefixerPackedLength))) - TAG_HEADER_LENGTH; 125 int fldno = Integer.parseInt(ISOUtil.ebcdicToAscii(readBytes (in, TAG_HEADER_LENGTH))); 126 c.setFieldNumber (fldno); 127 c.setValue (readBytes(in, len)); 128 } 129 public int getMaxPackedLength() { 130 return getLength() + prefixerPackedLength + TAG_HEADER_LENGTH; 131 } 132}