KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > it > stefanochizzolini > clown > bytes > Buffer


1 /*
2   Copyright © 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
3
4   Contributors:
5     * Stefano Chizzolini (original code developer, info@stefanochizzolini.it):
6       contributed code is Copyright © 2006 by Stefano Chizzolini.
7
8   This file should be part of the source code distribution of "PDF Clown library"
9   (the Program): see the accompanying README files for more info.
10
11   This Program is free software; you can redistribute it and/or modify it under
12   the terms of the GNU General Public License as published by the Free Software
13   Foundation; either version 2 of the License, or (at your option) any later version.
14
15   This Program is distributed in the hope that it will be useful, but WITHOUT ANY
16   WARRANTY, either expressed or implied; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
18
19   You should have received a copy of the GNU General Public License along with this
20   Program (see README files); if not, go to the GNU website (http://www.gnu.org/).
21
22   Redistribution and use, with or without modification, are permitted provided that such
23   redistributions retain the above copyright notice, license and disclaimer, along with
24   this list of conditions.
25 */

26
27 package it.stefanochizzolini.clown.bytes;
28
29 import it.stefanochizzolini.clown.bytes.filters.Filter;
30 import it.stefanochizzolini.clown.util.NotImplementedException;
31
32 import java.io.EOFException JavaDoc;
33 import java.io.IOException JavaDoc;
34 import java.util.Date JavaDoc;
35
36 /**
37   Byte buffer.
38 */

