
com.adobe.xmp.impl.ByteBuffer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of verapdf-xmp-core Show documentation
Show all versions of verapdf-xmp-core Show documentation
Core components for the veraPDF PDF/A XMP Parsing and Validation library.
/**
* This file is part of veraPDF PDF/A XMP Library Core, a module of the veraPDF project.
* Copyright (c) 2015, veraPDF Consortium
* All rights reserved.
*
* veraPDF PDF/A XMP Library Core is free software: you can redistribute it and/or modify
* it under the terms of either:
*
* The GNU General public license GPLv3+.
* You should have received a copy of the GNU General Public License
* along with veraPDF PDF/A XMP Library Core as the LICENSE.GPL file in the root of the source
* tree. If not, see http://www.gnu.org/licenses/ or
* https://www.gnu.org/licenses/gpl-3.0.en.html.
*
* The Mozilla Public License MPLv2+.
* You should have received a copy of the Mozilla Public License along with
* veraPDF PDF/A XMP Library Core as the LICENSE.MPL file in the root of the source tree.
* If a copy of the MPL was not distributed with this file, you can obtain one at
* http://mozilla.org/MPL/2.0/.
*/
// =================================================================================================
// ADOBE SYSTEMS INCORPORATED
// Copyright 2006 Adobe Systems Incorporated
// All Rights Reserved
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
// of the Adobe license agreement accompanying it.
// =================================================================================================
package com.adobe.xmp.impl;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Byte buffer container including length of valid data.
*
* @since 11.10.2006
*/
public class ByteBuffer
{
/** */
private byte[] buffer;
/** */
private int length;
/** */
private String encoding = null;
/**
* @param initialCapacity the initial capacity for this buffer
*/
public ByteBuffer(int initialCapacity)
{
this.buffer = new byte[initialCapacity];
this.length = 0;
}
/**
* @param buffer a byte array that will be wrapped with ByteBuffer
.
*/
public ByteBuffer(byte[] buffer)
{
this.buffer = buffer;
this.length = buffer.length;
}
/**
* @param buffer a byte array that will be wrapped with ByteBuffer
.
* @param length the length of valid bytes in the array
*/
public ByteBuffer(byte[] buffer, int length)
{
if (length > buffer.length)
{
throw new ArrayIndexOutOfBoundsException("Valid length exceeds the buffer length.");
}
this.buffer = buffer;
this.length = length;
}
/**
* Loads the stream into a buffer.
*
* @param in an InputStream
* @throws IOException If the stream cannot be read.
*/
public ByteBuffer(InputStream in) throws IOException
{
// load stream into buffer
int chunk = 16384;
this.length = 0;
this.buffer = new byte[chunk];
int read;
while ((read = in.read(this.buffer, this.length, chunk)) > -1)
{
this.length += read;
ensureCapacity(this.length + chunk);
}
}
/**
* @param buffer a byte array that will be wrapped with ByteBuffer
.
* @param offset the offset of the provided buffer.
* @param length the length of valid bytes in the array
*/
public ByteBuffer(byte[] buffer, int offset, int length)
{
if (length > buffer.length - offset)
{
throw new ArrayIndexOutOfBoundsException("Valid length exceeds the buffer length.");
}
this.buffer = new byte[length];
System.arraycopy(buffer, offset, this.buffer, 0, length);
this.length = length;
}
/**
* @return Returns a byte stream that is limited to the valid amount of bytes.
*/
public InputStream getByteStream()
{
return new ByteArrayInputStream(buffer, 0, length);
}
/**
* @return Returns the length, that means the number of valid bytes, of the buffer;
* the inner byte array might be bigger than that.
*/
public int length()
{
return length;
}
// /**
// * Note: Only the byte up to length are valid!
// * @return Returns the inner byte buffer.
// */
// public byte[] getBuffer()
// {
// return buffer;
// }
/**
* @param index the index to retrieve the byte from
* @return Returns a byte from the buffer
*/
public byte byteAt(int index)
{
if (index < length)
{
return buffer[index];
}
else
{
throw new IndexOutOfBoundsException("The index exceeds the valid buffer area");
}
}
/**
* @param index the index to retrieve a byte as int or char.
* @return Returns a byte from the buffer
*/
public int charAt(int index)
{
if (index < length)
{
return buffer[index] & 0xFF;
}
else
{
throw new IndexOutOfBoundsException("The index exceeds the valid buffer area");
}
}
/**
* Appends a byte to the buffer.
* @param b a byte
*/
public void append(byte b)
{
ensureCapacity(length + 1);
buffer[length++] = b;
}
/**
* Appends a byte array or part of to the buffer.
*
* @param bytes a byte array
* @param offset an offset with
* @param len
*/
public void append(byte[] bytes, int offset, int len)
{
ensureCapacity(length + len);
System.arraycopy(bytes, offset, buffer, length, len);
length += len;
}
/**
* Append a byte array to the buffer
* @param bytes a byte array
*/
public void append(byte[] bytes)
{
append(bytes, 0, bytes.length);
}
/**
* Append another buffer to this buffer.
* @param anotherBuffer another ByteBuffer
*/
public void append(ByteBuffer anotherBuffer)
{
append(anotherBuffer.buffer, 0, anotherBuffer.length);
}
/**
* Detects the encoding of the byte buffer, stores and returns it.
* Only UTF-8, UTF-16LE/BE and UTF-32LE/BE are recognized.
* Note: UTF-32 flavors are not supported by Java, the XML-parser will complain.
*
* @return Returns the encoding string.
*/
public String getEncoding()
{
if (encoding == null)
{
// needs four byte at maximum to determine encoding
if (length < 2)
{
// only one byte length must be UTF-8
encoding = "UTF-8";
}
else if (buffer[0] == 0)
{
// These cases are:
// 00 nn -- -- - Big endian UTF-16
// 00 00 00 nn - Big endian UTF-32
// 00 00 FE FF - Big endian UTF 32
if (length < 4 || buffer[1] != 0)
{
encoding = "UTF-16BE";
}
else if ((buffer[2] & 0xFF) == 0xFE && (buffer[3] & 0xFF) == 0xFF)
{
encoding = "UTF-32BE";
}
else
{
encoding = "UTF-32";
}
}
else if ((buffer[0] & 0xFF) < 0x80)
{
// These cases are:
// nn mm -- -- - UTF-8, includes EF BB BF case
// nn 00 -- -- - Little endian UTF-16
if (buffer[1] != 0)
{
encoding = "UTF-8";
}
else if (length < 4 || buffer[2] != 0)
{
encoding = "UTF-16LE";
}
else
{
encoding = "UTF-32LE";
}
}
else
{
// These cases are:
// EF BB BF -- - UTF-8
// FE FF -- -- - Big endian UTF-16
// FF FE 00 00 - Little endian UTF-32
// FF FE -- -- - Little endian UTF-16
if ((buffer[0] & 0xFF) == 0xEF)
{
encoding = "UTF-8";
}
else if ((buffer[0] & 0xFF) == 0xFE)
{
encoding = "UTF-16"; // in fact BE
}
else if (length < 4 || buffer[2] != 0)
{
encoding = "UTF-16"; // in fact LE
}
else
{
encoding = "UTF-32"; // in fact LE
}
}
}
return encoding;
}
/**
* Ensures the requested capacity by increasing the buffer size when the
* current length is exceeded.
*
* @param requestedLength requested new buffer length
*/
private void ensureCapacity(int requestedLength)
{
while (requestedLength > buffer.length)
{
byte[] oldBuf = buffer;
buffer = new byte[oldBuf.length * 2];
System.arraycopy(oldBuf, 0, buffer, 0, oldBuf.length);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy