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;
020import java.io.IOException;
021import java.io.InputStream;
022
023/**
024 * ISOFieldPackager ASCII variable len CHAR 
025 * suitable for GICC subfield 60<br>
026 * <code>
027 * Format LLLTT....
028 * Where LLL is the 3 digit field length
029 *       TT is the 2 digit field number (Tag)
030 *       is the field content   
031 * </code>
032 */
033public class IFEP_LLLCHAR extends ISOFieldPackager {
034    /** Default constructor. */
035    public IFEP_LLLCHAR() {
036        super();
037    }
038    /**
039     * Constructs a packager with the given length and description.
040     * @param len - field len
041     * @param description symbolic descrption
042     */
043    public IFEP_LLLCHAR (int len, String description) {
044        super(len, description);
045    }
046    /**
047     * @param c - a component
048     * @return packed component
049     * @exception ISOException on ISO processing error
050     */
051    public byte[] pack (ISOComponent c) throws ISOException {
052        int len;
053        String s = (String) c.getValue();
054    
055        if ((len=s.length()) > getLength() || len>997)   // paranoia settings
056            throw new ISOException (
057                "invalid len "+len +" packing LLEPCHAR field "
058                +c.getKey()
059            );
060
061        byte[] b = new byte[len + 5];
062        byte[] llltt = 
063            ISOUtil.asciiToEbcdic (
064              ISOUtil.zeropad(Integer.toString(len+2), 3)
065              +ISOUtil.zeropad(c.getKey().toString(), 2));
066        System.arraycopy(llltt, 0, b, 0, 5);
067        System.arraycopy(s.getBytes(), 0, b, 5, len);
068        return b;
069    }
070
071    /**
072     * @param c - the Component to unpack
073     * @param b - binary image
074     * @param offset - starting offset within the binary image
075     * @return consumed bytes
076     * @exception ISOException on ISO processing error
077     */
078    public int unpack (ISOComponent c, byte[] b, int offset)
079        throws ISOException
080    {
081        int len = Integer.parseInt(ISOUtil.ebcdicToAscii(b, offset, 3)) - 2;
082        if (!(c instanceof ISOField))
083            throw new ISOException 
084                (c.getClass().getName() + " is not an ISOField");
085
086        c.setFieldNumber (
087            Integer.parseInt(ISOUtil.ebcdicToAscii (b, offset+3, 2))
088        );
089
090        c.setValue (new String (b, offset+5, len));
091        return len + 5;
092    }
093    public void unpack (ISOComponent c, InputStream in) 
094        throws IOException, ISOException
095    {
096
097        if (!(c instanceof ISOField))
098            throw new ISOException 
099                (c.getClass().getName() + " is not an ISOField");
100
101        int len   = Integer.parseInt(ISOUtil.ebcdicToAscii(readBytes (in, 3))) - 2;
102        int fldno = Integer.parseInt(ISOUtil.ebcdicToAscii(readBytes (in, 2)));
103        c.setFieldNumber (fldno);
104        c.setValue (new String (readBytes (in, len)));
105    }
106
107    public int getMaxPackedLength() {
108        return getLength() + 2;
109    }
110}