View Javadoc

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