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