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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [io/] [OutputStreamWriter.java] - Blame information for rev 791

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* 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 final CharsetEncoder encoder;
95
 
96
  /**
97
   * java.io canonical name of the encoding.
98
   */
99
  private final String encodingName;
100
 
101
  /**
102
   * Buffer output before character conversion as it has costly overhead.
103
   */
104
  private final 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
    CharsetEncoder encoder;
124
    String encodingName;
125
    this.out = out;
126
    outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
127
 
128
    try
129
      {
130
        // Don't use NIO if avoidable
131
        if(EncodingHelper.isISOLatin1(encoding_scheme))
132
          {
133
            encodingName = "ISO8859_1";
134
            encoder = null;
135
          }
136
       else
137
         {
138
           /*
139
            * Workaround for encodings with a byte-order-mark.
140
            * We only want to write it once per stream.
141
            */
142
           try
143
             {
144
               if(encoding_scheme.equalsIgnoreCase("UnicodeBig") ||
145
                  encoding_scheme.equalsIgnoreCase("UTF-16") ||
146
                  encoding_scheme.equalsIgnoreCase("UTF16"))
147
                 {
148
                   encoding_scheme = "UTF-16BE";
149
                   out.write((byte)0xFE);
150
                   out.write((byte)0xFF);
151
                 }
152
               else if(encoding_scheme.equalsIgnoreCase("UnicodeLittle"))
153
                 {
154
                   encoding_scheme = "UTF-16LE";
155
                   out.write((byte)0xFF);
156
                   out.write((byte)0xFE);
157
                 }
158
             }
159
           catch(IOException ioe)
160
             {
161
             }
162
 
163
           Charset cs = EncodingHelper.getCharset(encoding_scheme);
164
           if(cs == null)
165
             throw new UnsupportedEncodingException("Encoding "+encoding_scheme+
166
                                                    " unknown");
167
           encoder = cs.newEncoder();
168
           encodingName = EncodingHelper.getOldCanonical(cs.name());
169
 
170
           encoder.onMalformedInput(CodingErrorAction.REPLACE);
171
           encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
172
         }
173
      }
174
    catch(RuntimeException e)
175
      {
176
        // Default to ISO Latin-1, will happen if this is called, for instance,
177
        //  before the NIO provider is loadable.
178
        encoder = null;
179
        encodingName = "ISO8859_1";
180
      }
181
    this.encoder = encoder;
182
    this.encodingName = encodingName;
183
  }
184
 
185
  /**
186
   * This method initializes a new instance of <code>OutputStreamWriter</code>
187
   * to write to the specified stream using the default encoding.
188
   *
189
   * @param out The <code>OutputStream</code> to write to
190
   */
191
  public OutputStreamWriter (OutputStream out)
192
  {
193
    CharsetEncoder encoder;
194
    String encodingName;
195
    this.out = out;
196
    outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
197
    try
198
      {
199
        String encoding = System.getProperty("file.encoding");
200
        Charset cs = Charset.forName(encoding);
201
        encoder = cs.newEncoder();
202
        encodingName =  EncodingHelper.getOldCanonical(cs.name());
203
      }
204
    catch(RuntimeException e)
205
      {
206
        encoder = null;
207
        encodingName = "ISO8859_1";
208
      }
209
 
210
    if(encoder != null)
211
      {
212
        encoder.onMalformedInput(CodingErrorAction.REPLACE);
213
        encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
214
      }
215
    this.encoder = encoder;
216
    this.encodingName = encodingName;
217
  }
218
 
219
  /**
220
   * This method initializes a new instance of <code>OutputStreamWriter</code>
221
   * to write to the specified stream using a given <code>Charset</code>.
222
   *
223
   * @param out The <code>OutputStream</code> to write to
224
   * @param cs The <code>Charset</code> of the encoding to use
225
   *
226
   * @since 1.5
227
   */
228
  public OutputStreamWriter(OutputStream out, Charset cs)
229
  {
230
    this.out = out;
231
    encoder = cs.newEncoder();
232
    encoder.onMalformedInput(CodingErrorAction.REPLACE);
233
    encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
234
    outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
235
    encodingName = EncodingHelper.getOldCanonical(cs.name());
236
  }
237
 
238
  /**
239
   * This method initializes a new instance of <code>OutputStreamWriter</code>
240
   * to write to the specified stream using a given
241
   * <code>CharsetEncoder</code>.
242
   *
243
   * @param out The <code>OutputStream</code> to write to
244
   * @param enc The <code>CharsetEncoder</code> to encode the output with
245
   *
246
   * @since 1.5
247
   */
248
  public OutputStreamWriter(OutputStream out, CharsetEncoder enc)
249
  {
250
    this.out = out;
251
    encoder = enc;
252
    outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
253
    Charset cs = enc.charset();
254
    if (cs == null)
255
      encodingName = "US-ASCII";
256
    else
257
      encodingName = EncodingHelper.getOldCanonical(cs.name());
258
  }
259
 
260
  /**
261
   * This method closes this stream, and the underlying
262
   * <code>OutputStream</code>
263
   *
264
   * @exception IOException If an error occurs
265
   */
266
  public void close () throws IOException