39 public final class Buffer
40   implements IBuffer
41 {
42   // <class>
43
// <static>
44
// <fields>
45
/**
46     Default buffer capacity.
47   */

48   private static final int DefaultCapacity = 1 << 8;
49
50   private static final String JavaDoc DefaultCharset = "ISO-8859-1";
51   // </fields>
52
// </static>
53

54   // <dynamic>
55
// <fields>
56
/**
57     Inner buffer where data are stored.
58   */

59   private byte[] data;
60   /**
61     Number of bytes actually used in the buffer.
62   */

63   private int length;
64   /**
65     Pointer position within the buffer.
66   */

67   private int position = 0;
68   // </fields>
69

70   // <constructors>
71
public Buffer(
72     )
73   {this(0);}
74
75   public Buffer(
76     int capacity
77     )
78   {
79     if(capacity < 1)
80       capacity = DefaultCapacity;
81
82     this.data = new byte[capacity];
83     this.length = 0;
84   }
85
86   public Buffer(
87     byte[] data
88     )
89   {
90     this.data = data;
91     this.length = data.length;
92   }
93   // </constructors>
94

95   // <interface>
96
// <public>
97
// <IBuffer>
98
public void append(
99     byte data
100     )
101   {
102     while(true)
103     {
104       try
105       {
106         this.data[this.length] = data;
107         break; // Escape the loop.
108
}
109       catch(Exception JavaDoc e)
110       {
111         // Do NOT additional data exceed buffer capacity?
112
if(!ensureCapacity(1)) // Unhandled exception.
113
{
114           // Propagate the exception!
115
throw new RuntimeException JavaDoc(e);
116         }
117       }
118     }
119
120     // Update buffer size!
121
this.length++;
122   }
123
124   public void append(
125     byte[] data
126     )
127   {
128     append(
129       data,
130       0,
131       data.length
132       );
133   }
134
135   public void append(
136     byte[] data,
137     int offset,
138     int length
139     )
140   {
141     while(true)
142     {
143       try
144       {
145         System.arraycopy(
146           data,
147           offset,
148           this.data,
149           this.length,
150           length
151           );
152         break; // Escape the loop.
153
}
154       catch(Exception JavaDoc e)
155       {
156         // Do NOT additional data exceed buffer capacity?
157
if(!ensureCapacity(length)) // Unhandled exception.
158
{
159           // Propagate the exception!
160
throw new RuntimeException JavaDoc(e);
161         }
162       }
163     }
164
165     // Update buffer size!
166
this.length += length;
167   }
168
169   public void append(
170     String JavaDoc data
171     )
172   {
173     try
174     {append(data.getBytes(DefaultCharset));}
175     catch(Exception JavaDoc e)
176     {throw new RuntimeException JavaDoc(e);}
177   }
178
179   public void append(
180     IInputStream data
181     )
182   {
183     append(
184       data.toByteArray(),
185       0,
186       (int)data.getLength()
187       );
188   }
189
190   public IBuffer clone(
191     )
192   {
193     IBuffer clone = new Buffer(getCapacity());
194     clone.append(data);
195
196     return clone;
197   }
198
199   public void decode(
200     Filter filter
201     )
202   {
203     data = filter.decode(data,0,length);
204     length = data.length;
205   }
206
207   public void delete(
208     int index,
209     int length
210     )
211   {
212     try
213     {
214       // Shift left the trailing data block to override the deleted data!
215
System.arraycopy(
216         this.data,
217         index + length,
218         this.data,
219         index,
220         this.length - (index + length)
221         );
222     }
223     catch(Exception JavaDoc e)
224     {throw new RuntimeException JavaDoc(e);}
225
226     // Update the buffer size!
227
this.length -= length;
228   }
229
230   public byte[] encode(
231     Filter filter
232     )
233   {return filter.encode(data,0,length);}
234
235   public int getByte(
236     int index
237     )
238   {return data[index];}
239
240   public byte[] getByteArray(
241     int index,
242     int length
243     )
244   {
245     byte[] data = new byte[length];
246     System.arraycopy(
247       this.data,
248       index,
249       data,
250       0,
251       length
252       );
253
254     return data;
255   }
256
257   public String JavaDoc getString(
258     int index,
259     int length
260     )
261   {
262     try
263     {return new String JavaDoc(data,index,length,DefaultCharset);}
264     catch(Exception JavaDoc e)
265     {throw new RuntimeException JavaDoc(e);}
266   }
267
268   public int getCapacity(
269     )
270   {return data.length;}
271
272   public void insert(
273     int index,
274     byte[] data
275     )
276   {
277     insert(
278       index,
279       data,
280       0,
281       data.length
282       );
283   }
284
285   public void insert(
286     int index,
287     byte[] data,
288     int offset,
289     int length
290     )
291   {
292     while(true)
293     {
294       try
295       {
296         // Shift right the existing data block to make room for new data!
297
System.arraycopy(
298           this.data,
299           index,
300           this.data,
301           index + length,
302           this.length - index
303           );
304         break; // Escape the loop.
305
}
306       catch(Exception JavaDoc e)
307       {
308         // Do NOT additional data exceed buffer capacity?
309
if(!ensureCapacity(length)) // Unhandled exception.
310
{
311           // Propagate the exception!
312
throw new RuntimeException JavaDoc(e);
313         }
314       }
315     }
316
317     // Insert additional data!
318
System.arraycopy(
319       data,
320       offset,
321       this.data,
322       index,
323       length
324       );
325
326     // Update the buffer size!
327
this.length += length;
328   }
329
330   public void insert(
331     int index,
332     String JavaDoc data
333     )
334   {
335     try
336     {
337       insert(
338         index,
339         data.getBytes(DefaultCharset)
340         );
341     }
342     catch(Exception JavaDoc e)
343     {
344       // Propagate the exception!
345
throw new RuntimeException JavaDoc(e);
346     }
347   }
348
349   public void insert(
350     int index,
351     IInputStream data
352     )
353   {
354     insert(
355       index,
356       data.toByteArray()
357       );
358   }
359
360   public void replace(
361     int index,
362     byte[] data
363     )
364   {
365     // Replace data!
366
System.arraycopy(
367       data,
368       0,
369       this.data,
370       index,
371       data.length
372       );
373   }
374
375   public void replace(
376     int index,
377     byte[] data,
378     int offset,
379     int length
380     )
381   {
382     // Replace data!
383
System.arraycopy(
384       data,
385       offset,
386       this.data,
387       index,
388       data.length
389       );
390   }
391
392   public void replace(
393     int index,
394     String JavaDoc data
395     )
396   {
397     try
398     {
399       // Replace data!
400
replace(
401         index,
402         data.getBytes(DefaultCharset)
403         );
404     }
405     catch(Exception JavaDoc e)
406     {throw new RuntimeException JavaDoc(e);}
407   }
408
409   public void replace(
410     int index,
411     IInputStream data
412     )
413   {
414     // Replace data!
415
replace(
416       index,
417       data.toByteArray()
418       );
419   }
420
421   public void setLength(
422     int value
423     )
424   {length = value;}
425
426   public void writeTo(
427     IOutputStream stream
428     )
429   {
430     stream.write(
431       data,
432       0,
433       length
434       );
435   }
436
437   // <IInputStream>
438
public long getLength(
439     )
440   {return length;}
441
442   public long getPosition(
443     )
444   {return position;}
445
446   /* int hashCode() uses inherited implementation. */
447
448   public void read(
449     byte[] data
450     )
451   {
452     read(
453       data,
454       0,
455       data.length
456       );
457   }
458
459   public void read(
460     byte[] data,
461     int offset,
462     int length
463     )
464   {
465     try
466     {
467       System.arraycopy(
468         this.data,
469         position,
470         data,
471         offset,
472         length
473         );
474       position += length;
475     }
476     catch(Exception JavaDoc e)
477     {throw new RuntimeException JavaDoc(e);}
478   }
479
480   public byte readByte(
481     )
482     throws EOFException JavaDoc
483   {
484     try
485     {return data[position++];}
486     catch(ArrayIndexOutOfBoundsException JavaDoc e)
487     {throw new EOFException JavaDoc();}
488   }
489
490   public int readInt(
491     )
492     throws EOFException JavaDoc
493   {throw new NotImplementedException();}
494
495   public String JavaDoc readLine(
496     )
497     throws EOFException JavaDoc
498   {
499     StringBuilder JavaDoc buffer = new StringBuilder JavaDoc();
500     try
501     {
502       while(true)
503       {
504         int c = data[position++];
505         if(c == '\r'
506           || c == '\n')
507           break;
508
509         buffer.append((char)c);
510       }
511     }
512     catch(ArrayIndexOutOfBoundsException JavaDoc e)
513     {throw new EOFException JavaDoc();}
514
515     return buffer.toString();
516   }
517
518   public short readShort(
519     )
520     throws EOFException JavaDoc
521   {throw new NotImplementedException();}
522
523   public String JavaDoc readString(
524     int length
525     )
526   {
527     try
528     {
529       String JavaDoc data = new String JavaDoc(
530         this.data,
531         position,
532         length,
533         DefaultCharset
534         );
535       position += length;
536
537       return data;
538     }
539     catch(Exception JavaDoc e)
540     {throw new RuntimeException JavaDoc(e);}
541   }
542
543   public int readUnsignedByte(
544     )
545     throws EOFException JavaDoc
546   {
547     try
548     {return data[position++];}
549     catch(ArrayIndexOutOfBoundsException JavaDoc e)
550     {throw new EOFException JavaDoc();}
551   }
552
553   public int readUnsignedShort(
554     )
555     throws EOFException JavaDoc
556   {throw new NotImplementedException();}
557
558   public void seek(
559     long offset
560     )
561   {position = (int)offset;}
562
563   public void setPosition(
564     long value
565     )
566   {position = (int)value;}
567
568   public void skip(
569     long offset
570     )
571   {position += (int)offset;}
572
573   public byte[] toByteArray(
574     )
575   {
576     byte[] data = new byte[this.length];
577     System.arraycopy(
578       this.data,
579       0,
580       data,
581       0,
582       this.length
583       );
584
585     return data;
586   }
587   // </IInputStream>
588
// </IBuffer>
589
// </public>
590

591   // <protected>
592
/**
593     Check whether the buffer capacity has sufficient room for adding data.
594   */

595   protected boolean ensureCapacity(
596     int additionalLength
597     )
598   {
599     int minCapacity = this.length + additionalLength;
600     // Is additional data within the buffer capacity?
601
if(minCapacity <= this.data.length)
602       return false; // OK -- No change.
603

604     // Additional data exceed buffer capacity.
605
// Reallocate the buffer!
606
byte[] data = new byte[
607       Math.max(
608         this.data.length << 1, // 1 order of magnitude greater than current capacity.
609
minCapacity // Minimum capacity required.
610
)
611       ];
612     System.arraycopy(
613       this.data,
614       0,
615       data,
616       0,
617       this.length
618       );
619     this.data = data;
620
621     return true; // Reallocation happened.
622
}
623 }
Popular Tags