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

com.adobe.internal.util.ByteString Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
Show newest version
/*
 *
 *	File: ByteString.java
 *
 *
 *	ADOBE CONFIDENTIAL
 *	___________________
 *
 *	Copyright 2005 Adobe Systems Incorporated
 *	All Rights Reserved.
 *
 *	NOTICE: All information contained herein is, and remains the property of
 *	Adobe Systems Incorporated and its suppliers, if any. The intellectual
 *	and technical concepts contained herein are proprietary to Adobe Systems
 *	Incorporated and its suppliers and may be covered by U.S. and Foreign
 *	Patents, patents in process, and are protected by trade secret or
 *	copyright law. Dissemination of this information or reproduction of this
 *	material is strictly forbidden unless prior written permission is obtained
 *	from Adobe Systems Incorporated.
 *
 */
package com.adobe.internal.util;

import java.io.Serializable;

/**
 * The ByteString class represents strings of bytes.
 *
 */
public class ByteString implements ByteSequence, Comparable, Serializable
{
    /**
     * 
     */
    private static final long serialVersionUID = -7911865041315030524L;

    /**
     * The byte string.
     */
    private byte[] value;
    
    /**
     * Offset in the value array where the byte string starts.
     */
    private int offset;
    
    /**
     * The number of bytes in the byte string.
     */
    private int length;
    
    private int hash = 0;
    
    /**
     * Create a ByteString that represents an empty byte
     * sequence.
     */
    public ByteString()
    {
        this.value = new byte[0];
    }
    
    /**
     * Create a ByteString that represents the same
     * byte sequence as that represented by another ByteString.
     * 
     * @param original ByteString to copy
     */
    public ByteString(ByteString original)
    {
        this.length = original.length;
        if (original.value.length > this.length) 
        {
            // The array representing the ByteString is bigger than the new
            // ByteString itself.  Perhaps this constructor is being called
            // in order to trim the baggage, so make a copy of the array.
            this.value = new byte[this.length];
            System.arraycopy(original.value, original.offset, this.value, 0, this.length);
        } else {
            // The array representing the String is the same
            // size as the String, so no point in making a copy.
            this.value = original.value;
        }
    }
    
    /**
     * Create a ByteString that represents the same
     * byte sequence as that contained in a byte array.  The byte array is
     * copied and so subsequent modification of the byte array does not affect the
     * ByteString.
     * 
     * @param value the initial value of the ByteString
     */
    public ByteString(byte[] value)
    {
        this.length = value.length;
        this.value = new byte[this.length];
        System.arraycopy(value, 0, this.value, 0, this.length);
    }
    
    /**
     * Create a ByteString that represents the same
     * byte sequence as that contained in a subsequence of a byte array.  The 
     * subsequence is copied and so subsequent modification of the byte array 
     * does not affect the ByteString.
     * 
     * @param value the initial value of the ByteString
     * @param offset the offset in the array for the subsequence
     * @param length the length of the subsequence
     */
    public ByteString(byte[] value, int offset, int length)
    {
        checkBounds(value, offset, length);
        
        this.value = new byte[length];
        this.length = length;
        System.arraycopy(value, offset, this.value, 0, this.length);
        
    }
    
    public int hashCode()
    {
        if (this.hash == 0)
        {
            for (int i = 0; i < this.length; i++)
            {
                this.hash = 31 * this.hash + this.value[this.offset + i];
            }
        }
        return this.hash;
    }
    
    /* (non-Javadoc)
     * @see com.adobe.internal.util.ByteSequence#byteAt(int)
     */
    public byte byteAt(int index)
    {
        if ((index < 0) || (index >= this.length)) 
        {
            throw new StringIndexOutOfBoundsException(index);
        }
        return this.value[index + this.offset];
    }
    
    /* (non-Javadoc)
     * @see com.adobe.internal.util.ByteSequence#length()
     */
    public int length()
    {
        return this.length;
    }
    
    public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin)
    {
        try
        {
            System.arraycopy(this.value, this.offset + srcBegin, dst, dstBegin, srcEnd - srcBegin);
        } catch (IndexOutOfBoundsException e) {
            StringIndexOutOfBoundsException newException = new StringIndexOutOfBoundsException();
            newException.initCause(e);
            throw newException;
        }        
    }

    /* (non-Javadoc)
     * @see com.adobe.internal.util.ByteSequence#getBytes()
     */
    public byte[] getBytes()
    {
        byte[] array = new byte[length];
        System.arraycopy(this.value, this.offset, array, 0, this.length);
        return array;
    }
    
    /* (non-Javadoc)
     * @see com.adobe.internal.util.ByteSequence#subSequence(int, int)
     */
    public ByteSequence subSequence(int start, int end)
    {
        return substring(start, end);
    }
    
    /**
     * @param begin
     * @param end
     * @return a substring of this ByteString
     */
    public ByteString substring(int begin, int end)
    {
        if (begin < 0) 
        {
            throw new StringIndexOutOfBoundsException(begin);
        }
        if (end > this.length) 
        {
            throw new StringIndexOutOfBoundsException(end);
        }
        if (begin > end) 
        {
            throw new StringIndexOutOfBoundsException(end - begin);
        }
        return ((begin == 0) && (end == this.length)) ? this :
            new ByteString(this.value, this.offset + begin, end - begin);
    }
    
    public ByteString concat(ByteString byteString)
    {
    	int otherLen = byteString.length();
    	if (otherLen == 0) 
    	{
    	    return this;
    	}
    	byte buf[] = new byte[this.length + otherLen];
    	this.getBytes(0, this.length, buf, 0);
    	byteString.getBytes(0, otherLen, buf, this.length);
    	return new ByteString(buf);
    	
    }
    
    /* (non-Javadoc)
     * @see java.lang.Comparable#compareTo(java.lang.Object)
     */
    public int compareTo(Object otherObject)
    {
        return compareTo((ByteString) otherObject);
    }
    
    public int compareTo(ByteString otherByteString)
    {
        int count = Math.min(this.length, otherByteString.length);
        
        for (int i = 0; i < count; i++)
        {
            byte b1 = this.value[this.offset + i];
            byte b2 = otherByteString.value[otherByteString.offset + i];
            if (b1 != b2)
            {
                return b1 - b2;
            }
        }
        return this.length - otherByteString.length;
    }
    
    public boolean equals(Object otherObject)
    {
        if (this == otherObject)
        {
            return true;
        }
        
        if (otherObject instanceof ByteString)
        {
        	return (this.compareTo((ByteString) otherObject) == 0);
        }
        return false;
    }
    
    /* Common private utility method used to bounds check the byte array
     * and requested offset & length values used by the String(byte[],..)
     * constructors.
     */
    private static void checkBounds(byte[] bytes, int offset, int length) 
    {
        if (length < 0)
        {
            throw new StringIndexOutOfBoundsException(length);
        }
        if (offset < 0)
        {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (offset > bytes.length - length)
        {
            throw new StringIndexOutOfBoundsException(offset + length);
        }
    }
    
    public String toString()
    {
    	return new String(this.value, this.offset, this.length);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy