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

com.crankuptheamps.client.fields.Field Maven / Gradle / Ivy

////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2010-2021 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.fields;

import java.nio.charset.StandardCharsets;

/**
 * Base class for the different types of field data that make up a
 * {@link com.crankuptheamps.client.Message}.
 * Implemented with byte array and int offset and length primitives to maximize
 * heap efficiency of cloning, reads, updates, and comparisons.
 */
public class Field
{
    public byte[] buffer   = null;
    public int    position = 0;
    public int    length   = 0;

    /**
     * Default constructor.
     */
    public Field()
    {
    }

    /**
     * Constructs an instance with the bytes of the specified string value. The string is interpreted as the 
     * UTF-8 representation.
     * @param value The string to be converted into UTF-8 bytes.
     */
    public Field(String value)
    {
        byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
        this.buffer = bytes;
        this.position = 0;
        this.length = buffer.length;
    }

    /**
     * Constructs an instance with the specified region of a byte buffer. Note: the bytes are not copied 
     * from the buffer. The specified buffer region is referenced by this instance.
     * @param buffer The byte buffer.
     * @param position The starting positon of the value in the byte buffer.
     * @param length The length from the starting position of the value in the byte buffer.
     */
    public Field(byte[] buffer, int position, int length)
    {
        set(buffer, position, length);
    }

    /**
     * Sets the value of this instance with the specified region of a byte buffer. Note: the bytes are not 
     * copied from the buffer. The specified buffer region is referenced by this instance.
     * @param buffer The byte buffer.
     * @param position The starting positon of the value in the byte buffer.
     * @param length The length from the starting position of the value in the byte buffer.
     */
    public final void set(byte[] buffer,int position,int length)
    {
        this.buffer   = buffer;
        this.position = position;
        this.length   = length;
    }

    /**
     * Sets the value of this instance with the specified buffer. Note: the bytes are not copied 
     * from the buffer. The buffer is referenced by this instance.
     * @param buffer The byte buffer to be copied.
     */
    public void set(byte[] buffer)
    {
        this.buffer   = buffer;
        this.position = 0;
        this.length   = buffer.length;
    }

    /**
     * Indicates whether this instance's value is null.
     * @return True if null, false if not.
     */
    public boolean isNull()
    {
        return this.buffer == null || this.length == 0;
    }

    /** 
     * Resets the value of this instance to null.
     */
    public void reset()
    {
        this.buffer   = null;
        this.length   = 0;
    }

    /**
     * Returns the byte at {@link #position} plus index i.
     * @param i The given index.
     * @return The specified byte.
     */
    public byte byteAt(int i)
    {
        return this.buffer[this.position + i];
    }

    /**
     * Default implementation of {@link Object#hashCode} for a Field.
     */
    public int hashCode()
    {
        // for large sets of short, similar byte sequences this can produce lots of collision
        int result = 0;
        for(int i = 0; i < length; i++)
        {
            result += buffer[position+i];
        }
        return result;
    }

    /**
     * Default implementation for {@link Object#equals} for a Field. For two Fields to be considered equal,
     * their values must have the same length and all bytes in the value must be equal.
     * @param obj The object to compare this with.
     */
    public boolean equals(Object obj)
    {
        if(obj == null || !(obj instanceof Field))
        {
            return false;
        }
        Field o = (Field)obj;
        if(o.length != length) return false;
        for(int i=0; i< length; i++)
        {
            if(o.buffer[o.position+i] != buffer[position+i]) return false;
        }
        return true;
    }

    /**
     * Constructs a new Field and sets its value to a deep copy of this instance. 
     * @return The new deep copy of this instance.
     */
    public Field copy()
    {
        byte[] copy = null;
        if (buffer != null) {
            copy = new byte[length];
            System.arraycopy(buffer, position, copy, 0, length);
        }
        return new Field(copy, 0, length);
    }

    /**
     * Converts the value to a string representation where each byte is interpreted as a Java character.
     * @return The Java string. 
     */
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        for(int i = position; i < position + length; i++)
        {
            sb.append((char)buffer[i]);
        }
        return sb.toString();
    }

    /**
     * Sets the value of this instance to a deep copy of the value of the specified field.
     * @param f The Field to copy from.
     */
    public void copyFrom(Field f) {
        if (buffer == null || f.length > buffer.length) {
            buffer = new byte[f.length];
        }
        System.arraycopy(f.buffer, f.position, buffer, 0, f.length);
        position = 0;
        length = f.length;
    }


}






© 2015 - 2024 Weber Informatics LLC | Privacy Policy