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; 023import java.util.BitSet; 024 025/** 026 * EBCDIC [unpacked] Bitmap 027 * 028 * @author apr 029 * @see ISOComponent 030 * @see ISOBitMapPackager 031 */ 032public class IFE_BITMAP extends ISOBitMapPackager { 033 public IFE_BITMAP() { 034 super(); 035 } 036 /** 037 * @param len - field len 038 * @param description symbolic descrption 039 */ 040 public IFE_BITMAP(int len, String description) { 041 super(len, description); 042 } 043 /** 044 * @param c - a component 045 * @return packed component 046 * @exception ISOException 047 */ 048 public byte[] pack (ISOComponent c) throws ISOException { 049 BitSet bitMapValue = (BitSet) c.getValue(); 050 int maxBytesPossible = getLength(); 051 int maxBitsAllowedPhysically = maxBytesPossible<<3; 052 int lastBitOn = bitMapValue.length()-1; 053 int actualLastBit=lastBitOn; // takes into consideration 2nd and 3rd bit map flags 054 if (lastBitOn > 128) { 055 if (bitMapValue.get(65)) { 056 actualLastBit = 192; 057 } else { 058 actualLastBit = 128; 059 } 060 } else if (lastBitOn > 64) { 061 actualLastBit = 128; 062 } 063 if (actualLastBit > maxBitsAllowedPhysically) { 064 throw new ISOException ("Bitmap can only hold bits numbered up to " + maxBitsAllowedPhysically + " in the " + 065 getLength() + " bytes available."); 066 } 067 068 int requiredLengthInBytes = (actualLastBit >> 3) + (actualLastBit % 8 > 0 ? 1 : 0); 069 070 int requiredBitMapLengthInBytes; 071 if (requiredLengthInBytes>4 && requiredLengthInBytes<=8) { 072 requiredBitMapLengthInBytes = 8; 073 } 074 else if (requiredLengthInBytes>8 && requiredLengthInBytes<=16) { 075 requiredBitMapLengthInBytes = 16; 076 } 077 else if (requiredLengthInBytes>16 && requiredLengthInBytes<=24) { 078 requiredBitMapLengthInBytes = 24; 079 } 080 else { 081 requiredBitMapLengthInBytes=maxBytesPossible; 082 } 083 084 byte[] b = ISOUtil.bitSet2byte (bitMapValue, requiredBitMapLengthInBytes); 085 return ISOUtil.asciiToEbcdic(ISOUtil.hexString(b).getBytes()); 086 } 087 public int getMaxPackedLength() { 088 return getLength() >> 2; 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 { 100 int bytes; 101 byte [] b1 = ISOUtil.ebcdicToAsciiBytes (b, offset, getLength()*2 ); 102 BitSet bmap = ISOUtil.hex2BitSet (b1, 0, getLength() << 3); 103 c.setValue(bmap); 104 bytes = b1.length; 105 // check for 2nd bit map indicator 106 if (bytes > 16 && !bmap.get(1)) { 107 bytes = 16; 108 // check for 3rd bit map indicator 109 } else if (bytes > 32 && !bmap.get(65)) { 110 bytes = 32; 111 } 112 return bytes; 113 } 114 public void unpack (ISOComponent c, InputStream in) 115 throws IOException, ISOException 116 { 117 byte [] b1 = ISOUtil.ebcdicToAsciiBytes (readBytes (in, 16), 0, 16); 118 BitSet bmap = ISOUtil.hex2BitSet (new BitSet (64), b1, 0); 119 if (getLength() > 8 && bmap.get (1)) { 120 byte [] b2 = ISOUtil.ebcdicToAsciiBytes (readBytes (in, 16), 0, 16); 121 ISOUtil.hex2BitSet (bmap, b2, 64); 122 } 123 c.setValue(bmap); 124 } 125}