KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > text > rtf > document > output > RtfByteArrayBuffer


1 /*
2  * Copyright 2007 Thomas Bickel
3  *
4  * The contents of this file are subject to the Mozilla Public License Version 1.1
5  * (the "License"); you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
7  *
8  * Software distributed under the License is distributed on an "AS IS" basis,
9  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10  * for the specific language governing rights and limitations under the License.
11  *
12  * The Original Code is 'iText, a free JAVA-PDF library'.
13  *
14  * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
15  * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
16  * All Rights Reserved.
17  * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
18  * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
19  *
20  * Contributor(s): all the names of the contributors are added in the source code
21  * where applicable.
22  *
23  * Alternatively, the contents of this file may be used under the terms of the
24  * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
25  * provisions of LGPL are applicable instead of those above. If you wish to
26  * allow use of your version of this file only under the terms of the LGPL
27  * License and not to allow others to use your version of this file under
28  * the MPL, indicate your decision by deleting the provisions above and
29  * replace them with the notice and other provisions required by the LGPL.
30  * If you do not delete the provisions above, a recipient may use your version
31  * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
32  *
33  * This library is free software; you can redistribute it and/or modify it
34  * under the terms of the MPL as stated above or under the terms of the GNU
35  * Library General Public License as published by the Free Software Foundation;
36  * either version 2 of the License, or any later version.
37  *
38  * This library is distributed in the hope that it will be useful, but WITHOUT
39  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
40  * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
41  * details.
42  *
43  * If you didn't download this code from the following link, you should check if
44  * you aren't using an obsolete version:
45  * http://www.lowagie.com/iText/
46  */

47
48 package com.lowagie.text.rtf.document.output;
49
50 import java.io.*;
51
52 /**
53  * A RtfByteArrayBuffer works much like {@link ByteArrayOutputStream} but is cheaper and faster in most cases
54  * (exception: large writes when reusing buffers).
55  *
56  * @version $Id: RtfByteArrayBuffer.java 2785 2007-05-24 15:45:47Z hallm $
57  * @author Thomas Bickel (tmb99@inode.at)
58  */

