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     public void write(char[] ca)
121         throws IOException
122     {
123         ensureSpareCapacity(ca.length);
124         for (int i=0;i<ca.length;i++)
125         {
126             char c=ca[i];
127             if (c>=0&&c<=0x7f)
128                 _buf[_size++]=(byte)c;
129             else
130             {
131                 writeEncoded(ca,i,ca.length-i);
132                 break;
133             }
134         }
135     }
136     
137     /* ------------------------------------------------------------ */
138     public void write(char[] ca,int offset, int length)
139         throws IOException
140     {
141         ensureSpareCapacity(length);
142         for (int i=0;i<length;i++)
143         {
144             char c=ca[offset+i];
145             if (c>=0&&c<=0x7f)
146                 _buf[_size++]=(byte)c;
147             else
148             {
149                 writeEncoded(ca,offset+i,length-i);
150                 break;
151             }
152         }
153     }
154     
155     /* ------------------------------------------------------------ */
156     public void write(String s)
157         throws IOException
158     {
159         if (s==null)
160         {
161             write("null",0,4);
162             return;
163         }
164         
165         int length=s.length();
166         ensureSpareCapacity(length);
167         for (int i=0;i<length;i++)
168         {
169             char c=s.charAt(i);
170             if (c>=0x0&&c<=0x7f)
171                 _buf[_size++]=(byte)c;
172             else
173             {
174                 writeEncoded(s.toCharArray(),i,length-i);
175                 break;
176             }
177         }
178     }
179     
180     /* ------------------------------------------------------------ */
181     public void write(String s,int offset, int length)
182         throws IOException
183     {
184         ensureSpareCapacity(length);
185         for (int i=0;i<length;i++)
186         {
187             char c=s.charAt(offset+i);
188             if (c>=0&&c<=0x7f)
189                 _buf[_size++]=(byte)c;
190             else
191             {
192                 writeEncoded(s.toCharArray(),offset+i,length-i);
193                 break;
194             }
195         }
196     }
197 
198     /* ------------------------------------------------------------ */
199     private void writeEncoded(char[] ca,int offset, int length)
200         throws IOException
201     {
202         if (_bout==null)
203         {
204             _bout = new ByteArrayOutputStream2(2*length);
205             _writer = new OutputStreamWriter(_bout,StringUtil.__ISO_8859_1);
206         }
207         else
208             _bout.reset();
209         _writer.write(ca,offset,length);
210         _writer.flush();
211         ensureSpareCapacity(_bout.getCount());
212         System.arraycopy(_bout.getBuf(),0,_buf,_size,_bout.getCount());
213         _size+=_bout.getCount();
214     }
215     
216     /* ------------------------------------------------------------ */
217     public void flush()
218     {}
219 
220     /* ------------------------------------------------------------ */
221     public void resetWriter()
222     {
223         _size=0;
224     }
225 
226     /* ------------------------------------------------------------ */
227     public void close()
228     {}
229 
230     /* ------------------------------------------------------------ */
231     public void destroy()
232     {
233         _buf=null;
234     }
235     
236     /* ------------------------------------------------------------ */
237     public void ensureSpareCapacity(int n)
238         throws IOException
239     {
240         if (_size+n>_buf.length)
241         {
242             if (_fixed)
243                 throw new IOException("Buffer overflow: "+_buf.length);
244             byte[] buf = new byte[(_buf.length+n)*4/3];
245             System.arraycopy(_buf,0,buf,0,_size);
246             _buf=buf;
247         }
248     }
249 
250 
251     /* ------------------------------------------------------------ */
252     public byte[] getByteArray()
253     {
254         byte[] data=new byte[_size];
255         System.arraycopy(_buf,0,data,0,_size);
256         return data;
257     }
258     
259 }
260     
261