All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.credibledoc.iso8583packer.asciihex.AsciiLengthPacker Maven / Gradle / Ivy

package com.credibledoc.iso8583packer.asciihex;

import com.credibledoc.iso8583packer.exception.PackerRuntimeException;
import com.credibledoc.iso8583packer.length.LengthPacker;
import com.credibledoc.iso8583packer.message.MsgValue;
import com.credibledoc.iso8583packer.string.StringUtils;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Packs and unpacks {@link MsgValue#getBodyBytes()} length in the ASCII format with fixed lenLength, for example
 * three bytes 30 32 34 decoded as decimal String 024 and int 24.
 * 

* See the * ascii-length-packer.md page. * * @author Kyrylo Semenko */ public class AsciiLengthPacker implements LengthPacker { private static final Charset ISO_88591 = StandardCharsets.ISO_8859_1; private static final char PAD_CHAR_0 = '0'; /** * Contains created instances. Each instance is a Singleton. */ private static final Map instances = new ConcurrentHashMap<>(); /** * How many bytes the {@link MsgValue#getTagBytes()} (optional) and {@link MsgValue#getBodyBytes()} fields * occupy in a packed state. */ private final int numBytes; private AsciiLengthPacker(int numBytes) { this.numBytes = numBytes; } /** * Static factory. Creates and returns singletons. * @param numBytes see {@link #numBytes} * @return Existing instance from {@link #instances} or a new created instance. */ public static AsciiLengthPacker getInstance(int numBytes) { instances.computeIfAbsent(numBytes, k -> new AsciiLengthPacker(numBytes)); return instances.get(numBytes); } @Override public byte[] pack(int bodyBytesLength) { String lenString = Integer.toString(bodyBytesLength); if (lenString.length() > numBytes) { throw new PackerRuntimeException("Cannot pack bodyBytesLength '" + bodyBytesLength + "' to a byte array with length '" + numBytes + "' bytes because the value requires '" + lenString.length() + "' bytes for packing."); } String formattedLength = StringUtils.leftPad(lenString, numBytes, PAD_CHAR_0); byte[] bytes = new byte[numBytes]; for (int i = 0; i < formattedLength.length(); i++) { bytes[i] = (byte) formattedLength.charAt(i); } return bytes; } @Override public int unpack(byte[] messageBytes, int offset) { int availableBytes = messageBytes.length - offset; if (availableBytes < numBytes) { throw new PackerRuntimeException("Required bytes length '" + numBytes + "' is greater than available sourceData length '" + availableBytes + "'"); } byte[] lenBytes = new byte[numBytes]; System.arraycopy(messageBytes, offset, lenBytes, 0, numBytes); String number = new String(lenBytes, ISO_88591); return Integer.parseInt(number); } @Override public int calculateLenLength(byte[] data, int offset) { return numBytes; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy