OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [java/] [io/] [OutputStreamWriter.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* OutputStreamWriter.java -- Writer that converts chars to bytes
2
   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package java.io;
40
 
41
import gnu.java.nio.charset.EncodingHelper;
42
 
43
import java.nio.ByteBuffer;
44
import java.nio.CharBuffer;
45
import java.nio.charset.CharacterCodingException;
46
import java.nio.charset.Charset;
47
import java.nio.charset.CharsetEncoder;
48
import java.nio.charset.CodingErrorAction;
49
import java.nio.charset.MalformedInputException;
50
 
51
/**
52
 * This class writes characters to an output stream that is byte oriented
53
 * It converts the chars that are written to bytes using an encoding layer,
54
 * which is specific to a particular encoding standard.  The desired
55
 * encoding can either be specified by name, or if no encoding is specified,
56
 * the system default encoding will be used.  The system default encoding
57
 * name is determined from the system property <code>file.encoding</code>.
58
 * The only encodings that are guaranteed to be available are "8859_1"
59
 * (the Latin-1 character set) and "UTF8".  Unfortunately, Java does not
60
 * provide a mechanism for listing the encodings that are supported in
61
 * a given implementation.
62
 * <p>
63
 * Here is a list of standard encoding names that may be available:
64
 * <p>
65
 * <ul>
66
 * <li>8859_1 (ISO-8859-1/Latin-1)
67
 * <li>8859_2 (ISO-8859-2/Latin-2)
68
 * <li>8859_3 (ISO-8859-3/Latin-3)
69
 * <li>8859_4 (ISO-8859-4/Latin-4)
70
 * <li>8859_5 (ISO-8859-5/Latin-5)
71
 * <li>8859_6 (ISO-8859-6/Latin-6)
72
 * <li>8859_7 (ISO-8859-7/Latin-7)
73
 * <li>8859_8 (ISO-8859-8/Latin-8)
74
 * <li>8859_9 (ISO-8859-9/Latin-9)
75
 * <li>ASCII (7-bit ASCII)
76
 * <li>UTF8 (UCS Transformation Format-8)
77
 * <li>More Later
78
 * </ul>
79
 *
80
 * @author Aaron M. Renn (arenn@urbanophile.com)
81
 * @author Per Bothner (bothner@cygnus.com)
82
 * @date April 17, 1998.
83
 */
84
public class OutputStreamWriter extends Writer
85
{
86
  /**
87
   * The output stream.
88
   */
89
  private OutputStream out;
90
 
91
  /**
92
   * The charset encoder.
93
   */
94
  private CharsetEncoder encoder;
95
 
96
  /**
97
   * java.io canonical name of the encoding.
98
   */
99
  private String encodingName;
100
 
101
  /**
102
   * Buffer output before character conversion as it has costly overhead.
103
   */
104
  private CharBuffer outputBuffer;
105
  private final static int BUFFER_SIZE = 1024;
106
 
107
  /**
108
   * This method initializes a new instance of <code>OutputStreamWriter</code>
109
   * to write to the specified stream using a caller supplied character
110
   * encoding scheme.  Note that due to a deficiency in the Java language
111
   * design, there is no way to determine which encodings are supported.
112
   *
113
   * @param out The <code>OutputStream</code> to write to
114
   * @param encoding_scheme The name of the encoding scheme to use for
115
   * character to byte translation
116
   *
117
   * @exception UnsupportedEncodingException If the named encoding is
118
   * not available.
119
   */
120
  public OutputStreamWriter (OutputStream out, String encoding_scheme)
121
    throws UnsupportedEncodingException
122
  {
123
    this.out = out;
124
    try
125
      {
126
        // Don't use NIO if avoidable
127
        if(EncodingHelper.isISOLatin1(encoding_scheme))
128
          {
129
            encodingName = "ISO8859_1";
130
            encoder = null;
131
            return;
132
          }
133
 
134
        /*
135
         * Workraround for encodings with a byte-order-mark.
136
         * We only want to write it once per stream.
137
         */
138
        try
139
          {
140
            if(encoding_scheme.equalsIgnoreCase("UnicodeBig") ||
141
               encoding_scheme.equalsIgnoreCase("UTF-16") ||
142
               encoding_scheme.equalsIgnoreCase("UTF16"))
143
              {
144
                encoding_scheme = "UTF-16BE";
145
                out.write((byte)0xFE);
146
                out.write((byte)0xFF);
147
              }
148
            else if(encoding_scheme.equalsIgnoreCase("UnicodeLittle")){
149
              encoding_scheme = "UTF-16LE";
150
              out.write((byte)0xFF);
151
              out.write((byte)0xFE);
152
            }
153
          }
154
        catch(IOException ioe)
155
          {
156
          }
157
 
158
        outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
159
 
160
        Charset cs = EncodingHelper.getCharset(encoding_scheme);
161
        if(cs == null)
162
          throw new UnsupportedEncodingException("Encoding "+encoding_scheme+
163
                                                 " unknown");
164
        encoder = cs.newEncoder();
165
        encodingName = EncodingHelper.getOldCanonical(cs.name());
166
 
167
        encoder.onMalformedInput(CodingErrorAction.REPLACE);
168
        encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
169
      }
170
    catch(RuntimeException e)
171
      {
172
        // Default to ISO Latin-1, will happen if this is called, for instance,
173
        //  before the NIO provider is loadable.
174
        encoder = null;
175
        encodingName = "ISO8859_1";
176
      }
177
  }
178
 
179
  /**
180
   * This method initializes a new instance of <code>OutputStreamWriter</code>
181
   * to write to the specified stream using the default encoding.
182
   *
183
   * @param out The <code>OutputStream</code> to write to
184
   */
185
  public OutputStreamWriter (OutputStream out)
186
  {
187
    this.out = out;
188
    outputBuffer = null;
189
    try
190
      {
191
        String encoding = System.getProperty("file.encoding");
192
        Charset cs = Charset.forName(encoding);
193
        encoder = cs.newEncoder();
194
        encodingName =  EncodingHelper.getOldCanonical(cs.name());
195
      }
196
    catch(RuntimeException e)
197
      {
198
        encoder = null;
199
        encodingName = "ISO8859_1";
200
      }
201
 
202
    if(encoder != null)
203
      {
204
        encoder.onMalformedInput(CodingErrorAction.REPLACE);
205
        encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
206
        outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
207
      }
208
  }
209
 
210
  /**
211
   * This method initializes a new instance of <code>OutputStreamWriter</code>
212
   * to write to the specified stream using a given <code>Charset</code>.
213
   *
214
   * @param out The <code>OutputStream</code> to write to
215
   * @param cs The <code>Charset</code> of the encoding to use
216
   */
217
  public OutputStreamWriter(OutputStream out, Charset cs)
218
  {
219
    this.out = out;
220
    encoder = cs.newEncoder();
221
    encoder.onMalformedInput(CodingErrorAction.REPLACE);
222
    encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
223
    outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
224
  }
225
 
226
  /**
227
   * This method initializes a new instance of <code>OutputStreamWriter</code>
228
   * to write to the specified stream using a given
229
   * <code>CharsetEncoder</code>.
230
   *
231
   * @param out The <code>OutputStream</code> to write to
232
   * @param enc The <code>CharsetEncoder</code> to encode the output with
233
   */
234
  public OutputStreamWriter(OutputStream out, CharsetEncoder enc)
235
  {
236
    this.out = out;
237
    encoder = enc;
238
    outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
239
  }
240
 
241
  /**
242
   * This method closes this stream, and the underlying
243
   * <code>OutputStream</code>
244
   *
245
   * @exception IOException If an error occurs
246
   */
247
  public void close () throws IOException
248
  {
249
    if(out == null)
250
      return;
251
    flush();
252
    out.close ();
253
    out = null;
254
  }
255
 
256
  /**
257
   * This method returns the name of the character encoding scheme currently
258
   * in use by this stream.  If the stream has been closed, then this method
259
   * may return <code>null</code>.
260
   *
261
   * @return The encoding scheme name
262
   */
263
  public String getEncoding ()
264
  {
265
    return out != null ? encodingName : null;
266
  }
267
 
268
  /**
269
   * This method flushes any buffered bytes to the underlying output sink.
270
   *
271
   * @exception IOException If an error occurs
272
   */
273
  public void flush () throws IOException
274
  {
275
      if(out != null){
276
          if(outputBuffer != null){
277
              char[] buf = new char[outputBuffer.position()];
278
              if(buf.length > 0){
279
                  outputBuffer.flip();
280
                  outputBuffer.get(buf);
281
                  writeConvert(buf, 0, buf.length);
282
                  outputBuffer.clear();
283
              }
284
          }
285
          out.flush ();
286
      }
287
  }
288
 
289
  /**
290
   * This method writes <code>count</code> characters from the specified
291
   * array to the output stream starting at position <code>offset</code>
292
   * into the array.
293
   *
294
   * @param buf The array of character to write from
295
   * @param offset The offset into the array to start writing chars from
296
   * @param count The number of chars to write.
297
   *
298
   * @exception IOException If an error occurs
299
   */
300
  public void write (char[] buf, int offset, int count) throws IOException
301
  {
302
    if(out == null)
303
      throw new IOException("Stream is closed.");
304
    if(buf == null)
305
      throw new IOException("Buffer is null.");
306
 
307
    if(outputBuffer != null)
308
        {
309
            if(count >= outputBuffer.remaining())
310
                {
311
                    int r = outputBuffer.remaining();
312
                    outputBuffer.put(buf, offset, r);
313
                    writeConvert(outputBuffer.array(), 0, BUFFER_SIZE);
314
                    outputBuffer.clear();
315
                    offset += r;
316
                    count -= r;
317
                    // if the remaining bytes is larger than the whole buffer, 
318
                    // just don't buffer.
319
                    if(count >= outputBuffer.remaining()){
320
                      writeConvert(buf, offset, count);
321
                      return;
322
                    }
323
                }
324
            outputBuffer.put(buf, offset, count);
325
        } else writeConvert(buf, offset, count);
326
  }
327
 
328
 /**
329
  * Converts and writes characters.
330
  */
331
  private void writeConvert (char[] buf, int offset, int count)
332
      throws IOException
333
  {
334
    if(encoder == null)
335
    {
336
      byte[] b = new byte[count];
337
      for(int i=0;i<count;i++)
338
        b[i] = (byte)((buf[offset+i] <= 0xFF)?buf[offset+i]:'?');
339
      out.write(b);
340
    } else {
341
      try  {
342
        ByteBuffer output = encoder.encode(CharBuffer.wrap(buf,offset,count));
343
        encoder.reset();
344
        if(output.hasArray())
345
          out.write(output.array());
346
        else
347
          {
348
            byte[] outbytes = new byte[output.remaining()];
349
            output.get(outbytes);
350
            out.write(outbytes);
351
          }
352
      } catch(IllegalStateException e) {
353
        throw new IOException("Internal error.");
354
      } catch(MalformedInputException e) {
355
        throw new IOException("Invalid character sequence.");
356
      } catch(CharacterCodingException e) {
357
        throw new IOException("Unmappable character.");
358
      }
359
    }
360
  }
361
 
362
  /**
363
   * This method writes <code>count</code> bytes from the specified
364
   * <code>String</code> starting at position <code>offset</code> into the
365
   * <code>String</code>.
366
   *
367
   * @param str The <code>String</code> to write chars from
368
   * @param offset The position in the <code>String</code> to start
369
   * writing chars from
370
   * @param count The number of chars to write
371
   *
372
   * @exception IOException If an error occurs
373
   */
374
  public void write (String str, int offset, int count) throws IOException
375
  {
376
    if(str == null)
377
      throw new IOException("String is null.");
378
 
379
    write(str.toCharArray(), offset, count);
380
  }
381
 
382
  /**
383
   * This method writes a single character to the output stream.
384
   *
385
   * @param ch The char to write, passed as an int.
386
   *
387
   * @exception IOException If an error occurs
388
   */
389
  public void write (int ch) throws IOException
390
  {
391
    write(new char[]{ (char)ch }, 0, 1);
392
  }
393
} // class OutputStreamWriter
394
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.