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

com.crankuptheamps.client.FIXBuilder Maven / Gradle / Ivy

////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2010-2022 60East Technologies Inc., All Rights Reserved.
//
// This computer software is owned by 60East Technologies Inc. and is
// protected by U.S. copyright laws and other laws and by international
// treaties.  This computer software is furnished by 60East Technologies
// Inc. pursuant to a written license agreement and may be used, copied,
// transmitted, and stored only in accordance with the terms of such
// license agreement and with the inclusion of the above copyright notice.
// This computer software or any other copies thereof may not be provided
// or otherwise made available to any other person.
//
// U.S. Government Restricted Rights.  This computer software: (a) was
// developed at private expense and is in all respects the proprietary
// information of 60East Technologies Inc.; (b) was not developed with
// government funds; (c) is a trade secret of 60East Technologies Inc.
// for all purposes of the Freedom of Information Act; and (d) is a
// commercial item and thus, pursuant to Section 12.212 of the Federal
// Acquisition Regulations (FAR) and DFAR Supplement Section 227.7202,
// Government's use, duplication or disclosure of the computer software
// is subject to the restrictions set forth by 60East Technologies Inc..
//
////////////////////////////////////////////////////////////////////////////

package com.crankuptheamps.client;

import java.nio.charset.StandardCharsets;
import com.crankuptheamps.client.exception.CommandException;

/**
 * Used to build up message strings for FIX.
 */

public class FIXBuilder
{
    /**
     * We'll repeatedly double capacity when growth is required.
     * Starting at less than zero doesn't work,
     * capacity won't initialize to anything less than this value.
     */
    private static final int MIN_CAPACITY = 8;

    private byte[] _buffer   = null;
    private int    _size     = 0;
    private int    _capacity = 1024;
    private final byte   _fieldSeparator;

    public FIXBuilder(int capacity, byte fieldSeparator)
    {
        _fieldSeparator = fieldSeparator;
        _capacity = capacity < MIN_CAPACITY ? MIN_CAPACITY : capacity;
        _buffer = new byte[_capacity];
    }

    /**
     *  Clears self.
     */
    public void clear()
    {
        _size = 0;
    }

    /**
     * Returns the number of bytes in the byte array containing the FIX message.
     *
     * @return Number of valid bytes in the byte array.
     */
    public int getSize()
    {
        return _size;
    }

    /**
     * Returns the byte array containing the FIX message. The number of valid
     * bytes within the buffer is returned from getSize().
     *
     * @return Byte array containing the FIX message.
     */
    public byte[] getBytes()
    {
        return _buffer;
    }

    private int ruLog10(int tag)
    {
        long scalar = 10;
        for (int j = 1; j < 20; ++j)
        {
            if(tag < scalar)
            {
                return j;
            }
            scalar = scalar * 10;
        }
        return 0;
    }

    private void checkCapacity(int bytesNeeded)
    {
        if(_capacity - _size < bytesNeeded)
        {
            // Not enough capacity left, must resize
            while (_capacity - _size < bytesNeeded)
            {
                _capacity = _capacity * 2;
            }

            byte[] newbuf = new byte[_capacity];
            System.arraycopy(_buffer, 0, newbuf, 0, _size);

            _buffer = newbuf;
        }
    }

    /**
     * Appends a tag and and value pair contained within a byte buffer to the FIX message.
     *
     * @param tag
     *           The integer FIX tag to append.
     * @param value
     *           The byte buffer containing the FIX value to append.
     * @param offset
     *           The starting location of the value inside the byte buffer.
     * @param length
     *           The length of the value inside the byte buffer.
     * @throws IllegalArgumentException
     *           If the tag argument is negative.
     * @throws CommandException not thrown, throws {@link IllegalArgumentException}
     * @return
     *           A reference to this object.
     */
    public FIXBuilder append(int tag, byte[] value, int offset, int length)
    throws CommandException
    {
        if(tag < 0)
            throw new IllegalArgumentException("negative tag used in FIXBuilder");

        int tagSize = ruLog10(tag);
        int sizeNeeded = tagSize + length + 2;
        checkCapacity(sizeNeeded);

        // Tag
        int writeIndex = _size + tagSize;
        for (int j = 1; j <= tagSize; ++j)
        {
            _buffer[writeIndex - j] = (byte) (48 + (tag % 10));
            tag = tag / 10;
        }

        // Equal sign
        _buffer[writeIndex] = '=';
        ++writeIndex;

        // value
        System.arraycopy(value, offset, _buffer, writeIndex, length);
        writeIndex += length;

        _buffer[writeIndex] = _fieldSeparator;
        _size += sizeNeeded;
        return this;
    }

    /**
     * Appends a tag and value  pair to contained within a byte buffer to the FIX message.
     * @param tag The integer FIX to append.
     * @param value The byte buffer containing the FIX value to append.
     * @return A reference to this object.
     * @throws CommandException error occurred while appending the tag and value to the message
     */
    public FIXBuilder append(int tag, byte[] value) throws CommandException
    {
        return append(tag, value, 0, value.length);
    }


    /**
     * Appends a tag and value pair to the FIX message.
     *
     * @param tag
     *           The integer FIX tag to append.
     * @param value
     *           The FIX value for the tag to append. The value will be converted
     *           to an ISO-8859-1 byte array for writing.
     * @throws IllegalArgumentException
     *            If the tag argument is negative.
     * @throws CommandException
     *            If the tag or value argument is not convertible to ISO-8859-1
     * @return A reference to this object.
     */
    public FIXBuilder append(int tag, String value) throws CommandException
    {
        return append(tag, toBytes(value));
    }

    // Private methods

    private static byte[] toBytes(final String datum)
    {
        return datum.getBytes(StandardCharsets.ISO_8859_1);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy