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 021/** Formats tagged-field headers where tag and length can appear in either order. */ 022public class IsoFieldHeaderFormatter { 023 024 private boolean tagFirst; 025 026 /** Constructs a formatter. 027 * @param tagFirst if true, the tag field comes before the length 028 */ 029 public IsoFieldHeaderFormatter(boolean tagFirst) { 030 this.tagFirst = tagFirst; 031 } 032 033 034 /** Returns whether tag comes before length. 035 * @return true if tag-first ordering 036 */ 037 public boolean isTagFirst() { 038 return tagFirst; 039 } 040 041 /** 042 * 043 * Formats tag/length fields according to the configured ordering. 044 * @param tagPrefixer the tag part prefixer 045 * @param lengthPrefixer the length part prefixer 046 * @param tagData byte array containing the tag value bytes 047 * @param lengthData byte array containing the length value bytes 048 * @return byte array containing the header (tag and length), size of returned bytes is just the header length 049 */ 050 public byte[] format(final Prefixer tagPrefixer, final Prefixer lengthPrefixer, final byte[] tagData, final byte[] lengthData) { 051 if (tagPrefixer != null && lengthPrefixer != null && tagData != null && lengthData != null) { 052 final byte[] destinationData = new byte[tagPrefixer.getPackedLength() + lengthPrefixer.getPackedLength()]; 053 format(tagPrefixer, lengthPrefixer, tagData, lengthData, destinationData); 054 return destinationData; 055 } 056 return null; 057 } 058 059 /** Formats the tag and length prefixers into the output. 060 * @param tagPrefixer the tag length prefixer 061 * @param lengthPrefixer the data length prefixer 062 * @param tagData the tag byte array 063 * @param lengthData the length byte array 064 * @param destinationData the output byte array 065 */ 066 public void format(final Prefixer tagPrefixer, final Prefixer lengthPrefixer, final byte[] tagData, final byte[] lengthData, final byte[] destinationData) { 067 if (tagPrefixer != null && lengthPrefixer != null && tagData != null && lengthData != null && destinationData != null) { 068 System.arraycopy(tagData, 0, destinationData, tagFirst ? 0 : lengthPrefixer.getPackedLength(), tagPrefixer.getPackedLength()); 069 System.arraycopy(lengthData, 0, destinationData, tagFirst ? tagPrefixer.getPackedLength() : 0, lengthPrefixer.getPackedLength()); 070 } 071 } 072 073 /** Returns the index of the tag prefixer relative to length. 074 * @param lengthPrefixer the length prefixer 075 * @return the tag index 076 */ 077 public int getTagIndex(Prefixer lengthPrefixer) { 078 return tagFirst ? 0 : lengthPrefixer.getPackedLength(); 079 } 080 081 /** Returns the index of the length prefixer relative to tag. 082 * @param tagPrefixer the tag prefixer 083 * @return the length index 084 */ 085 public int getLengthIndex(Prefixer tagPrefixer) { 086 return tagFirst ? tagPrefixer.getPackedLength() : 0; 087 } 088 089 /** Formatter with tag before length. */ 090 public static IsoFieldHeaderFormatter TAG_FIRST = new IsoFieldHeaderFormatter(true); 091 /** Formatter with length before tag. */ 092 public static IsoFieldHeaderFormatter LENGTH_FIRST = new IsoFieldHeaderFormatter(false); 093 094 /** 095 * Returns the total length of tag and length fields. 096 * @param tagPrefixer the tag prefixer 097 * @param prefixer the length prefixer 098 * @return total length in bytes 099 */ 100 public int getTotalLength(final Prefixer tagPrefixer, final Prefixer prefixer) { 101 if (tagPrefixer == null || prefixer == null) { 102 throw new IllegalArgumentException("Neither tag or length prefixer was provided."); 103 } 104 return tagPrefixer.getPackedLength() + prefixer.getPackedLength(); 105 } 106}