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  
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   */
35  public 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