KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > om > FastStringBuffer


1 package net.sf.saxon.om;
2
3 import net.sf.saxon.tinytree.CharSlice;
4
5 import java.io.Writer JavaDoc;
6 import java.io.Serializable JavaDoc;
7
8 /**
9  * A simple implementation of a class similar to StringBuffer. Unlike
10  * StringBuffer it is not synchronized. It also offers the capability
11  * to remove unused space. (This class could possibly be replaced by
12  * StringBuilder in JDK 1.5, but using our own class gives more control.)
13  */

14
15 public final class FastStringBuffer implements CharSequence JavaDoc, Serializable JavaDoc {
16
17     private char[] array;
18     private int used = 0;
19
20     public FastStringBuffer(int initialSize) {
21         array = new char[initialSize];
22     }
23
24     /**
25      * Append the contents of a String to the buffer
26      * @param s the String to be appended
27      */

28
29     public void append(String JavaDoc s) {
30         int len = s.length();
31         ensureCapacity(len);
32         s.getChars(0, len, array, used);
33         used += len;
34     }
35
36     /**
37      * Append the contents of a CharSlice to the buffer
38      * @param s the String to be appended
39      */

40
41     public void append(CharSlice s) {
42         int len = s.length();
43         ensureCapacity(len);
44         s.copyTo(array, used);
45         used += len;
46     }
47
48     /**
49      * Append the contents of a FastStringBuffer to the buffer
50      * @param s the FastStringBuffer to be appended
51      */

52
53     public void append(FastStringBuffer s) {
54         int len = s.length();
55         ensureCapacity(len);
56         s.getChars(0, len, array, used);
57         used += len;
58     }
59
60     /**
61      * Append the contents of a StringBuffer to the buffer
62      * @param s the StringBuffer to be appended
63      */

64
65     public void append(StringBuffer JavaDoc s) {
66         int len = s.length();
67         ensureCapacity(len);
68         s.getChars(0, len, array, used);
69         used += len;
70     }
71
72     /**
73      * Append the contents of a general CharSequence to the buffer
74      * @param s the CharSequence to be appended
75      */

76
77     public void append(CharSequence JavaDoc s) {
78         // Although we provide variants of this method for different subtypes, Java decides which to use based
79
// on the static type of the operand. We want to use the right method based on the dynamic type, to avoid
80
// creating objects and copying strings unnecessarily. So we do a dynamic dispatch.
81
final int len = s.length();
82         ensureCapacity(len);
83         if (s instanceof CharSlice) {
84             ((CharSlice)s).copyTo(array, used);
85         } else if (s instanceof String JavaDoc) {
86             ((String JavaDoc)s).getChars(0, len, array, used);
87         } else if (s instanceof FastStringBuffer) {
88             ((FastStringBuffer)s).getChars(0, len, array, used);
89         } else {
90             s.toString().getChars(0, len, array, used);
91         }
92         used += len;
93     }
94
95     /**
96      * Append the contents of a character array to the buffer
97      * @param srcArray the array whose contents are to be added
98      * @param start the offset of the first character in the array to be copied
99      * @param length the number of characters to be copied
100      */

101
102     public void append(char[] srcArray, int start, int length) {
103         ensureCapacity(length);
104         System.arraycopy(srcArray, start, array, used, length);
105         used += length;
106     }
107
108     /**
109      * Append a character to the buffer
110      * @param ch the character to be added
111      */

112
113     public void append(char ch) {
114         ensureCapacity(1);
115         array[used++] = ch;
116     }
117
118     /**
119      * Returns the length of this character sequence. The length is the number
120      * of 16-bit <code>char</code>s in the sequence.</p>
121      *
122      * @return the number of <code>char</code>s in this sequence
123      */

124     public int length() {
125         return used;
126     }
127
128     /**
129      * Returns the <code>char</code> value at the specified index. An index ranges from zero
130      * to <tt>length() - 1</tt>. The first <code>char</code> value of the sequence is at
131      * index zero, the next at index one, and so on, as for array
132      * indexing. </p>
133      * <p/>
134      * <p>If the <code>char</code> value specified by the index is a
135      * <a HREF="Character.html#unicode">surrogate</a>, the surrogate
136      * value is returned.
137      *
138      * @param index the index of the <code>char</code> value to be returned
139      * @return the specified <code>char</code> value
140      * @throws IndexOutOfBoundsException if the <tt>index</tt> argument is negative or not less than
141      * <tt>length()</tt>
142      */

143     public char charAt(int index) {
144         if (index >= used) {
145             throw new IndexOutOfBoundsException JavaDoc("" + index);
146         }
147         return array[index];
148     }
149
150     /**
151      * Returns a new <code>CharSequence</code> that is a subsequence of this sequence.
152      * The subsequence starts with the <code>char</code> value at the specified index and
153      * ends with the <code>char</code> value at index <tt>end - 1</tt>. The length
154      * (in <code>char</code>s) of the
155      * returned sequence is <tt>end - start</tt>, so if <tt>start == end</tt>
156      * then an empty sequence is returned. </p>
157      *
158      * @param start the start index, inclusive
159      * @param end the end index, exclusive
160      * @return the specified subsequence
161      * @throws IndexOutOfBoundsException if <tt>start</tt> or <tt>end</tt> are negative,
162      * if <tt>end</tt> is greater than <tt>length()</tt>,
163      * or if <tt>start</tt> is greater than <tt>end</tt>
164      */

165     public CharSequence JavaDoc subSequence(int start, int end) {
166         return new CharSlice(array, start, end - start);
167     }
168
169     /**
170      * Copies characters from this FastStringBuffer into the destination character
171      * array.
172      * <p>
173      * The first character to be copied is at index <code>srcBegin</code>;
174      * the last character to be copied is at index <code>srcEnd-1</code>
175      * (thus the total number of characters to be copied is
176      * <code>srcEnd-srcBegin</code>). The characters are copied into the
177      * subarray of <code>dst</code> starting at index <code>dstBegin</code>
178      * and ending at index:
179      * <p><blockquote><pre>
180      * dstbegin + (srcEnd-srcBegin) - 1
181      * </pre></blockquote>
182      *
183      * @param srcBegin index of the first character in the string
184      * to copy.
185      * @param srcEnd index after the last character in the string
186      * to copy.
187      * @param dst the destination array.
188      * @param dstBegin the start offset in the destination array.
189      * @exception IndexOutOfBoundsException If any of the following
190      * is true:
191      * <ul><li><code>srcBegin</code> is negative.
192      * <li><code>srcBegin</code> is greater than <code>srcEnd</code>
193      * <li><code>srcEnd</code> is greater than the length of this
194      * string
195      * <li><code>dstBegin</code> is negative
196      * <li><code>dstBegin+(srcEnd-srcBegin)</code> is larger than
197      * <code>dst.length</code></ul>
198      */

199     public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
200         if (srcBegin < 0) {
201             throw new StringIndexOutOfBoundsException JavaDoc(srcBegin);
202         }
203         if (srcEnd > used) {
204             throw new StringIndexOutOfBoundsException JavaDoc(srcEnd);
205         }
206         if (srcBegin > srcEnd) {
207             throw new StringIndexOutOfBoundsException JavaDoc(srcEnd - srcBegin);
208         }
209         System.arraycopy(array, srcBegin, dst, dstBegin, srcEnd - srcBegin);
210     }
211
212     /**
213      * Convert contents of the FastStringBuffer to a string
214      */

