KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > emf > ecore > xmi > impl > StringSegment


1 /**
2  * <copyright>
3  *
4  * Copyright (c) 2002-2005 IBM Corporation and others.
5  * All rights reserved. This program and the accompanying materials
6  * are made available under the terms of the Eclipse Public License v1.0
7  * which accompanies this distribution, and is available at
8  * http://www.eclipse.org/legal/epl-v10.html
9  *
10  * Contributors:
11  * IBM - Initial API and implementation
12  *
13  * </copyright>
14  *
15  * $Id: StringSegment.java,v 1.4 2005/06/08 06:16:07 nickb Exp $
16  */

17 package org.eclipse.emf.ecore.xmi.impl;
18
19
20 import java.io.File JavaDoc;
21 import java.io.FileInputStream JavaDoc;
22 import java.io.FileOutputStream JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.InputStream JavaDoc;
25 import java.io.InputStreamReader JavaDoc;
26 import java.io.OutputStream JavaDoc;
27 import java.io.OutputStreamWriter JavaDoc;
28 import java.io.Writer JavaDoc;
29
30 import java.util.Iterator JavaDoc;
31 import java.util.ListIterator JavaDoc;
32
33 import org.eclipse.emf.common.util.BasicEList;
34
35
36 /**
37  * A String Buffer that never reallocates
38  */

