View on GitHub

tlc.open.java

TLC APIs for reading and writing general purpose buffers and for processing X9.37 files

Download this project as a .zip file Download this project as a tar.gz file

tlc-commons-buffer

Overview

The commons buffer classes provide a set of utilities for easily getting and setting data inside of a buffer, usually of a fixed length. These are typically records received in files from mainframe type systems that are not XML, JSON, or comma-delimited. Each record contains data in fixed positions (columns) in the record.

ByteBuffer

The central class provided here is the ByteBuffer. This class provides read and write methods for a number of different kinds of data type to be placed at fixed displacements and lengths in the buffer.

Because data received from IBM systems is often EBCDIC instead of ASCII, each buffer is associated with an encoding scheme so that read and writes will get and store the data in the proper encoding. Strings that are written to the buffer that are in UNICODE are converted to the appropriate single-byte ASCII or EBCDIC code. Strings that are read from the buffer will be converted into UNICODE appropriately based on the buffer encoding.

Integer and longs that are stored in binary can be different endian formats. Each buffer is associated with an endian type for storing this binary data in either big or little endian format. When these numbers are written to the buffer, the proper endian structure is maintained. Similarly for reading numbers from the buffer.

ByteArray instances are actually backed by Java NIO ByteBuffers. As such the memory model supported by Java ByteBuffer instances is available, so the actual buffer can be direct or non-direct. Direct buffers are typically off-heap and so give the user access to non-Java allocated memory allowing for larger buffers and processing buffers that are from memory mapped I/O buffers.

See the Javadoc for all the different read and write methods available.

These include:

Examples:

Create new array and initialize to spaces

    byteArray = new ByteArray(200, ByteArray.EBCDIC_CHARSET_NAME);
    assertTrue(byteArray.getLength() == 200);
    byteArray.write(" ", 0);
    assertTrue((byteArray.getArray().value[0] & 0x00ff) == 0x40);

    byteArray = new ByteArray(200, ByteArray.ASCII_CHARSET_NAME);
    assertTrue(byteArray.getLength() == 200);
    byteArray.write(" ", 0);
    assertTrue((byteArray.getArray().value[0] & 0x00ff) == 0x20);
                

Write binary data to array

    byteArray = new ByteArray(200, ByteArray.EBCDIC_CHARSET_NAME);
    byte[] value = {0, 1, 2, 3, 4};
    byteArray.write(value, 0);
    byteArray.write(value, 20);
    ByteArray bytes1 = byteArray.readAsByteArray(0, 5);
    ByteArray bytes2 = byteArray.readAsByteArray(20, 5);
    assertTrue(bytes1.equals(bytes2));
                

Write and read characters from an array into another buffer

    byteArray = new ByteArray(20, ByteArray.EBCDIC_CHARSET_NAME);
    // write "TEST" starting at displacement 10, length 4 (size of string)
    byteArray.write("TEST", 10);
    char[] chars = new char[5];
    // read "EST" into middle three positions of chars
    byteArray.read(11, chars, 1, 3);
    // convert char values to bytes
    byte[] bytes = new byte[5];
    for (int i = 0; i < 5; i++) {
       bytes[i] = (byte) chars[i];
    }
    // create new array
    ByteArray testBA = new ByteArray(bytes);
    // get array into unpacked hex values
    String value = testBA.readPns(0, 5, false);
    // verify ASCII "EST" in middle of five positions
    assertTrue(value.equals("0045535400"));
                

Similar to sample above, but with EBCDIC

    byteArray = new ByteArray(20, ByteArray.EBCDIC_CHARSET_NAME);
    byteArray.write("TEST", 10);
    byte[] bytes = new byte[5];
    byteArray.read(11, bytes, 1, 3);
    ByteArray testBA = new ByteArray(bytes);
    String value = testBA.readPns(0, 5, false);
    assertTrue(value.equals("00C5E2E300"));
                

