Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 1ea8f7733a49c156190f30fba66b6f85a23f9a64 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/*******************************************************************************
 * Copyright (c) 2002, 2008 QNX Software Systems and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * QNX Software Systems - Initial API and implementation
 *******************************************************************************/

package org.eclipse.cdt.internal.core.util;

/**
 * The <code>CharArrayBuffer</code> is intended as a lightweight partial
 * implementation of the StringBuffer class, but using <code>char[]'s</code>
 * instead of Strings.
 * 
 * <p>
 * The <code>CharArrayBuffer</code> maintains a list of <code>char[]'s</code>
 * which don't get appended until the user asks for them. The following code
 * illustrates how to use the class.
 * 
 * <code>
 * CharArrayBuffer buffer = new CharArrayBuffer(myCharArray);
 * buffer.append(moreBytes, 0, someLength);
 * myCharArray = buffer.getContents();
 * </code>
 * 
 * <p>
 * NOTE: This class is not Thread safe!
 */
public class CharArrayBuffer {
	/**
	 * This is the buffer of char arrays which must be appended together during
	 * the getContents method.
	 */
	protected char[][] fBuffer;

	/**
	 * The default buffer size.
	 */
	public static final int DEFAULT_BUFFER_SIZE = 10;

	/**
	 * The end of the buffer
	 */
	protected int fEnd;

	/**
	 * The current size of the buffer.
	 */
	protected int fSize;

	/**
	 * A buffer of ranges which is maintained along with the buffer. Ranges are
	 * of the form {start, length}. Enables append(char[] array, int start, int
	 * end).
	 */
	protected int[][] fRanges;

	/**
	 * Creates a <code>CharArrayBuffer</code> with the default buffer size
	 * (10).
	 */
	public CharArrayBuffer() {
		this(null, DEFAULT_BUFFER_SIZE);
	}

	/**
	 * Creates a <code>CharArrayBuffer</code> with the default buffer size,
	 * and sets the first element in the buffer to be the given char[].
	 * 
	 * @param first -
	 *            the first element to be placed in the buffer, ignored if null
	 */
	public CharArrayBuffer(char[] first) {
		this(first, DEFAULT_BUFFER_SIZE);
	}

	/**
	 * Creates a <code>CharArrayBuffer</code> with the given buffer size, and
	 * sets the first element in the buffer to be the given char array.
	 * 
	 * @param first -
	 *            the first element of the buffer, ignored if null.
	 * @param size -
	 *            the buffer size, if less than 1, set to the
	 *            DEFAULT_BUFFER_SIZE.
	 */
	public CharArrayBuffer(char[] first, int size) {
		fSize = (size > 0) ? size : DEFAULT_BUFFER_SIZE;
		fBuffer = new char[fSize][];
		fRanges = new int[fSize][];
		fEnd = 0;
		if (first != null)
			append(first, 0, first.length);
	}

	/**
	 * Creates a <code>CharArrayBuffer</code> with the given buffer size.
	 * 
	 * @param size -
	 *            the size of the buffer.
	 */
	public CharArrayBuffer(int size) {
		this(null, size);
	}

	/**
	 * Appends the entire given char array. Given for convenience.
	 * 
	 * @param src -
	 *            a char array which is appended to the end of the buffer.
	 */
	public CharArrayBuffer append(char[] src) {
		if (src != null)
			append(src, 0, src.length);
		return this;
	}

	/**
	 * Appends a sub array of the given array to the buffer.
	 * 
	 * @param src -
	 *            the next array of characters to be appended to the buffer,
	 *            ignored if null
	 * @param start -
	 *            the start index in the src array.
	 * @param length -
	 *            the number of characters from start to be appended
	 * 
	 * @throws ArrayIndexOutOfBoundsException -
	 *             if arguments specify an array index out of bounds.
	 */
	public CharArrayBuffer append(char[] src, int start, int length) {
		if (start < 0)
			throw new ArrayIndexOutOfBoundsException();
		if (length < 0)
			throw new ArrayIndexOutOfBoundsException();
		if (src != null) {
			int srcLength = src.length;
			if (start > srcLength)
				throw new ArrayIndexOutOfBoundsException();
			if (length + start > srcLength)
				throw new ArrayIndexOutOfBoundsException();
			/** do length check here to allow exceptions to be thrown */
			if (length > 0) {
				if (fEnd == fSize) {
					int size2 = fSize * 2;
					System.arraycopy(fBuffer, 0, (fBuffer = new char[size2][]),
							0, fSize);
					System.arraycopy(fRanges, 0, (fRanges = new int[size2][]),
							0, fSize);
					fSize *= 2;
				}
				fBuffer[fEnd] = src;
				fRanges[fEnd] = new int[] { start, length };
				fEnd++;
			}
		}
		return this;
	}

	/**
	 * Appends the given char. Given for convenience.
	 * 
	 * @param c -
	 *            a char which is appended to the end of the buffer.
	 */
	public CharArrayBuffer append(char c) {
		append(new char[] { c }, 0, 1);
		return this;
	}

	/**
	 * Appends the given String to the buffer. Given for convenience, use
	 * #append(char[]) if possible
	 * 
	 * @param src -
	 *            a char array which is appended to the end of the buffer.
	 */
	public CharArrayBuffer append(String src) {
		if (src != null)
			append(src.toCharArray(), 0, src.length());
		return this;
	}

	/**
	 * Returns the entire contents of the buffer as one char[] or null if
	 * nothing has been put in the buffer.
	 */
	public char[] getContents() {
		if (fEnd == 0)
			return null;

		// determine the size of the array
		int size = 0;
		for (int i = 0; i < fEnd; i++)
			size += fRanges[i][1];

		if (size > 0) {
			char[] result = new char[size];
			int current = 0;
			// copy the results
			for (int i = 0; i < fEnd; i++) {
				int[] range = fRanges[i];
				int length = range[1];
				System.arraycopy(fBuffer[i], range[0], result, current, length);
				current += length;
			}
			return result;
		}
		return null;
	}

	/**
	 * Returns the contents of the buffer as a String, or <code>null</code> if
	 * the buffer is empty.
	 */
	@Override
	public String toString() {
		char[] contents = getContents();
		return (contents != null) ? new String(contents) : null;
	}
}

Back to the top