1 // ========================================================================
2 // Copyright 2001-2005 Mort Bay Consulting Pty. Ltd.
3 // ------------------------------------------------------------------------
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 // ========================================================================
14
15 package org.mortbay.util;
16 import java.io.IOException;
17 import java.io.OutputStream;
18 import java.io.OutputStreamWriter;
19 import java.io.Writer;
20
21
22 /* ------------------------------------------------------------ */
23 /** Byte Array ISO 8859 writer.
24 * This class combines the features of a OutputStreamWriter for
25 * ISO8859 encoding with that of a ByteArrayOutputStream. It avoids
26 * many inefficiencies associated with these standard library classes.
27 * It has been optimized for standard ASCII characters.
28 *
29 * @author Greg Wilkins (gregw)
30 */
31 public class ByteArrayISO8859Writer extends Writer
32 {
33 private byte[] _buf;
34 private int _size;
35 private ByteArrayOutputStream2 _bout=null;
36 private OutputStreamWriter _writer=null;
37 private boolean _fixed=false;
38
39 /* ------------------------------------------------------------ */
40 /** Constructor.
41 */
42 public ByteArrayISO8859Writer()
43 {
44 _buf=new byte[2048];
45 }
46
47 /* ------------------------------------------------------------ */
48 /** Constructor.
49 * @param capacity Buffer capacity
50 */
51 public ByteArrayISO8859Writer(int capacity)
52 {
53 _buf=new byte[capacity];
54 }
55
56 /* ------------------------------------------------------------ */
57 public ByteArrayISO8859Writer(byte[] buf)
58 {
59 _buf=buf;
60 _fixed=true;
61 }
62
63 /* ------------------------------------------------------------ */
64 public Object getLock()
65 {
66 return lock;
67 }
68
69 /* ------------------------------------------------------------ */
70 public int size()
71 {
72 return _size;
73 }
74
75 /* ------------------------------------------------------------ */
76 public int capacity()
77 {
78 return _buf.length;
79 }
80
81 /* ------------------------------------------------------------ */
82 public int spareCapacity()
83 {
84 return _buf.length-_size;
85 }
86
87 /* ------------------------------------------------------------ */
88 public void setLength(int l)
89 {
90 _size=l;
91 }
92
93 /* ------------------------------------------------------------ */
94 public byte[] getBuf()
95 {
96 return _buf;
97 }
98
99 /* ------------------------------------------------------------ */
100 public void writeTo(OutputStream out)
101 throws IOException
102 {
103 out.write(_buf,0,_size);
104 }
105
106 /* ------------------------------------------------------------ */
107 public void write(char c)
108 throws IOException
109 {
110 ensureSpareCapacity(1);
111 if (c>=0&&c<=0x7f)
112 _buf[_size++]=(byte)c;
113 else
114 {
115 char[] ca ={c};
116 writeEncoded(ca,0,1);
117 }
118 }
119
120 /* ------------------------------------------------------------ */
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 public void write(char[] ca,int offset, int length)
140 throws IOException
141 {
142 ensureSpareCapacity(length);
143 for (int i=0;i<length;i++)
144 {
145 char c=ca[offset+i];
146 if (c>=0&&c<=0x7f)
147 _buf[_size++]=(byte)c;
148 else
149 {
150 writeEncoded(ca,offset+i,length-i);
151 break;
152 }
153 }
154 }
155
156 /* ------------------------------------------------------------ */
157 public void write(String s)
158 throws IOException
159 {
160 if (s==null)
161 {
162 write("null",0,4);
163 return;
164 }
165
166 int length=s.length();
167 ensureSpareCapacity(length);
168 for (int i=0;i<length;i++)
169 {
170 char c=s.charAt(i);
171 if (c>=0x0&&c<=0x7f)
172 _buf[_size++]=(byte)c;
173 else
174 {
175 writeEncoded(s.toCharArray(),i,length-i);
176 break;
177 }
178 }
179 }
180
181 /* ------------------------------------------------------------ */
182 public void write(String s,int offset, int length)
183 throws IOException
184 {
185 ensureSpareCapacity(length);
186 for (int i=0;i<length;i++)
187 {
188 char c=s.charAt(offset+i);
189 if (c>=0&&c<=0x7f)
190 _buf[_size++]=(byte)c;
191 else
192 {
193 writeEncoded(s.toCharArray(),offset+i,length-i);
194 break;
195 }
196 }
197 }
198
199 /* ------------------------------------------------------------ */
200 private void writeEncoded(char[] ca,int offset, int length)
201 throws IOException
202 {
203 if (_bout==null)
204 {
205 _bout = new ByteArrayOutputStream2(2*length);
206 _writer = new OutputStreamWriter(_bout,StringUtil.__ISO_8859_1);
207 }
208 else
209 _bout.reset();
210 _writer.write(ca,offset,length);
211 _writer.flush();
212 ensureSpareCapacity(_bout.getCount());
213 System.arraycopy(_bout.getBuf(),0,_buf,_size,_bout.getCount());
214 _size+=_bout.getCount();
215 }
216
217 /* ------------------------------------------------------------ */
218 public void flush()
219 {}
220
221 /* ------------------------------------------------------------ */
222 public void resetWriter()
223 {
224 _size=0;
225 }
226
227 /* ------------------------------------------------------------ */
228 public void close()
229 {}
230
231 /* ------------------------------------------------------------ */
232 public void destroy()
233 {
234 _buf=null;
235 }
236
237 /* ------------------------------------------------------------ */
238 public void ensureSpareCapacity(int n)
239 throws IOException
240 {
241 if (_size+n>_buf.length)
242 {
243 if (_fixed)
244 throw new IOException("Buffer overflow: "+_buf.length);
245 byte[] buf = new byte[(_buf.length+n)*4/3];
246 System.arraycopy(_buf,0,buf,0,_size);
247 _buf=buf;
248 }
249 }
250
251
252 /* ------------------------------------------------------------ */
253 public byte[] getByteArray()
254 {
255 byte[] data=new byte[_size];
256 System.arraycopy(_buf,0,data,0,_size);
257 return data;
258 }
259
260 }
261
262