39 public class StringSegment extends BasicEList
40 {
41   protected final static int LIST_SIZE = 100;
42
43   protected static final int ELEMENT_SIZE = 1000;
44
45   protected static final int BUFFER_SIZE = 8192;
46
47   protected int segmentCapacity;
48
49   protected byte[] outputbytes;
50
51   protected char[] outputchars;
52
53   protected char[] buffer;
54
55   protected Element cursor;
56
57   protected int cursorIndex = 0;
58
59   protected String JavaDoc lineSeparator = System.getProperty("line.separator");
60
61   protected String JavaDoc temporaryFileName;
62
63   protected Writer JavaDoc temporaryFile;
64
65   protected int bufferPosition;
66
67   public StringSegment()
68   {
69     this(LIST_SIZE);
70   }
71
72   public StringSegment(int minimumCapacity)
73   {
74     this(minimumCapacity, ELEMENT_SIZE);
75   }
76
77   public StringSegment(int minimumCapacity, int segmentCapacity)
78   {
79     super(minimumCapacity);
80     add(cursor = new Element(this.segmentCapacity = segmentCapacity));
81     outputchars = new char [BUFFER_SIZE];
82   }
83
84   public StringSegment(String JavaDoc temporaryFileName)
85   {
86     this(LIST_SIZE, ELEMENT_SIZE);
87     setTemporaryFileName(temporaryFileName);
88   }
89
90   public void setTemporaryFileName(String JavaDoc tempFile)
91   {
92     temporaryFileName = tempFile;
93     if (temporaryFileName != null)
94     {
95       buffer = new char [BUFFER_SIZE];
96     }
97     else
98     {
99       buffer = null;
100     }
101   }
102
103   public String JavaDoc getTemporaryFileName()
104   {
105     return temporaryFileName;
106   }
107
108   protected Object JavaDoc[] newData(int capacity)
109   {
110     return new Element [capacity];
111   }
112
113   public void reset()
114   {
115     bufferPosition = 0;
116     cursor = (Element)data[0];
117     cursorIndex = 0;
118     for (int i = 0; i < size; i++)
119     {
120       ((Element)data[i]).size = 0;
121     }
122   }
123
124   public void add(String JavaDoc newString)
125   {
126     // System.err.println("add = ["+newString+"]");
127

128     // If there is a temporary file...
129
//
130
if (temporaryFile != null)
131     {
132       int length = newString.length();
133       if (length + bufferPosition >= buffer.length)
134       {
135         try
136         {
137           temporaryFile.write(buffer, 0, bufferPosition);
138         }
139         catch (IOException JavaDoc exception)
140         {
141         }
142         bufferPosition = 0;
143         if (length > buffer.length)
144         {
145           buffer = new char [length];
146         }
147       }
148       newString.getChars(0, length, buffer, bufferPosition);
149       bufferPosition += length;
150       return;
151     }
152
153     // This is the cheapest and most common case.
154
//
155
if (cursor.size < segmentCapacity)
156     {
157       cursor.add(newString);
158       return;
159     }
160
161     Element oldCursor = cursor;
162     int index = size - 1;
163     if (cursorIndex < index)
164     {
165       cursor = (Element)data[++cursorIndex];
166       if (cursor.size == 0)
167       {
168         cursor.add(newString);
169         return;
170       }
171     }
172
173     cursor = new Element(segmentCapacity);
174     cursor.add(newString);
175
176     // The first case is the most common case.
177
// It is slightly cheaper to call add without an index since an index will be range checked.
178
//
179
if (data[index] == oldCursor)
180     {
181       super.add(cursor);
182       cursorIndex = ++index;
183     }
184     else
185     {
186       // This case can only happen if we are reset to a mark and we've got lots of XMLNS attributes to write.
187
//
188
int counter = 0;
189       while (counter < index)
190       {
191         if (data[counter++] == oldCursor)
192         {
193           cursorIndex = counter;
194           super.add(cursorIndex, cursor);
195           break;
196         }
197       }
198     }
199   }
200
201   public void addLine()
202   {
203     add(lineSeparator);
204   }
205
206   public Object JavaDoc mark()
207   {
208     Element result = cursor;
209     if (cursor.size == 0)
210     {
211       result.add("");
212     }
213     int i = size - 1;
214     if (cursorIndex < i)
215     {
216       cursor = (Element)data[++cursorIndex];
217     }
218     else
219     {
220       cursorIndex++;
221       cursor = new Element(segmentCapacity);
222       super.add(cursor);
223     }
224
225     if (temporaryFileName != null && temporaryFile == null)
226     {
227       try
228       {
229         temporaryFile = new OutputStreamWriter JavaDoc(new FileOutputStream JavaDoc(temporaryFileName), "UTF8");
230       }
231       catch (IOException JavaDoc exception)
232       {
233       }
234     }
235
236     return result;
237   }
238
239   public void resetToMark(Object JavaDoc mark)
240   {
241     if (temporaryFile != null)
242     {
243       cursor.add("");
244       try
245       {
246         temporaryFile.write(buffer, 0, bufferPosition);
247         temporaryFile.close();
248       }
249       catch (IOException JavaDoc exception)
250       {
251       }
252       temporaryFile = null;
253     }
254     cursor = (Element)mark;
255     for (int i = 0; i < data.length; i++)
256     {
257       if (data[i] == cursor)
258       {
259         cursorIndex = i;
260         return;
261       }
262     }
263   }
264
265   public int getLength()
266   {
267     Element[] elements = (Element[])data;
268     int length = 0;
269     for (int i = 0; i < size; ++i)
270     {
271       Element element = elements[i];
272       int segmentSize = element.size;
273       for (int j = 0; j < segmentSize; ++j)
274       {
275         String JavaDoc s = element.data[j];
276         length += s.length();
277       }
278     }
279     return length;
280   }
281
282   public int getChars(char[] destination, int position)
283   {
284     Element[] elements = (Element[])data;
285     for (int i = 0; i < size; ++i)
286     {
287       Element element = elements[i];
288       int segmentSize = element.size;
289       for (int j = 0; j < segmentSize; ++j)
290       {
291         String JavaDoc string = element.data[j];
292         int length = string.length();
293         string.getChars(0, length, destination, position);
294         position += length;
295       }
296     }
297     return position;
298   }
299
300   public void writeAscii(OutputStream JavaDoc os, int flushThreshold) throws IOException JavaDoc
301   {
302     if (outputbytes == null)
303     {
304       outputbytes = new byte [BUFFER_SIZE];
305     }
306     Element[] elements = (Element[])data;
307     int position = 0;
308     int count = 0;
309
310     for (int i = 0; i < size; ++i)
311     {
312       Element element = elements[i];
313       int segmentSize = element.size;
314       for (int j = 0; j < segmentSize; ++j)
315       {
316         String JavaDoc string = element.data[j];
317         int length = string.length();
318         if (length + position >= outputchars.length)
319         {
320           for (int x = 0; x < position; x++)
321           {
322             outputbytes[x] = (byte)(outputchars[x] & 0xFF);
323           }
324           os.write(outputbytes, 0, position);
325           position = 0;
326           if (length > outputchars.length)
327           {
328             outputchars = new char [length];
329             outputbytes = new byte [length];
330           }
331         }
332         string.getChars(0, length, outputchars, position);
333         position += length;
334         count += length;
335         if (count > flushThreshold)
336         {
337           os.flush();
338           count = 0;
339         }
340       }
341     }
342     for (int x = 0; x < position; x++)
343     {
344       outputbytes[x] = (byte)(outputchars[x] & 0xFF);
345     }
346
347     os.write(outputbytes, 0, position);
348
349     String JavaDoc temporaryFileName = this.temporaryFileName;
350     if (temporaryFileName != null)
351     {
352       InputStream JavaDoc inputStream = new FileInputStream JavaDoc(temporaryFileName);
353       for (int length = inputStream.read(outputbytes, 0, outputbytes.length); length > 0; length = inputStream.read(
354         outputbytes,
355         0,
356         outputbytes.length))
357       {
358         os.write(outputbytes, 0, length);
359         count += length;
360         if (count > flushThreshold)
361         {
362           os.flush();
363           count = 0;
364         }
365       }
366       inputStream.close();
367       new File JavaDoc(temporaryFileName).delete();
368     }
369   }
370
371   public void write(OutputStreamWriter JavaDoc os, int flushThreshold) throws IOException JavaDoc
372   {
373     Element[] elements = (Element[])data;
374     int position = 0;
375     int count = 0;
376     for (int i = 0; i < size; ++i)
377     {
378       Element element = elements[i];
379       int segmentSize = element.size;
380       for (int j = 0; j < segmentSize; ++j)
381       {
382         String JavaDoc string = element.data[j];
383         int length = string.length();
384         if (length + position >= outputchars.length)
385         {
386           os.write(outputchars, 0, position);
387           position = 0;
388           if (length > outputchars.length)
389           {
390             outputchars = new char [length];
391           }
392         }
393         string.getChars(0, length, outputchars, position);
394         position += length;
395         count += length;
396         if (count > flushThreshold)
397         {
398           os.flush();
399           count = 0;
400         }
401       }
402     }
403     os.write(outputchars, 0, position);
404
405     String JavaDoc temporaryFileName = this.temporaryFileName;
406     if (temporaryFileName != null)
407     {
408       InputStreamReader JavaDoc reader = new InputStreamReader JavaDoc(new FileInputStream JavaDoc(temporaryFileName), "UTF8");
409       for (int length = reader.read(outputchars, 0, outputchars.length); length > 0; length = reader.read(
410         outputchars,
411         0,
412         outputchars.length))
413       {
414         os.write(outputchars, 0, length);
415         count += length;
416         if (count > flushThreshold)
417         {
418           os.flush();
419           count = 0;
420         }
421       }
422       reader.close();
423       new File JavaDoc(temporaryFileName).delete();
424     }
425
426   }
427
428   protected static class Element
429   {
430     int size;
431
432     String JavaDoc[] data;
433
434     Element(int capacity)
435     {
436       data = new String JavaDoc [capacity];
437     }
438
439     void add(String JavaDoc newString)
440     {
441       data[size++] = newString;
442     }
443   }
444
445   public Iterator JavaDoc iterator()
446   {
447     return new SegmentIterator();
448   }
449
450   public ListIterator JavaDoc listIterator()
451   {
452     return new SegmentIterator();
453   }
454
455   protected class SegmentIterator implements ListIterator JavaDoc
456   {
457     protected int outerIndex = 0;
458
459     protected int innerIndex = 0;
460
461     SegmentIterator()
462     {
463     }
464
465     public boolean hasNext()
466     {
467       return outerIndex < size - 1 || (outerIndex == size - 1 && innerIndex < ((Element)data[outerIndex]).size);
468     }
469
470     public boolean hasPrevious()
471     {
472       return outerIndex > 0 || innerIndex > 0;
473     }
474
475     public Object JavaDoc next()
476     {
477       Element element = (Element)data[outerIndex];
478       if (innerIndex < element.size)
479       {
480         return element.data[innerIndex++];
481       }
482       else
483       {
484         innerIndex = 1;
485         return ((Element)data[++outerIndex]).data[0];
486       }
487     }
488
489     public Object JavaDoc previous()
490     {
491       if (innerIndex > 0)
492       {
493         return ((Element)data[outerIndex]).data[--innerIndex];
494       }
495       else
496       {
497         Element element = (Element)data[--outerIndex];
498         innerIndex = element.size - 1;
499         return element.data[innerIndex];
500       }
501     }
502
503     public void add(Object JavaDoc newElement)
504     {
505       throw new UnsupportedOperationException JavaDoc(SegmentIterator.class.toString());
506     }
507
508     public void remove()
509     {
510       throw new UnsupportedOperationException JavaDoc(SegmentIterator.class.toString());
511     }
512
513     public void set(Object JavaDoc newElement)
514     {
515       throw new UnsupportedOperationException JavaDoc(SegmentIterator.class.toString());
516     }
517
518     public int nextIndex()
519     {
520       throw new UnsupportedOperationException JavaDoc(SegmentIterator.class.toString());
521     }
522
523     public int previousIndex()
524     {
525       throw new UnsupportedOperationException JavaDoc(SegmentIterator.class.toString());
526     }
527   }
528 }
529
Popular Tags