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 java.util.ArrayList;
022import java.util.List;
023import java.util.Map;
024
025import org.jpos.iso.*;
026import org.xml.sax.Attributes;
027
028/**
029 * This packager is used to package subfields such as field 60 of GICC.
030 */
031public class GICCSubFieldPackager extends GenericPackager implements ISOSubFieldPackager, GenericPackagerParams {
032    private int fieldId = 0;
033
034    /**
035     * Default constructor
036     */
037    public GICCSubFieldPackager() throws ISOException {
038        super();
039    }
040
041    /**
042     * Always return false
043     */
044    protected boolean emitBitMap() {
045        return false;
046    }
047
048    @Override
049    public int getFieldNumber() {
050        return fieldId;
051    }
052
053    @Override
054    public void setGenericPackagerParams(Attributes atts) {
055        super.setGenericPackagerParams(atts);
056        fieldId = Integer.parseInt(atts.getValue("id"));
057    }
058
059    public byte[] pack(ISOComponent c) throws ISOException {
060        try {
061            int len = 0;
062            byte[] result;
063            Map tab = c.getChildren();
064            List list = new ArrayList();
065
066            // Handle first IF_CHAR field
067            ISOField f0 = (ISOField) tab.get(0);
068            if (f0 != null) {
069                String s = (String) f0.getValue();
070                list.add(s.getBytes());
071                len += s.getBytes().length;
072            }
073            for (int i = 1; i < fld.length; i++) {
074                Object obj = tab.get(i);
075                if (obj instanceof ISOComponent) {
076                    ISOComponent f = (ISOComponent) obj;
077                    byte[] b = fld[i].pack(f);
078                    list.add(b);
079                    len += b.length;
080                }
081            }
082
083            result = new byte[len];
084            int k = 0;
085            for (int i = 0; i < list.size(); i++) {
086                byte[] b = (byte[]) list.get(i);
087                for (int j = 0; j < b.length; j++)
088                    result[k++] = b[j];
089            }
090
091            return result;
092        } catch (Exception ex) {
093            throw new ISOException(ex);
094        }
095    }
096
097    public int unpack(ISOComponent m, byte[] b) throws ISOException {
098        // Unpack the IF_CHAR field
099        int consumed = 0;
100        ISOComponent c;
101        if (fld[0] != null && b[consumed] == 0x20) {
102            // Hack to support a nine-byte filler
103            c = fld[0].createComponent(0);
104            consumed += fld[0].unpack(c, b, consumed);
105            m.set(c);
106        }
107
108        // Now unpack the IFEP_LLCHAR fields
109        for (; consumed < b.length; ) {
110            int fieldNumber = Integer.parseInt(ISOUtil.ebcdicToAscii(b,
111              consumed + 3, 2));
112            if (fld[fieldNumber] == null)
113                break;
114            c = fld[fieldNumber].createComponent(fieldNumber);
115            consumed += fld[fieldNumber].unpack(c, b, consumed);
116            m.set(c);
117        }
118
119        return consumed;
120    }
121}
122