View Javadoc

1   // ========================================================================
2   // Copyright 2001-2005 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // Licensed under the Apache License, Version 2.0 (the "License");
5   // you may not use this file except in compliance with the License.
6   // You may obtain a copy of the License at 
7   // http://www.apache.org/licenses/LICENSE-2.0
8   // Unless required by applicable law or agreed to in writing, software
9   // distributed under the License is distributed on an "AS IS" BASIS,
10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  // See the License for the specific language governing permissions and
12  // limitations under the License.
13  // ========================================================================
14  
15  package org.mortbay.util;
16  import java.io.IOException;
17  import java.io.OutputStream;
18  import java.io.OutputStreamWriter;
19  import java.io.Writer;
20  
21  
22  /* ------------------------------------------------------------ */
23  /** Byte Array ISO 8859 writer. 
24   * This class combines the features of a OutputStreamWriter for
25   * ISO8859 encoding with that of a ByteArrayOutputStream.  It avoids
26   * many inefficiencies associated with these standard library classes.
27   * It has been optimized for standard ASCII characters.
28   * 
29   * @author Greg Wilkins (gregw)
30   */
31  public class ByteArrayISO8859Writer extends Writer
32  {
33      private byte[] _buf;
34      private int _size;
35      private ByteArrayOutputStream2 _bout=null;
36      private OutputStreamWriter _writer=null;
37      private boolean _fixed=false;
38  
39      /* ------------------------------------------------------------ */
40      /** Constructor. 
41       */
42      public ByteArrayISO8859Writer()
43      {
44          _buf=new byte[2048];
45      } 
46      
47      /* ------------------------------------------------------------ */
48      /** Constructor. 
49       * @param capacity Buffer capacity
50       */
51      public ByteArrayISO8859Writer(int capacity)
52      {
53          _buf=new byte[capacity];
54      }
55      
56      /* ------------------------------------------------------------ */
57      public ByteArrayISO8859Writer(byte[] buf)
58      {
59          _buf=buf;
60          _fixed=true;
61      }
62  
63      /* ------------------------------------------------------------ */
64      public Object getLock()
65      {
66          return lock;
67      }
68      
69      /* ------------------------------------------------------------ */
70      public int size()
71      {
72          return _size;
73      }
74      
75      /* ------------------------------------------------------------ */
76      public int capacity()
77      {
78          return _buf.length;
79      }
80  
81      /* ------------------------------------------------------------ */
82      public int spareCapacity()
83      {
84          return _buf.length-_size;
85      }
86      
87      /* ------------------------------------------------------------ */
88      public void setLength(int l)
89      {
90          _size=l;
91      }
92  
93      /* ------------------------------------------------------------ */
94      public byte[] getBuf()
95      {
96          return _buf;
97      }
98      
99      /* ------------------------------------------------------------ */
100     public void writeTo(OutputStream out)
101         throws IOException
102     {
103         out.write(_buf,0,_size);
104     }
105 
106     /* ------------------------------------------------------------ */
107     public void write(char c)
108         throws IOException
109     {
110         ensureSpareCapacity(1);
111         if (c>=0&&c<=0x7f)
112             _buf[_size++]=(byte)c;
113         else
114         {
115             char[] ca ={c};
116             writeEncoded(ca,0,1);
117         }
118     }
119     
120     /* ------------------------------------------------------------ */
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     public void write(char[] ca,int offset, int length)
140         throws IOException
141     {
142         ensureSpareCapacity(length);
143         for (int i=0;i<length;i++)
144         {
145             char c=ca[offset+i];
146             if (c>=0&&c<=0x7f)
147                 _buf[_size++]=(byte)c;
148             else
149             {
150                 writeEncoded(ca,offset+i,length-i);
151                 break;
152             }
153         }
154     }
155     
156     /* ------------------------------------------------------------ */
157     public void write(String s)
158         throws IOException
159     {
160         if (s==null)
161         {
162             write("null",0,4);
163             return;
164         }
165         
166         int length=s.length();
167         ensureSpareCapacity(length);
168         for (int i=0;i<length;i++)
169         {
170             char c=s.charAt(i);
171             if (c>=0x0&&c<=0x7f)
172                 _buf[_size++]=(byte)c;
173             else
174             {
175                 writeEncoded(s.toCharArray(),i,length-i);
176                 break;
177             }
178         }
179     }
180     
181     /* ------------------------------------------------------------ */
182     public void write(String s,int offset, int length)
183         throws IOException
184     {
185         ensureSpareCapacity(length);
186         for (int i=0;i<length;i++)
187         {
188             char c=s.charAt(offset+i);
189             if (c>=0&&c<=0x7f)
190                 _buf[_size++]=(byte)c;
191             else
192             {
193                 writeEncoded(s.toCharArray(),offset+i,length-i);
194                 break;
195             }
196         }
197     }
198 
199     /* ------------------------------------------------------------ */
200     private void writeEncoded(char[] ca,int offset, int length)
201         throws IOException
202     {
203         if (_bout==null)
204         {
205             _bout = new ByteArrayOutputStream2(2*length);
206             _writer = new OutputStreamWriter(_bout,StringUtil.__ISO_8859_1);
207         }
208         else
209             _bout.reset();
210         _writer.write(ca,offset,length);
211         _writer.flush();
212         ensureSpareCapacity(_bout.getCount());
213         System.arraycopy(_bout.getBuf(),0,_buf,_size,_bout.getCount());
214         _size+=_bout.getCount();
215     }
216     
217     /* ------------------------------------------------------------ */
218     public void flush()
219     {}
220 
221     /* ------------------------------------------------------------ */
222     public void resetWriter()
223     {
224         _size=0;
225     }
226 
227     /* ------------------------------------------------------------ */
228     public void close()
229     {}
230 
231     /* ------------------------------------------------------------ */
232     public void destroy()
233     {
234         _buf=null;
235     }
236     
237     /* ------------------------------------------------------------ */
238     public void ensureSpareCapacity(int n)
239         throws IOException
240     {
241         if (_size+n>_buf.length)
242         {
243             if (_fixed)
244                 throw new IOException("Buffer overflow: "+_buf.length);
245             byte[] buf = new byte[(_buf.length+n)*4/3];
246             System.arraycopy(_buf,0,buf,0,_size);
247             _buf=buf;
248         }
249     }
250 
251 
252     /* ------------------------------------------------------------ */
253     public byte[] getByteArray()
254     {
255         byte[] data=new byte[_size];
256         System.arraycopy(_buf,0,data,0,_size);
257         return data;
258     }
259     
260 }
261     
262