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; 020 021import java.io.IOException; 022import java.io.InputStream; 023 024/** 025 * Uses a 2 EBCDIC byte length field. 026 * 027 * right-justified with leading 0 028 * and packed data as BCD. 2 BCD digits 029 * per byte and adding the value hex(0xF) 030 * for padding if length is odd. 031 * 032 * @author julien.moebs@paybox.net 033 * @author doronf@xor-t.com 034 * @version $Id$ 035 * @see ISOFieldPackager 036 * @see ISOComponent 037 */ 038public class IFEB_LLNUM extends ISOFieldPackager { 039 public IFEB_LLNUM () { 040 super(); 041 } 042 /** 043 * @param len - field len 044 * @param description symbolic descrption 045 */ 046 public IFEB_LLNUM (int len, String description) { 047 super(len, description); 048 } 049 /** 050 * @param c - a component 051 * @return packed component 052 * @exception ISOException 053 */ 054 public byte[] pack(ISOComponent c) throws ISOException { 055 boolean odd = false; 056 int len; 057 String s = (String) c.getValue(); 058 059 if ((len=s.length()) > getLength() || len>99) // paranoia settings 060 throw new ISOException( 061 "invalid len "+len +" packing IFEB_LLNUM field "+ c.getKey()); 062 063 // if odd length 064 if ( len%2 ==1 ) { 065 odd = true; 066 len = len/2 +1; 067 } else { 068 odd = false; 069 len = len/2; 070 } 071 072 String fieldLength = ISOUtil.zeropad(Integer.toString(len), 2); 073 074 byte [] EBCDIClength = ISOUtil.asciiToEbcdic(fieldLength); 075 076 // bcd stuff 077 byte[] bcd = ISOUtil.str2bcd(s, false); 078 079 if(odd) 080 bcd[len-1] = (byte) (bcd[len-1] | 0xf); 081 082 byte[] b = new byte[bcd.length + 2]; 083 084 b[0] = EBCDIClength[0]; 085 b[1] = EBCDIClength[1]; 086 System.arraycopy(bcd, 0, b, 2, bcd.length); 087 088 return b; 089 } 090 /** 091 * @param c - the Component to unpack 092 * @param b - binary image 093 * @param offset - starting offset within the binary image 094 * @return consumed bytes 095 * @exception ISOException 096 */ 097 public int unpack(ISOComponent c, byte[] b, int offset) 098 throws ISOException { 099 boolean pad = false; 100 int len = (b[offset] & 0x0f) * 10 + (b[offset+1] & 0x0f); 101 int tempLen = len*2; 102 103 // odd handling 104 byte lastByte = b[offset+2+len-1]; 105 106 if((lastByte & 0x0f) == 0x0f) 107 tempLen--; 108 109 c.setValue(ISOUtil.bcd2str(b, offset+2, tempLen, pad)); 110 111 return len+2; 112 } 113 114 /* 115 * code contributed by doronf@xor-t.com 116 */ 117 public void unpack (ISOComponent c, InputStream in) 118 throws IOException, ISOException 119 { 120 byte[] b = readBytes (in, 2); 121 int len = 122 100 * (((b[0] >> 4 & 0x0F) > 0x09 ? 0 : 123 b[0] >> 4 & 0x0F) * 10 + (b[0] & 0x0F)) 124 + ((b[1] >> 4 & 0x0F) > 0x09 ? 0 : 125 b[1] >> 4 & 0x0F) * 10 + (b[1] & 0x0F); 126 c.setValue (ISOUtil.bcd2str (readBytes (in, len), 0, 2*len, pad)); 127 } 128 129 public int getMaxPackedLength() { 130 return getLength()+2; 131 } 132}