1f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// =================================================================================================
2f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// ADOBE SYSTEMS INCORPORATED
3f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// Copyright 2006 Adobe Systems Incorporated
4f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// All Rights Reserved
5f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling//
6f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms
7f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// of the Adobe license agreement accompanying it.
8f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling// =================================================================================================
9f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
10f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
11f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
12f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingpackage com.adobe.xmp.impl;
13f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
14f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingimport java.io.ByteArrayInputStream;
15f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingimport java.io.IOException;
16f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingimport java.io.InputStream;
17f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
18f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
19f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling/**
20f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling * Byte buffer container including length of valid data.
21f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling *
22f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling * @since   11.10.2006
23f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling */
24f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberlingpublic class ByteBuffer
25f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling{
26f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/** */
27f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	private byte[] buffer;
28f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/** */
29f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	private int length;
30f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/** */
31f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	private String encoding = null;
32f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
33f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
34f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
35f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param initialCapacity the initial capacity for this buffer
36f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
37f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public ByteBuffer(int initialCapacity)
38f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
39f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.buffer = new byte[initialCapacity];
40f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.length = 0;
41f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
42f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
43f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
44f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
45f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param buffer a byte array that will be wrapped with <code>ByteBuffer</code>.
46f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
47f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public ByteBuffer(byte[] buffer)
48f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
49f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.buffer = buffer;
50f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.length = buffer.length;
51f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
52f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
53f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
54f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
55f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param buffer a byte array that will be wrapped with <code>ByteBuffer</code>.
56f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param length the length of valid bytes in the array
57f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
58f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public ByteBuffer(byte[] buffer, int length)
59f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
60f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		if (length > buffer.length)
61f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
62f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			throw new ArrayIndexOutOfBoundsException("Valid length exceeds the buffer length.");
63f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
64f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.buffer = buffer;
65f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.length = length;
66f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
67f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
68f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
69f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
70f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * Loads the stream into a buffer.
71f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 *
72f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param in an InputStream
73f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @throws IOException If the stream cannot be read.
74f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
75f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public ByteBuffer(InputStream in) throws IOException
76f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
77f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		// load stream into buffer
78f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		int chunk = 16384;
79f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.length = 0;
80f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.buffer = new byte[chunk];
81f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
82f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		int read;
83f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		while ((read = in.read(this.buffer, this.length, chunk)) > 0)
84f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
85f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			this.length += read;
86f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			if (read == chunk)
87f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			{
88f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				ensureCapacity(length + chunk);
89f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			}
90f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			else
91f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			{
92f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				break;
93f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			}
94f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
95f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
96f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
97f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
98f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
99f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param buffer a byte array that will be wrapped with <code>ByteBuffer</code>.
100f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param offset the offset of the provided buffer.
101f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param length the length of valid bytes in the array
102f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
103f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public ByteBuffer(byte[] buffer, int offset, int length)
104f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
105f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		if (length > buffer.length - offset)
106f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
107f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			throw new ArrayIndexOutOfBoundsException("Valid length exceeds the buffer length.");
108f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
109f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.buffer = new byte[length];
110f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		System.arraycopy(buffer, offset, this.buffer, 0, length);
111f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		this.length = length;
112f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
113f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
114f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
115f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
116f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @return Returns a byte stream that is limited to the valid amount of bytes.
117f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
118f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public InputStream getByteStream()
119f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
120f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return new ByteArrayInputStream(buffer, 0, length);
121f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
122f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
123f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
124f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
125f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @return Returns the length, that means the number of valid bytes, of the buffer;
126f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * the inner byte array might be bigger than that.
127f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
128f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public int length()
129f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
130f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return length;
131f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
132f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
133f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
134f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling//	/**
135f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling//	 * <em>Note:</em> Only the byte up to length are valid!
136f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling//	 * @return Returns the inner byte buffer.
137f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling//	 */
138f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling//	public byte[] getBuffer()
139f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling//	{
140f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling//		return buffer;
141f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling//	}
142f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
143f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
144f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
145f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param index the index to retrieve the byte from
146f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @return Returns a byte from the buffer
147f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
148f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public byte byteAt(int index)
149f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
150f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		if (index < length)
151f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
152f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			return buffer[index];
153f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
154f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		else
155f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
156f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			throw new IndexOutOfBoundsException("The index exceeds the valid buffer area");
157f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
158f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
159f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
160f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
161f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
162f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param index the index to retrieve a byte as int or char.
163f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @return Returns a byte from the buffer
164f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
165f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public int charAt(int index)
166f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
167f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		if (index < length)
168f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
169f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			return buffer[index] & 0xFF;
170f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
171f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		else
172f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
173f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			throw new IndexOutOfBoundsException("The index exceeds the valid buffer area");
174f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
175f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
176f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
177f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
178f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
179f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * Appends a byte to the buffer.
180f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param b a byte
181f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
182f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public void append(byte b)
183f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
184f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		ensureCapacity(length + 1);
185f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		buffer[length++] = b;
186f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
187f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
188f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
189f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
190f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * Appends a byte array or part of to the buffer.
191f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 *
192f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param bytes a byte array
193f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param offset an offset with
194f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param len
195f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
196f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public void append(byte[] bytes, int offset, int len)
197f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
198f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		ensureCapacity(length + len);
199f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		System.arraycopy(bytes, offset, buffer, length, len);
200f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		length += len;
201f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
202f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
203f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
204f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
205f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * Append a byte array to the buffer
206f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param bytes a byte array
207f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
208f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public void append(byte[] bytes)
209f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
210f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		append(bytes, 0, bytes.length);
211f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
212f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
213f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
214f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
215f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * Append another buffer to this buffer.
216f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param anotherBuffer another <code>ByteBuffer</code>
217f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
218f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public void append(ByteBuffer anotherBuffer)
219f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
220f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		append(anotherBuffer.buffer, 0, anotherBuffer.length);
221f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
222f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
223f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
224f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
225f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * Detects the encoding of the byte buffer, stores and returns it.
226f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * Only UTF-8, UTF-16LE/BE and UTF-32LE/BE are recognized.
227f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * <em>Note:</em> UTF-32 flavors are not supported by Java, the XML-parser will complain.
228f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 *
229f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @return Returns the encoding string.
230f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
231f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	public String getEncoding()
232f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
233f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		if (encoding == null)
234f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
235f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			// needs four byte at maximum to determine encoding
236f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			if (length < 2)
237f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			{
238f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				// only one byte length must be UTF-8
239f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				encoding = "UTF-8";
240f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			}
241f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			else if (buffer[0] == 0)
242f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			{
243f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				// These cases are:
244f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				//   00 nn -- -- - Big endian UTF-16
245f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				//   00 00 00 nn - Big endian UTF-32
246f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				//   00 00 FE FF - Big endian UTF 32
247f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
248f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				if (length < 4  ||  buffer[1] != 0)
249f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				{
250f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling					encoding =  "UTF-16BE";
251f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				}
252f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				else if ((buffer[2] & 0xFF) == 0xFE  &&  (buffer[3] & 0xFF) == 0xFF)
253f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				{
254f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling					encoding = "UTF-32BE";
255f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				}
256f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				else
257f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				{
258f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling					encoding = "UTF-32";
259f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				}
260f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			}
261f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			else if ((buffer[0] & 0xFF) < 0x80)
262f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			{
263f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				// These cases are:
264f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				//   nn mm -- -- - UTF-8, includes EF BB BF case
265f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				//   nn 00 -- -- - Little endian UTF-16
266f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
267f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				if (buffer[1] != 0)
268f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				{
269f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling					encoding = "UTF-8";
270f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				}
271f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				else if (length < 4  ||  buffer[2] != 0)
272f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				{
273f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling					encoding = "UTF-16LE";
274f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				}
275f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				else
276f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				{
277f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling					encoding = "UTF-32LE";
278f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				}
279f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			}
280f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			else
281f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			{
282f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				// These cases are:
283f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				//   EF BB BF -- - UTF-8
284f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				//   FE FF -- -- - Big endian UTF-16
285f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				//   FF FE 00 00 - Little endian UTF-32
286f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				//   FF FE -- -- - Little endian UTF-16
287f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
288f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				if ((buffer[0] & 0xFF) == 0xEF)
289f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				{
290f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling					encoding = "UTF-8";
291f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				}
292f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				else if ((buffer[0] & 0xFF) == 0xFE)
293f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				{
294f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling					encoding = "UTF-16"; // in fact BE
295f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				}
296f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				else if (length < 4  ||  buffer[2] != 0)
297f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				{
298f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling					encoding = "UTF-16"; // in fact LE
299f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				}
300f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				else
301f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				{
302f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling					encoding = "UTF-32"; // in fact LE
303f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling				}
304f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			}
305f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
306f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
307f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		return encoding;
308f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
309f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
310f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling
311f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	/**
312f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * Ensures the requested capacity by increasing the buffer size when the
313f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * current length is exceeded.
314f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 *
315f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 * @param requestedLength requested new buffer length
316f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	 */
317f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	private void ensureCapacity(int requestedLength)
318f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	{
319f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		if (requestedLength > buffer.length)
320f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		{
321f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			byte[] oldBuf = buffer;
322f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			buffer = new byte[oldBuf.length * 2];
323f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling			System.arraycopy(oldBuf, 0, buffer, 0, oldBuf.length);
324f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling		}
325f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling	}
326f12f744843a67c910ec325fc6dfa73988f67b97cSascha Haeberling}