Read full buffer as String

    byteArray = new ByteArray(200, ByteArray.ASCII_CHARSET_NAME);
    byteArray.write("TEST", 0);
    value = byteArray.readAsString();
    assertTrue(value.length() == 200);
    assertFalse("TEST".equals(value));
    assertTrue("TEST".equals(value.substring(0, 4)));
                

Read value from buffer as String

    byteArray = new ByteArray(200, ByteArray.ASCII_CHARSET_NAME);
    byteArray.write("TEST", 0);
    value = byteArray.readAsString(0, 4);
    assertTrue(value.length() == 4);
    assertTrue("TEST".equals(value));
                

Read and write double

    byteArray = new ByteArray(10);
    byteArray.write(1.5, 0);
    double d = byteArray.readAsDouble(0);
    assertTrue(d == 1.5);

    byteArray = new ByteArray(10, ByteOrder.LITTLE_ENDIAN);
    byteArray.write(1.5, 0);
    double d = byteArray.readAsDouble(0);
    assertTrue(d == 1.5);
                

Read and write int

    byteArray = new ByteArray(10);
    byteArray.write(15, 0);
    int i = byteArray.readAsInt(0);
    assertTrue(i == 15);

    byteArray = new ByteArray(10, ByteOrder.LITTLE_ENDIAN);
    byteArray.write(15, 2);
    int i = byteArray.readAsInt(2);
    assertTrue(i == 15);
                

Read and write long

    byteArray = new ByteArray(10);
    byteArray.write((long) 15, 2);
    long i = byteArray.readAsLong(2);
    assertTrue(i == 15);

    byteArray = new ByteArray(10, ByteOrder.LITTLE_ENDIAN);
    byteArray.write((long) 15, 2);
    long i = byteArray.readAsLong(2);
    assertTrue(i == 15);
                

Setting, testing, and clearing bits

    byte[] ba = new byte[2];
    byteArray = new ByteArray(ba);
    byteArray.setBit(0, (byte) 0x41);
    byteArray.setBit(1, (byte) 0x01);
    assertTrue(byteArray.testBit(0, (byte) 0x01));
    assertTrue(byteArray.testBit(0, (byte) 0x40));
    assertTrue(byteArray.testBit(0, (byte) 0x41));
    assertFalse(byteArray.testBit(0, (byte) 0x02));
    assertFalse(byteArray.testBit(1, (byte) 0x80));
    assertFalse(byteArray.testBit(1, (byte) 0x81));
    assertTrue(byteArray.testBit(1, (byte) 0x01));
    byteArray.clearBit(0, (byte) 0x40);
    assertFalse(byteArray.testBit(0, (byte) 0x40));
                

Write string with trailing null (for C type strings)

    byteArray = new ByteArray(12);
    byteArray.fill((byte) 0xBB);
    // use write with "true" to get null terminated string
    // all extra bytes after string value will be set to null for length of write
    byteArray.write("TEST", 5, 6, true);
    String value = byteArray.readPns(0, 12, false);
    assertTrue(value.equals("BBBBBBBBBB544553540000BB"));

    byteArray.fill((byte) 0xBB);
    // use write with "false" to get space filled string (if string shorter than length)
    // all extra bytes after string value will be set to space for length of write
    byteArray.write("TEST", 5, 6, false);
    value = byteArray.readPns(0, 12, false);
    assertTrue(value.equals("BBBBBBBBBB544553542020BB"));
    // default without "true" or "false" is false
    byteArray.write("TEST", 5, 6);
    value = byteArray.readPns(0, 12, false);
    assertTrue(value.equals("BBBBBBBBBB544553542020BB"));

    // In EBCDIC, so spaces will be X'40'
    byteArray = new ByteArray(12, ByteArray.EBCDIC_CHARSET_NAME);
    byteArray.write("TEST", 5, 6);
    value = byteArray.readPns(0, 12, false);
    assertTrue(value.equals("BBBBBBBBBBE3C5E2E34040BB"));