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 /** Default constructor. */ 034 public IFE_BITMAP() { 035 super(); 036 } 037 /** 038 * Constructs a packager with the given length and description. 039 * @param len - field len 040 * @param description symbolic descrption 041 */ 042 public IFE_BITMAP(int len, String description) { 043 super(len, description); 044 } 045 /** 046 * @param c - a component 047 * @return packed component 048 * @exception ISOException on ISO processing error 049 */ 050 public byte[] pack (ISOComponent c) throws ISOException { 051 BitSet bitMapValue = (BitSet) c.getValue(); 052 int maxBytesPossible = getLength(); 053 int maxBitsAllowedPhysically = maxBytesPossible<<3; 054 int lastBitOn = bitMapValue.length()-1; 055 int actualLastBit=lastBitOn; // takes into consideration 2nd and 3rd bit map flags 056 if (lastBitOn > 128) { 057 if (bitMapValue.get(65)) { 058 actualLastBit = 192; 059 } else { 060 actualLastBit = 128; 061 } 062 } else if (lastBitOn > 64) { 063 actualLastBit = 128; 064 } 065 if (actualLastBit > maxBitsAllowedPhysically) { 066 throw new ISOException ("Bitmap can only hold bits numbered up to " + maxBitsAllowedPhysically + " in the " + 067 getLength() + " bytes available."); 068 } 069 070 int requiredLengthInBytes = (actualLastBit >> 3) + (actualLastBit % 8 > 0 ? 1 : 0); 071 072 int requiredBitMapLengthInBytes; 073 if (requiredLengthInBytes>4 && requiredLengthInBytes<=8) { 074 requiredBitMapLengthInBytes = 8; 075 } 076 else if (requiredLengthInBytes>8 && requiredLengthInBytes<=16) { 077 requiredBitMapLengthInBytes = 16; 078 } 079 else if (requiredLengthInBytes>16 && requiredLengthInBytes<=24) { 080 requiredBitMapLengthInBytes = 24; 081 } 082 else { 083 requiredBitMapLengthInBytes=maxBytesPossible; 084 } 085 086 byte[] b = ISOUtil.bitSet2byte (bitMapValue, requiredBitMapLengthInBytes); 087 return ISOUtil.asciiToEbcdic(ISOUtil.hexString(b).getBytes()); 088 } 089 public int getMaxPackedLength() { 090 return getLength() >> 2; 091 } 092 /** 093 * @param c - the Component to unpack 094 * @param b - binary image 095 * @param offset - starting offset within the binary image 096 * @return consumed bytes 097 * @exception ISOException on ISO processing error 098 */ 099 public int unpack (ISOComponent c, byte[] b, int offset) 100 throws ISOException 101 { 102 int bytes; 103 byte [] b1 = ISOUtil.ebcdicToAsciiBytes (b, offset, getLength()*2 ); 104 BitSet bmap = ISOUtil.hex2BitSet (b1, 0, getLength() << 3); 105 c.setValue(bmap); 106 bytes = b1.length; 107 // check for 2nd bit map indicator 108 if (bytes > 16 && !bmap.get(1)) { 109 bytes = 16; 110 // check for 3rd bit map indicator 111 } else if (bytes > 32 && !bmap.get(65)) { 112 bytes = 32; 113 } 114 return bytes; 115 } 116 public void unpack (ISOComponent c, InputStream in) 117 throws IOException, ISOException 118 { 119 byte [] b1 = ISOUtil.ebcdicToAsciiBytes (readBytes (in, 16), 0, 16); 120 BitSet bmap = ISOUtil.hex2BitSet (new BitSet (64), b1, 0); 121 if (getLength() > 8 && bmap.get (1)) { 122 byte [] b2 = ISOUtil.ebcdicToAsciiBytes (readBytes (in, 16), 0, 16); 123 ISOUtil.hex2BitSet (bmap, b2, 64); 124 } 125 c.setValue(bmap); 126 } 127}