8aecc501556ed3a147ccee2d730fc4db0c626f19
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / util / CharArrayBuffer.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core.util;
12
13 /**
14  * The <code>CharArrayBuffer</code> is intended as a lightweight partial
15  * implementation of the StringBuffer class, but using <code>char[]'s</code>
16  * instead of Strings.
17  * 
18  * <p>
19  * The <code>CharArrayBuffer</code> maintains a list of <code>char[]'s</code>
20  * which don't get appended until the user asks for them. The following code
21  * illustrates how to use the class.
22  * 
23  * <code>
24  * CharArrayBuffer buffer = new CharArrayBuffer(myCharArray);
25  * buffer.append(moreBytes, 0, someLength);
26  * myCharArray = buffer.getContents();
27  * </code>
28  * 
29  * <p>
30  * NOTE: This class is not Thread safe!
31  */
32 public class CharArrayBuffer {
33         /**
34          * This is the buffer of char arrays which must be appended together during
35          * the getContents method.
36          */
37         protected char[][] fBuffer;
38
39         /**
40          * The default buffer size.
41          */
42         public static final int DEFAULT_BUFFER_SIZE = 10;
43
44         /**
45          * The end of the buffer
46          */
47         protected int fEnd;
48
49         /**
50          * The current size of the buffer.
51          */
52         protected int fSize;
53
54         /**
55          * A buffer of ranges which is maintained along with the buffer. Ranges are
56          * of the form {start, length}. Enables append(char[] array, int start, int
57          * end).
58          */
59         protected int[][] fRanges;
60
61         /**
62          * Creates a <code>CharArrayBuffer</code> with the default buffer size
63          * (10).
64          */
65         public CharArrayBuffer() {
66                 this(null, DEFAULT_BUFFER_SIZE);
67         }
68
69         /**
70          * Creates a <code>CharArrayBuffer</code> with the default buffer size,
71          * and sets the first element in the buffer to be the given char[].
72          * 
73          * @param first -
74          *            the first element to be placed in the buffer, ignored if null
75          */
76         public CharArrayBuffer(char[] first) {
77                 this(first, DEFAULT_BUFFER_SIZE);
78         }
79
80         /**
81          * Creates a <code>CharArrayBuffer</code> with the given buffer size, and
82          * sets the first element in the buffer to be the given char array.
83          * 
84          * @param first -
85          *            the first element of the buffer, ignored if null.
86          * @param size -
87          *            the buffer size, if less than 1, set to the
88          *            DEFAULT_BUFFER_SIZE.
89          */
90         public CharArrayBuffer(char[] first, int size) {
91                 fSize = (size > 0) ? size : DEFAULT_BUFFER_SIZE;
92                 fBuffer = new char[fSize][];
93                 fRanges = new int[fSize][];
94                 fEnd = 0;
95                 if (first != null)
96                         append(first, 0, first.length);
97         }
98
99         /**
100          * Creates a <code>CharArrayBuffer</code> with the given buffer size.
101          * 
102          * @param size -
103          *            the size of the buffer.
104          */
105         public CharArrayBuffer(int size) {
106                 this(null, size);
107         }
108
109         /**
110          * Appends the entire given char array. Given for convenience.
111          * 
112          * @param src -
113          *            a char array which is appended to the end of the buffer.
114          */
115         public CharArrayBuffer append(char[] src) {
116                 if (src != null)
117                         append(src, 0, src.length);
118                 return this;
119         }
120
121         /**
122          * Appends a sub array of the given array to the buffer.
123          * 
124          * @param src -
125          *            the next array of characters to be appended to the buffer,
126          *            ignored if null
127          * @param start -
128          *            the start index in the src array.
129          * @param length -
130          *            the number of characters from start to be appended
131          * 
132          * @throws ArrayIndexOutOfBoundsException -
133          *             if arguments specify an array index out of bounds.
134          */
135         public CharArrayBuffer append(char[] src, int start, int length) {
136                 if (start < 0)
137                         throw new ArrayIndexOutOfBoundsException();
138                 if (length < 0)
139                         throw new ArrayIndexOutOfBoundsException();
140                 if (src != null) {
141                         int srcLength = src.length;
142                         if (start > srcLength)
143                                 throw new ArrayIndexOutOfBoundsException();
144                         if (length + start > srcLength)
145                                 throw new ArrayIndexOutOfBoundsException();
146                         /** do length check here to allow exceptions to be thrown */
147                         if (length > 0) {
148                                 if (fEnd == fSize) {
149                                         int size2 = fSize * 2;
150                                         System.arraycopy(fBuffer, 0, (fBuffer = new char[size2][]),
151                                                         0, fSize);
152                                         System.arraycopy(fRanges, 0, (fRanges = new int[size2][]),
153                                                         0, fSize);
154                                         fSize *= 2;
155                                 }
156                                 fBuffer[fEnd] = src;
157                                 fRanges[fEnd] = new int[] { start, length };
158                                 fEnd++;
159                         }
160                 }
161                 return this;
162         }
163
164         /**
165          * Appends the given char. Given for convenience.
166          * 
167          * @param src -
168          *            a char which is appended to the end of the buffer.
169          */
170         public CharArrayBuffer append(char c) {
171                 append(new char[] { c }, 0, 1);
172                 return this;
173         }
174
175         /**
176          * Appends the given String to the buffer. Given for convenience, use
177          * #append(char[]) if possible
178          * 
179          * @param src -
180          *            a char array which is appended to the end of the buffer.
181          */
182         public CharArrayBuffer append(String src) {
183                 if (src != null)
184                         append(src.toCharArray(), 0, src.length());
185                 return this;
186         }
187
188         /**
189          * Returns the entire contents of the buffer as one char[] or null if
190          * nothing has been put in the buffer.
191          */
192         public char[] getContents() {
193                 if (fEnd == 0)
194                         return null;
195
196                 // determine the size of the array
197                 int size = 0;
198                 for (int i = 0; i < fEnd; i++)
199                         size += fRanges[i][1];
200
201                 if (size > 0) {
202                         char[] result = new char[size];
203                         int current = 0;
204                         // copy the results
205                         for (int i = 0; i < fEnd; i++) {
206                                 int[] range = fRanges[i];
207                                 int length = range[1];
208                                 System.arraycopy(fBuffer[i], range[0], result, current, length);
209                                 current += length;
210                         }
211                         return result;
212                 }
213                 return null;
214         }
215
216         /**
217          * Returns the contents of the buffer as a String, or <code>null</code> if
218          * the buffer is empty.
219          */
220         public String toString() {
221                 char[] contents = getContents();
222                 return (contents != null) ? new String(contents) : null;
223         }
224 }