1 // ========================================================================
2 // Copyright (c) 2001-2009 Mort Bay Consulting Pty. Ltd.
3 // ------------------------------------------------------------------------
4 // All rights reserved. This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v1.0
6 // and Apache License v2.0 which accompanies this distribution.
7 // The Eclipse Public License is available at
8 // http://www.eclipse.org/legal/epl-v10.html
9 // The Apache License v2.0 is available at
10 // http://www.opensource.org/licenses/apache2.0.php
11 // You may elect to redistribute this code under either of these licenses.
12 // ========================================================================
13
14 package org.eclipse.jetty.util;
15 import java.io.IOException;
16 import java.io.OutputStream;
17 import java.io.OutputStreamWriter;
18 import java.io.Writer;
19
20
21 /* ------------------------------------------------------------ */
22 /** Byte Array ISO 8859 writer.
23 * This class combines the features of a OutputStreamWriter for
24 * ISO8859 encoding with that of a ByteArrayOutputStream. It avoids
25 * many inefficiencies associated with these standard library classes.
26 * It has been optimized for standard ASCII characters.
27 *
28 *
29 */
30 public class ByteArrayISO8859Writer extends Writer
31 {
32 private byte[] _buf;
33 private int _size;
34 private ByteArrayOutputStream2 _bout=null;
35 private OutputStreamWriter _writer=null;
36 private boolean _fixed=false;
37
38 /* ------------------------------------------------------------ */
39 /** Constructor.
40 */
41 public ByteArrayISO8859Writer()
42 {
43 _buf=new byte[2048];
44 }
45
46 /* ------------------------------------------------------------ */
47 /** Constructor.
48 * @param capacity Buffer capacity
49 */
50 public ByteArrayISO8859Writer(int capacity)
51 {
52 _buf=new byte[capacity];
53 }
54
55 /* ------------------------------------------------------------ */
56 public ByteArrayISO8859Writer(byte[] buf)
57 {
58 _buf=buf;
59 _fixed=true;
60 }
61
62 /* ------------------------------------------------------------ */
63 public Object getLock()
64 {
65 return lock;
66 }
67
68 /* ------------------------------------------------------------ */
69 public int size()
70 {
71 return _size;
72 }
73
74 /* ------------------------------------------------------------ */
75 public int capacity()
76 {
77 return _buf.length;
78 }
79
80 /* ------------------------------------------------------------ */
81 public int spareCapacity()
82 {
83 return _buf.length-_size;
84 }
85
86 /* ------------------------------------------------------------ */
87 public void setLength(int l)
88 {
89 _size=l;
90 }
91
92 /* ------------------------------------------------------------ */
93 public byte[] getBuf()
94 {
95 return _buf;
96 }
97
98 /* ------------------------------------------------------------ */
99 public void writeTo(OutputStream out)
100 throws IOException
101 {
102 out.write(_buf,0,_size);
103 }
104
105 /* ------------------------------------------------------------ */
106 public void write(char c)
107 throws IOException
108 {
109 ensureSpareCapacity(1);
110 if (c>=0&&c<=0x7f)
111 _buf[_size++]=(byte)c;
112 else
113 {
114 char[] ca ={c};
115 writeEncoded(ca,0,1);
116 }
117 }
118
119 /* ------------------------------------------------------------ */
120 @Override
121 public void write(char[] ca)
122 throws IOException
123 {
124 ensureSpareCapacity(ca.length);
125 for (int i=0;i<ca.length;i++)
126 {
127 char c=ca[i];
128 if (c>=0&&c<=0x7f)
129 _buf[_size++]=(byte)c;
130 else
131 {
132 writeEncoded(ca,i,ca.length-i);
133 break;
134 }
135 }
136 }
137
138 /* ------------------------------------------------------------ */
139 @Override
140 public void write(char[] ca,int offset, int length)
141 throws IOException
142 {
143 ensureSpareCapacity(length);
144 for (int i=0;i<length;i++)
145 {
146 char c=ca[offset+i];
147 if (c>=0&&c<=0x7f)
148 _buf[_size++]=(byte)c;
149 else
150 {
151 writeEncoded(ca,offset+i,length-i);
152 break;
153 }
154 }
155 }
156
157 /* ------------------------------------------------------------ */
158 @Override
159 public void write(String s)
160 throws IOException
161 {
162 if (s==null)
163 {
164 write("null",0,4);
165 return;
166 }
167
168 int length=s.length();
169 ensureSpareCapacity(length);
170 for (int i=0;i<length;i++)
171 {
172 char c=s.charAt(i);
173 if (c>=0x0&&c<=0x7f)
174 _buf[_size++]=(byte)c;
175 else
176 {
177 writeEncoded(s.toCharArray(),i,length-i);
178 break;
179 }
180 }
181 }
182
183 /* ------------------------------------------------------------ */
184 @Override
185 public void write(String s,int offset, int length)
186 throws IOException
187 {
188 ensureSpareCapacity(length);
189 for (int i=0;i<length;i++)
190 {
191 char c=s.charAt(offset+i);
192 if (c>=0&&c<=0x7f)
193 _buf[_size++]=(byte)c;
194 else
195 {
196 writeEncoded(s.toCharArray(),offset+i,length-i);
197 break;
198 }
199 }
200 }
201
202 /* ------------------------------------------------------------ */
203 private void writeEncoded(char[] ca,int offset, int length)
204 throws IOException
205 {
206 if (_bout==null)
207 {
208 _bout = new ByteArrayOutputStream2(2*length);
209 _writer = new OutputStreamWriter(_bout,StringUtil.__ISO_8859_1);
210 }
211 else
212 _bout.reset();
213 _writer.write(ca,offset,length);
214 _writer.flush();
215 ensureSpareCapacity(_bout.getCount());
216 System.arraycopy(_bout.getBuf(),0,_buf,_size,_bout.getCount());
217 _size+=_bout.getCount();
218 }
219
220 /* ------------------------------------------------------------ */
221 @Override
222 public void flush()
223 {}
224
225 /* ------------------------------------------------------------ */
226 public void resetWriter()
227 {
228 _size=0;
229 }
230
231 /* ------------------------------------------------------------ */
232 @Override
233 public void close()
234 {}
235
236 /* ------------------------------------------------------------ */
237 public void destroy()
238 {
239 _buf=null;
240 }
241
242 /* ------------------------------------------------------------ */
243 public void ensureSpareCapacity(int n)
244 throws IOException
245 {
246 if (_size+n>_buf.length)
247 {
248 if (_fixed)
249 throw new IOException("Buffer overflow: "+_buf.length);
250 byte[] buf = new byte[(_buf.length+n)*4/3];
251 System.arraycopy(_buf,0,buf,0,_size);
252 _buf=buf;
253 }
254 }
255
256
257 /* ------------------------------------------------------------ */
258 public byte[] getByteArray()
259 {
260 byte[] data=new byte[_size];
261 System.arraycopy(_buf,0,data,0,_size);
262 return data;
263 }
264
265 }
266
267