267
  {
268
    if(out == null)
269
      return;
270
    flush();
271
    out.close ();
272
    out = null;
273
  }
274
 
275
  /**
276
   * This method returns the name of the character encoding scheme currently
277
   * in use by this stream.  If the stream has been closed, then this method
278
   * may return <code>null</code>.
279
   *
280
   * @return The encoding scheme name
281
   */
282
  public String getEncoding ()
283
  {
284
    return out != null ? encodingName : null;
285
  }
286
 
287
  /**
288
   * This method flushes any buffered bytes to the underlying output sink.
289
   *
290
   * @exception IOException If an error occurs
291
   */
292
  public void flush () throws IOException
293
  {
294
      if(out != null){
295
          if(outputBuffer != null){
296
              char[] buf = new char[outputBuffer.position()];
297
              if(buf.length > 0){
298
                  outputBuffer.flip();
299
                  outputBuffer.get(buf);
300
                  writeConvert(buf, 0, buf.length);
301
                  outputBuffer.clear();
302
              }
303
          }
304
          out.flush ();
305
      }
306
  }
307
 
308
  /**
309
   * This method writes <code>count</code> characters from the specified
310
   * array to the output stream starting at position <code>offset</code>
311
   * into the array.
312
   *
313
   * @param buf The array of character to write from
314
   * @param offset The offset into the array to start writing chars from
315
   * @param count The number of chars to write.
316
   *
317
   * @exception IOException If an error occurs
318
   */
319
  public void write (char[] buf, int offset, int count) throws IOException
320
  {
321
    if(out == null)
322
      throw new IOException("Stream is closed.");
323
    if(buf == null)
324
      throw new IOException("Buffer is null.");
325
 
326
    if(outputBuffer != null)
327
        {
328
            if(count >= outputBuffer.remaining())
329
                {
330
                    int r = outputBuffer.remaining();
331
                    outputBuffer.put(buf, offset, r);
332
                    writeConvert(outputBuffer.array(), 0, BUFFER_SIZE);
333
                    outputBuffer.clear();
334
                    offset += r;
335
                    count -= r;
336
                    // if the remaining bytes is larger than the whole buffer,
337
                    // just don't buffer.
338
                    if(count >= outputBuffer.remaining()){
339
                      writeConvert(buf, offset, count);
340
                      return;
341
                    }
342
                }
343
            outputBuffer.put(buf, offset, count);
344
        } else writeConvert(buf, offset, count);
345
  }
346
 
347
 /**
348
  * Converts and writes characters.
349
  */
350
  private void writeConvert (char[] buf, int offset, int count)
351
      throws IOException
352
  {
353
    if(encoder == null)
354
    {
355
      byte[] b = new byte[count];
356
      for(int i=0;i<count;i++)
357
        b[i] = nullConversion(buf[offset+i]);
358
      out.write(b);
359
    } else {
360
      try  {
361
        ByteBuffer output = encoder.encode(CharBuffer.wrap(buf,offset,count));
362
        encoder.reset();
363
        if(output.hasArray())
364
          out.write(output.array());
365
        else
366
          {
367
            byte[] outbytes = new byte[output.remaining()];
368
            output.get(outbytes);
369
            out.write(outbytes);
370
          }
371
      } catch(IllegalStateException e) {
372
        throw new IOException("Internal error.");
373
      } catch(MalformedInputException e) {
374
        throw new IOException("Invalid character sequence.");
375
      } catch(CharacterCodingException e) {
376
        throw new IOException("Unmappable character.");
377
      }
378
    }
379
  }
380
 
381
  private byte nullConversion(char c) {
382
          return (byte)((c <= 0xFF)?c:'?');
383
  }
384
 
385
  /**
386
   * This method writes <code>count</code> bytes from the specified
387
   * <code>String</code> starting at position <code>offset</code> into the
388
   * <code>String</code>.
389
   *
390
   * @param str The <code>String</code> to write chars from
391
   * @param offset The position in the <code>String</code> to start
392
   * writing chars from
393
   * @param count The number of chars to write
394
   *
395
   * @exception IOException If an error occurs
396
   */
397
  public void write (String str, int offset, int count) throws IOException
398
  {
399
    if(str == null)
400
      throw new IOException("String is null.");
401
 
402
    write(str.toCharArray(), offset, count);
403
  }
404
 
405
  /**
406
   * This method writes a single character to the output stream.
407
   *
408
   * @param ch The char to write, passed as an int.
409
   *
410
   * @exception IOException If an error occurs
411
   */
412
  public void write (int ch) throws IOException
413
  {
414
          // No buffering, no encoding ... just pass through
415
          if (encoder == null && outputBuffer == null) {
416
                  out.write(nullConversion((char)ch));
417
          } else {
418
                  if (outputBuffer != null) {
419
                          if (outputBuffer.remaining() == 0) {
420
                                  writeConvert(outputBuffer.array(), 0, BUFFER_SIZE);
421
                                  outputBuffer.clear();
422
                          }
423
                          outputBuffer.put((char)ch);
424
                  } else {
425
                      writeConvert(new char[]{ (char)ch }, 0, 1);
426
                  }
427
          }
428
  }
429
} // class OutputStreamWriter

powered by: WebSVN 2.1.0

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