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 org.jpos.iso.packager.XMLPackager;
022
023import java.io.*;
024
025/**
026 * implements <b>Leaf</b> for binary fields
027 *
028 * See the
029 * <a href="API_users_guide.html">API User's Guide</a>
030 * for details.
031 *
032 * @author apr@cs.com.uy
033 * @version $Id$
034 * @see ISOComponent
035 */
036public class ISOBinaryField 
037    extends ISOComponent 
038    implements Cloneable, Externalizable
039{
040
041    private static final long serialVersionUID = 7702505828876640372L;
042    /** The ISO field number. */
043    protected int fieldNumber;
044    /** The raw binary value. */
045    protected byte[] value;
046
047    /**
048     * No args constructor 
049     * (required by Externalizable support on ISOMsg)
050     */
051    public ISOBinaryField () {
052        fieldNumber = -1;
053    }
054    /**
055     * Constructs a binary field with the given field number.
056     * @param n - the FieldNumber
057     */
058    public ISOBinaryField(int n) {
059        fieldNumber = n;
060    }
061    /**
062     * Constructs a binary field.
063     * @param n - fieldNumber
064     * @param v - fieldValue
065     */
066    public ISOBinaryField(int n, byte[] v) {
067        fieldNumber = n;
068        value = v;
069    }
070    /**
071     * Constructs a binary field.
072     * @param n - fieldNumber
073     * @param v - fieldValue
074     * @param offset - starting offset
075     * @param len    - field length
076     */
077    public ISOBinaryField(int n, byte[] v, int offset, int len) {
078        byte[] b = new byte[len];
079        System.arraycopy (v, offset, b, 0, len);
080        fieldNumber = n;
081        value = b;
082    }
083    /**
084     * changes this Component field number<br>
085     * Use with care, this method does not change
086     * any reference held by a Composite.
087     * @param fieldNumber new field number
088     */
089    public void setFieldNumber (int fieldNumber) {
090        this.fieldNumber = fieldNumber;
091    }
092
093    @Override
094    public int getFieldNumber () {
095        return fieldNumber;
096    }
097
098    /**
099     * not available on Leaf - always throw ISOException
100     * @exception ISOException on ISO processing error
101     */
102    public byte[] pack() throws ISOException {
103        throw new ISOException ("Not available on Leaf");
104    }
105    /**
106     * not available on Leaf - always throw ISOException
107     * @exception ISOException on ISO processing error
108     */
109    public int unpack(byte[] b) throws ISOException {
110        throw new ISOException ("Not available on Leaf");
111    }
112    /**
113     * not available on Leaf - always throw ISOException
114     * @exception ISOException on ISO processing error
115     */
116    public void unpack(InputStream in) throws ISOException {
117        throw new ISOException ("Not available on Leaf");
118    }
119    /**
120     * @return Object representing this field number
121     */
122    public Object getKey() {
123        return fieldNumber;
124    }
125    /**
126     * @return Object representing this field value
127     */
128    public Object getValue() {
129        return value;
130    }
131    /**
132     * @param obj - Object representing this field value
133     * @exception ISOException on ISO processing error
134     */
135    public void setValue (Object obj) throws ISOException {
136        if (obj instanceof String)
137            value = ((String) obj).getBytes(ISOUtil.CHARSET);
138        else
139            value = (byte[]) obj;
140    }
141    /**
142     * @return byte[] representing this field
143     */
144    public byte[] getBytes() {
145        return value;
146    }
147    /**
148     * dump this field to PrintStream. The output is sorta
149     * XML, intended to be easily parsed.
150     * @param p - print stream
151     * @param indent - optional indent string
152     */
153    public void dump (PrintStream p, String indent) {
154        p.println (indent +"<"+XMLPackager.ISOFIELD_TAG + " " +
155            XMLPackager.ID_ATTR +"=\"" +fieldNumber +"\" "+
156            XMLPackager.VALUE_ATTR +"=\"" +this.toString() + "\" " +
157            XMLPackager.TYPE_ATTR +"=\"" + XMLPackager.TYPE_BINARY + "\"/>"
158        );
159    }
160    public String toString() {
161        return ISOUtil.hexString(value);
162    }
163    public void writeExternal (ObjectOutput out) throws IOException {
164        out.writeShort (fieldNumber);
165        out.writeShort (value.length);
166        out.write (value);
167    }
168    public void readExternal  (ObjectInput in) 
169        throws IOException, ClassNotFoundException
170    {
171        fieldNumber = in.readShort ();
172        value = new byte[in.readShort()];
173        in.readFully (value);
174    }
175}