View Javadoc

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