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.packager; 020 021import org.jpos.iso.Dataset; 022import org.jpos.iso.DatasetFormat; 023import org.jpos.iso.ISODatasetField; 024import org.jpos.iso.ISOComponent; 025import org.jpos.iso.ISODataset; 026import org.jpos.iso.ISOException; 027 028import java.io.IOException; 029import java.io.InputStream; 030 031/** 032 * Special-case packager for DE 055 ICC data, which carries raw BER-TLV without 033 * the standard dataset identifier and length envelope. 034 */ 035public class ICCDataPackager extends DatasetPackager { 036 /** 037 * Creates an ICC data packager. 038 * 039 * @throws ISOException on packager initialization errors 040 */ 041 public ICCDataPackager() throws ISOException { 042 super(); 043 } 044 045 /** 046 * ICC data is encoded as raw BER-TLV, without the standard dataset 047 * identifier and length envelope. 048 * 049 * @return always {@code false} 050 */ 051 @Override 052 public boolean hasDatasetEnvelope() { 053 return false; 054 } 055 056 /** 057 * Packs raw ICC BER-TLV bytes without the standard dataset envelope. 058 * 059 * @param m ICC dataset field 060 * @return packed BER-TLV bytes 061 * @throws ISOException on packing errors 062 */ 063 @Override 064 public byte[] pack(ISOComponent m) throws ISOException { 065 if (!(m instanceof ISODatasetField)) { 066 throw new ISOException("Can't call ICC data packager on " + (m != null ? m.getClass().getName() : "null")); 067 } 068 ISODatasetField field = (ISODatasetField) m; 069 Dataset dataset = field.getDataset(getFieldNumber()); 070 if (dataset == null) { 071 if (field.getDatasets().isEmpty()) { 072 return new byte[0]; 073 } 074 dataset = field.getDatasets().get(0); 075 } 076 if (dataset.getFormat() != DatasetFormat.TLV) { 077 throw new ISOException("ICC data is BER-TLV only"); 078 } 079 return packDatasetContent(dataset); 080 } 081 082 /** 083 * Unpacks raw ICC BER-TLV bytes into a synthetic dataset keyed by the outer field number. 084 * 085 * @param m destination dataset field 086 * @param b BER-TLV bytes 087 * @return number of bytes consumed 088 * @throws ISOException on unpacking errors 089 */ 090 @Override 091 public int unpack(ISOComponent m, byte[] b) throws ISOException { 092 if (!(m instanceof ISODatasetField)) { 093 throw new ISOException("Can't call ICC data packager on " + (m != null ? m.getClass().getName() : "null")); 094 } 095 ISODataset dataset = unpackTLV(getFieldNumber(), b); 096 ((ISODatasetField) m).addDataset(dataset); 097 return b.length; 098 } 099 100 /** 101 * Unpacks raw ICC BER-TLV bytes from a stream. 102 * 103 * @param m destination dataset field 104 * @param in source stream 105 * @throws IOException on stream errors 106 * @throws ISOException on unpacking errors 107 */ 108 @Override 109 public void unpack(ISOComponent m, InputStream in) throws IOException, ISOException { 110 unpack(m, in.readAllBytes()); 111 } 112}