215
216     public String JavaDoc toString() {
217         condense();
218         return new String JavaDoc(array, 0, used);
219     }
220
221     /**
222      * Set the character at a particular offset
223      * @param index the index of the character to be set
224      * @param ch the new character to overwrite the existing character at that location
225      * @throws IndexOutOfBoundsException if int<0 or int>=length()
226      */

227
228     public void setCharAt(int index, char ch) {
229         if (index<0 || index>used) {
230             throw new IndexOutOfBoundsException JavaDoc(""+index);
231         }
232         array[index] = ch;
233     }
234
235     /**
236      * Set the length. If this exceeds the current length, this method is a no-op.
237      * If this is less than the current length, characters beyond the specified point
238      * are deleted.
239      * @param length the new length
240      */

241
242     public void setLength(int length) {
243         if (length < 0 || length > used) {
244             return;
245         }
246         used = length;
247     }
248
249     /**
250      * Expand the character array if necessary to ensure capacity for appended data
251      */

252
253     public void ensureCapacity(int extra) {
254         if (used + extra > array.length) {
255             int newlen = array.length * 2;
256             if (newlen < used + extra) {
257                 newlen = used + extra*2;
258             }
259             char[] array2 = new char[newlen];
260             System.arraycopy(array, 0, array2, 0, used);
261             array = array2;
262         }
263     }
264
265     /**
266      * Remove surplus space from the array. This doesn't reduce the array to the minimum
267      * possible size; it only reclaims space if it seems worth doing. Specifically, it
268      * contracts the array if the amount of wasted space is more than 256 characters, or
269      * more than half the allocated size.
270      */

271
272     public CharSequence JavaDoc condense() {
273         if (array.length - used > 256 || array.length > used * 2) {
274             char[] array2 = new char[used];
275             System.arraycopy(array, 0, array2, 0, used);
276             array = array2;
277         }
278         return this;
279     }
280
281     /**
282      * Write the value to a writer
283      */

284
285     public void write(Writer JavaDoc writer) throws java.io.IOException JavaDoc {
286         writer.write(array, 0, used);
287     }
288 }
289
290 //
291
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
292
// you may not use this file except in compliance with the License. You may obtain a copy of the
293
// License at http://www.mozilla.org/MPL/
294
//
295
// Software distributed under the License is distributed on an "AS IS" basis,
296
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
297
// See the License for the specific language governing rights and limitations under the License.
298
//
299
// The Original Code is: all this file.
300
//
301
// The Initial Developer of the Original Code is Michael H. Kay
302
//
303
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
304
//
305
// Contributor(s): none
306
//
307

308
Popular Tags