1
2
3
4
5 package org.rcfaces.core.internal.lang;
6
7 import java.io.IOException;
8 import java.io.Writer;
9
10 import org.apache.commons.logging.Log;
11 import org.apache.commons.logging.LogFactory;
12
13
14
15
16
17
18 public final class StringAppender2 {
19 private static final String REVISION = "$Revision: 1.1 $";
20
21 private static final Log LOG = LogFactory.getLog(StringAppender2.class);
22
23 private String initialValue = null;
24
25 private int initialSize = 0;
26
27 private char value[];
28
29 private int count;
30
31 public StringAppender2() {
32 this(16);
33 }
34
35 public StringAppender2(int length) {
36 if (length < 16) {
37 length = 16;
38 }
39 initialSize = length;
40 }
41
42 public StringAppender2(String str) {
43 this(str, 16);
44 }
45
46 public StringAppender2(String str, int length) {
47 this(str.length() + length);
48
49 initialValue = str;
50 }
51
52 public int length() {
53 if (value == null) {
54 if (initialValue == null) {
55 return 0;
56 }
57 return initialValue.length();
58 }
59 return count;
60 }
61
62 private void expandCapacity(int minimumCapacity) {
63 if (value == null) {
64 throw new IllegalStateException(
65 "Can not expand capacity of an original string !");
66 }
67
68 int newCapacity = (value.length + 1) * 2;
69 if (newCapacity < 0) {
70 newCapacity = Integer.MAX_VALUE;
71
72 } else if (minimumCapacity > newCapacity) {
73 newCapacity = minimumCapacity;
74 }
75
76 if (LOG.isTraceEnabled()) {
77 LOG.trace("Expand capacity from '" + value.length + "' to '"
78 + newCapacity + "'.");
79 }
80
81 char newValue[] = new char[newCapacity];
82 System.arraycopy(value, 0, newValue, 0, count);
83 value = newValue;
84 }
85
86 public void setLength(int newLength) {
87 if (newLength < 0) {
88 throw new StringIndexOutOfBoundsException(newLength);
89 }
90
91 preModification(-newLength);
92
93 if (newLength > value.length) {
94 expandCapacity(newLength);
95 }
96
97 if (count < newLength) {
98 for (; count < newLength; count++) {
99 value[count] = '\0';
100 }
101 return;
102 }
103
104 count = newLength;
105 }
106
107 public char charAt(int index) {
108 if (value == null) {
109 if (initialValue == null) {
110 throw new StringIndexOutOfBoundsException(index);
111 }
112
113 return initialValue.charAt(index);
114 }
115
116 if ((index < 0) || (index >= count)) {
117 throw new StringIndexOutOfBoundsException(index);
118 }
119 return value[index];
120 }
121
122 private void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
123 if (value == null) {
124 if (initialValue == null) {
125 throw new StringIndexOutOfBoundsException(srcBegin);
126 }
127
128 initialValue.getChars(srcBegin, srcEnd, dst, dstBegin);
129 return;
130 }
131
132 if (srcBegin < 0) {
133 throw new StringIndexOutOfBoundsException(srcBegin);
134 }
135 if ((srcEnd < 0) || (srcEnd > count)) {
136 throw new StringIndexOutOfBoundsException(srcEnd);
137 }
138 if (srcBegin > srcEnd) {
139 throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
140 }
141 System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
142 }
143
144
145
146
147
148
149 public StringAppender2 append(String str) {
150 if (str == null) {
151 str = String.valueOf(str);
152 }
153
154 int len = str.length();
155 if (len == 0) {
156 return this;
157 }
158
159 preModification(len);
160
161 int newcount = count + len;
162 if (newcount > value.length) {
163 expandCapacity(newcount);
164 }
165
166 str.getChars(0, len, value, count);
167 count = newcount;
168
169 return this;
170 }
171
172 public StringAppender2 append(StringAppender2 sb) {
173 if (sb == null) {
174 return append((String) null);
175 }
176
177 int len = sb.length();
178 if (len == 0) {
179 return this;
180 }
181
182 preModification(len);
183
184 int newcount = count + len;
185 if (newcount > value.length) {
186 expandCapacity(newcount);
187 }
188
189 sb.getChars(0, len, value, count);
190 count = newcount;
191 return this;
192 }
193
194 public StringAppender2 append(char str[]) {
195 return append(str, 0, str.length);
196 }
197
198 public StringAppender2 append(char str[], int offset, int len) {
199
200 if (len == 0) {
201 return this;
202 }
203
204 preModification(len);
205
206 int newcount = count + len;
207 if (newcount > value.length) {
208 expandCapacity(newcount);
209 }
210
211 System.arraycopy(str, offset, value, count, len);
212 count = newcount;
213
214 return this;
215 }
216
217 public StringAppender2 append(String text, int offset, int len) {
218
219 if (len == 0) {
220 return this;
221 }
222
223 preModification(len);
224
225 int newcount = count + len;
226 if (newcount > value.length) {
227 expandCapacity(newcount);
228 }
229
230 text.getChars(offset, offset + len, value, count);
231 count = newcount;
232
233 return this;
234 }
235
236 public StringAppender2 append(boolean b) {
237 if (b) {
238 return append("true");
239 }
240
241 return append("false");
242 }
243
244 public StringAppender2 append(char c) {
245 return append(c, 1);
246 }
247
248 public StringAppender2 append(char c, int nb) {
249 if (nb < 1) {
250 return this;
251 }
252
253 preModification(nb);
254
255 int newcount = count + nb;
256 if (newcount > value.length) {
257 expandCapacity(newcount);
258 }
259
260 for (; nb > 0; nb--) {
261 value[count++] = c;
262 }
263
264 return this;
265 }
266
267 public StringAppender2 append(int i) {
268 return append(String.valueOf(i));
269 }
270
271 public StringAppender2 append(long l) {
272 return append(String.valueOf(l));
273 }
274
275 public StringAppender2 append(float f) {
276 return append(String.valueOf(f));
277 }
278
279 public String toString() {
280 if (value == null) {
281 return initialValue;
282 }
283 return new String(value, 0, count);
284 }
285
286 public void copyInto(Writer writer) throws IOException {
287 if (value == null) {
288 if (initialValue == null) {
289 return;
290 }
291
292 writer.write(initialValue);
293 return;
294 }
295
296 if (count < 1) {
297 return;
298 }
299
300 writer.write(value, 0, count);
301 }
302
303 public void ensure(int length) {
304 if (value == null) {
305 if (initialSize < length) {
306 initialSize = length;
307 }
308 return;
309 }
310
311 int newcount = count + length;
312 if (newcount <= value.length) {
313 return;
314 }
315 expandCapacity(newcount);
316 }
317
318 public StringAppender2 insert(int offset, String str) {
319
320 if (str == null) {
321 str = String.valueOf(str);
322 }
323
324 int len = str.length();
325 if (len == 0) {
326 return this;
327 }
328
329 preModification(len);
330
331 if ((offset < 0) || (offset > count)) {
332 throw new StringIndexOutOfBoundsException();
333 }
334
335 int newcount = count + len;
336 if (newcount > value.length) {
337 expandCapacity(newcount);
338 }
339
340 System.arraycopy(value, offset, value, offset + len, count - offset);
341 str.getChars(0, len, value, offset);
342 count = newcount;
343 return this;
344 }
345
346 public StringAppender2 insert(int offset, char c) {
347 return insert(offset, c, 1);
348 }
349
350 public StringAppender2 insert(int offset, char c, int nb) {
351 if (nb < 1) {
352 return this;
353 }
354
355 preModification(nb);
356
357 int newcount = count + nb;
358 if (newcount > value.length) {
359 expandCapacity(newcount);
360 }
361
362 System.arraycopy(value, offset, value, offset + nb, count - offset);
363 for (; nb > 0; nb--) {
364 value[offset++] = c;
365 }
366 count = newcount;
367 return this;
368 }
369
370 protected void preModification(int newSize) {
371 if (value != null) {
372 return;
373 }
374
375 if (newSize > 0) {
376 if (initialValue != null) {
377 newSize += initialValue.length();
378 }
379
380 if (initialSize < newSize) {
381 initialSize = newSize;
382 }
383
384 } else if (newSize < 0) {
385 initialSize = newSize;
386 }
387
388 if (initialSize < 16) {
389 initialSize = 16;
390 }
391
392 value = new char[initialSize];
393 if (initialValue != null) {
394 if (initialSize > 0 && initialValue.length() > 0) {
395 initialValue.getChars(0, Math.min(initialValue.length(),
396 initialSize), value, 0);
397 }
398
399 initialValue = null;
400 }
401 }
402
403 public Writer createWriter() {
404 return new Writer() {
405 private static final String REVISION = "$Revision: 1.1 $";
406
407 public void close() {
408 }
409
410 public void flush() {
411 }
412
413 public void write(char[] cbuf, int off, int len) {
414 StringAppender2.this.append(cbuf, off, len);
415 }
416
417 public void write(char c) {
418 StringAppender2.this.append(c);
419 }
420
421 public void write(String s, int off, int len) {
422 StringAppender2.this.append(s, off, len);
423 }
424
425 public void write(String s) {
426 StringAppender2.this.append(s);
427 }
428 };
429 }
430 }