59 public final class RtfByteArrayBuffer extends OutputStream
60 {
61     private final java.util.List JavaDoc arrays = new java.util.ArrayList JavaDoc();
62     private byte[] buffer;
63     private int pos = 0;
64     private int size = 0;
65     
66     /**
67      * Constructs a new buffer with a default initial size of 128 bytes.
68      */

69     public RtfByteArrayBuffer()
70     {
71         this(256);
72     }
73     /**
74      * Creates a new buffer with the given initial size.
75      *
76      * @param bufferSize desired initial size in bytes
77      */

78     public RtfByteArrayBuffer(final int bufferSize)
79     {
80         if((bufferSize <= 0) || (bufferSize > 1<<30)) throw(new IllegalArgumentException JavaDoc("bufferSize "+bufferSize));
81         
82         int n = 1<<5;
83         while(n < bufferSize) {
84             n <<= 1;
85         }
86         buffer = new byte[n];
87     }
88     
89     public String JavaDoc toString()
90     {
91         return("RtfByteArrayBuffer: size="+size()+" #arrays="+arrays.size()+" pos="+pos);
92     }
93     
94     /**
95      * Resets this buffer.
96      */

97     public void reset()
98     {
99         arrays.clear();
100         pos = 0;
101         size = 0;
102     }
103     
104     /**
105      * Returns the number of bytes that have been written to this buffer so far.
106      *
107      * @return number of bytes written to this buffer
108      */

109     public long size()
110     {
111         return(size);
112     }
113     
114     private void flushBuffer()
115     {
116         flushBuffer(1);
117     }
118     private void flushBuffer(final int reqSize)
119     {
120         if(reqSize < 0) throw(new IllegalArgumentException JavaDoc());
121         
122         if(pos == 0) return;
123
124         if(pos == buffer.length) {
125             //add old buffer, alloc new (possibly larger) buffer
126
arrays.add(buffer);
127             int newSize = buffer.length;
128             buffer = null;
129             final int MAX = Math.max(1, size>>24) << 16;
130             while(newSize < MAX) {
131                 newSize <<= 1;
132                 if(newSize >= reqSize) break;
133             }
134             buffer = new byte[newSize];
135         } else {
136             //copy buffer contents to newly allocated buffer
137
final byte[] c = new byte[pos];
138             System.arraycopy(buffer, 0, c, 0, pos);
139             arrays.add(c);
140         }
141         pos = 0;
142     }
143     
144     /**
145      * Copies the given byte to the internal buffer.
146      *
147      * @param b
148      */

149     public void write(final int b)
150     {
151         buffer[pos] = (byte)b;
152         size++;
153         if(++pos == buffer.length) flushBuffer();
154     }
155     /**
156      * Copies the given array to the internal buffer.
157      *
158      * @param src
159      */

160     public void write(final byte[] src)
161     {
162         if(src == null) throw(new NullPointerException JavaDoc());
163
164         if(src.length < buffer.length - pos) {
165             System.arraycopy(src, 0, buffer, pos, src.length);
166             pos += src.length;
167             size += src.length;
168             return;
169         }
170         writeLoop(src, 0, src.length);
171     }
172     /**
173      * Copies len bytes starting at position off from the array src to the internal buffer.
174      *
175      * @param src
176      * @param off
177      * @param len
178      */

179     public void write(final byte[] src, int off, int len)
180     {
181         if(src == null) throw(new NullPointerException JavaDoc());
182         if((off < 0) || (off > src.length) || (len < 0) || ((off + len) > src.length) || ((off + len) < 0)) throw new IndexOutOfBoundsException JavaDoc();
183
184         writeLoop(src, off, len);
185     }
186     private void writeLoop(final byte[] src, int off, int len)
187     {
188         while(len > 0) {
189             final int room = buffer.length - pos;
190             final int n = len > room ? room : len;
191             System.arraycopy(src, off, buffer, pos, n);
192             len -= n;
193             off += n;
194             pos += n;
195             size += n;
196             if(pos == buffer.length) flushBuffer(len);
197         }
198     }
199     
200     /**
201      * Writes all bytes available in the given inputstream to this buffer.
202      *
203      * @param in
204      * @return number of bytes written
205      * @throws IOException
206      */

207     public long write(final InputStream in) throws IOException
208     {
209         if(in == null) throw(new NullPointerException JavaDoc());
210         
211         final long sizeStart = size;
212         while(true) {
213             final int n = in.read(buffer, pos, buffer.length - pos);
214             if(n < 0) break;
215             pos += n;
216             size += n;
217             if(pos == buffer.length) flushBuffer();
218         }
219         return(size - sizeStart);
220     }
221     
222     /**
223      * Appends the given array to this buffer without copying (if possible).
224      *
225      * @param a
226      */

227     public void append(final byte[] a)
228     {
229         if(a == null) throw(new NullPointerException JavaDoc());
230         if(a.length == 0) return;
231         
232         if(a.length <= 8) {
233             write(a, 0, a.length);
234         } else
235         if((a.length <= 16) && (pos > 0) && ((buffer.length - pos) > a.length)) {
236             write(a, 0, a.length);
237         } else {
238             flushBuffer();
239             arrays.add(a);
240             size += a.length;
241         }
242     }
243     /**
244      * Appends all arrays to this buffer without copying (if possible).
245      *
246      * @param a
247      */

248     public void append(final byte[][] a)
249     {
250         if(a == null) throw(new NullPointerException JavaDoc());
251
252         for(int k = 0; k < a.length; k++) {
253             append(a[k]);
254         }
255     }
256     
257     /**
258      * Returns the internal list of byte array buffers without copying the buffer contents.
259      *
260      * @return number of bytes written
261      */

262     public byte[][] toByteArrayArray()
263     {
264         flushBuffer();
265         return(byte[][])arrays.toArray(new byte[arrays.size()][]);
266     }
267     
268     /**
269      * Allocates a new array and copies all data that has been written to this buffer to the newly allocated array.
270      *
271      * @return a new byte array
272      */

273     public byte[] toByteArray()
274     {
275         final byte[] r = new byte[size];
276         int off = 0;
277         final int n = arrays.size();
278         for(int k = 0; k < n; k++) {
279             byte[] src = (byte[])arrays.get(k);
280             System.arraycopy(src, 0, r, off, src.length);
281             off += src.length;
282         }
283         if(pos > 0) System.arraycopy(buffer, 0, r, off, pos);
284         return(r);
285     }
286
287     /**
288      * Writes all data that has been written to this buffer to the given output stream.
289      *
290      * @param out
291      * @throws IOException
292      */

293     public void writeTo(final OutputStream out) throws IOException
294     {
295         if(out == null) throw(new NullPointerException JavaDoc());
296         
297         final int n = arrays.size();
298         for(int k = 0; k < n; k++) {
299             byte[] src = (byte[])arrays.get(k);
300             out.write(src);
301         }
302         if(pos > 0) out.write(buffer, 0, pos);
303     }
304 }
305
Popular Tags