OSDN Git Service

2010-05-19 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / libjava / java / io / PrintStream.java
1 /* PrintStream.java -- OutputStream for printing output
2    Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005, 2006  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 java.util.Formatter;
42 import java.util.Locale;
43
44 import gnu.gcj.convert.UnicodeToBytes;
45
46 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
47  * "The Java Language Specification", ISBN 0-201-63451-1
48  * Status:  Believed complete and correct to 1.3
49  */
50
51 /**
52  * This class prints Java primitive values and object to a stream as
53  * text.  None of the methods in this class throw an exception.  However,
54  * errors can be detected by calling the <code>checkError()</code> method.
55  * Additionally, this stream can be designated as "autoflush" when 
56  * created so that any writes are automatically flushed to the underlying
57  * output sink when the current line is terminated.
58  * <p>
59  * This class converts char's into byte's using the system default encoding.
60  *
61  * @author Aaron M. Renn (arenn@urbanophile.com)
62  * @author Tom Tromey (tromey@cygnus.com)
63  */
64 public class PrintStream extends FilterOutputStream implements Appendable
65 {
66   /* Notice the implementation is quite similar to OutputStreamWriter.
67    * This leads to some minor duplication, because neither inherits
68    * from the other, and we want to maximize performance. */
69
70   // Line separator string.
71   private static final char[] line_separator
72     = System.getProperty("line.separator").toCharArray();
73   
74   UnicodeToBytes converter;
75
76   // Work buffer of characters for converter.
77   char[] work = new char[100];
78   // Work buffer of bytes where we temporarily keep converter output.
79   byte[] work_bytes = new byte[100];
80
81   /**
82    * This boolean indicates whether or not an error has ever occurred
83    * on this stream.
84    */
85   private boolean error_occurred = false;
86
87   /**
88    * This is <code>true</code> if auto-flush is enabled, 
89    * <code>false</code> otherwise
90    */
91   private boolean auto_flush;
92
93   /**
94    * This method intializes a new <code>PrintStream</code> object to write
95    * to the specified output sink.
96    *
97    * @param out The <code>OutputStream</code> to write to.
98    */
99   public PrintStream (OutputStream out)
100   {
101     this (out, false);
102   }
103
104   /**
105    * This method intializes a new <code>PrintStream</code> object to write
106    * to the specified output sink.  This constructor also allows "auto-flush"
107    * functionality to be specified where the stream will be flushed after
108    * every <code>print</code> or <code>println</code> call, when the 
109    * <code>write</code> methods with array arguments are called, or when a 
110    * single new-line character is written.
111    * <p>
112    *
113    * @param out The <code>OutputStream</code> to write to.
114    * @param auto_flush <code>true</code> to flush the stream after every 
115    * line, <code>false</code> otherwise
116    */
117   public PrintStream (OutputStream out, boolean auto_flush)
118   {
119     super (out);
120
121     converter = UnicodeToBytes.getDefaultEncoder();
122     this.auto_flush = auto_flush;
123   }
124
125   /**
126    * This method initializes a new <code>PrintStream</code> object to write
127    * to the specified output File. Doesn't autoflush.
128    *
129    * @param file The <code>File</code> to write to.
130    * @throws FileNotFoundException if an error occurs while opening the file.
131    *
132    * @since 1.5
133    */
134   public PrintStream (File file)
135     throws FileNotFoundException
136   {
137     this (new FileOutputStream(file), false);
138   }
139
140   /**
141    * This method initializes a new <code>PrintStream</code> object to write
142    * to the specified output File. Doesn't autoflush.
143    *
144    * @param file The <code>File</code> to write to.
145    * @param encoding The name of the character encoding to use for this
146    * object.
147    * @throws FileNotFoundException If an error occurs while opening the file.
148    * @throws UnsupportedEncodingException If the charset specified by
149    * <code>encoding</code> is invalid.
150    *
151    * @since 1.5
152    */
153   public PrintStream (File file, String encoding)
154     throws FileNotFoundException,UnsupportedEncodingException
155   {
156     this (new FileOutputStream(file), false, encoding);
157   }
158
159   /**
160    * This method initializes a new <code>PrintStream</code> object to write
161    * to the specified output File. Doesn't autoflush.
162    *
163    * @param fileName The name of the <code>File</code> to write to.
164    * @throws FileNotFoundException if an error occurs while opening the file,
165    *
166    * @since 1.5
167    */
168   public PrintStream (String fileName)
169     throws FileNotFoundException
170   {
171     this (new FileOutputStream(new File(fileName)), false);
172   }
173
174   /**
175    * This method initializes a new <code>PrintStream</code> object to write
176    * to the specified output File. Doesn't autoflush.
177    *
178    * @param fileName The name of the <code>File</code> to write to.
179    * @param encoding The name of the character encoding to use for this
180    * object.
181    * @throws FileNotFoundException if an error occurs while opening the file.
182    * @throws UnsupportedEncodingException If the charset specified by
183    * <code>encoding</code> is invalid.
184    *
185    * @since 1.5
186    */
187   public PrintStream (String fileName, String encoding)
188       throws FileNotFoundException,UnsupportedEncodingException
189   {
190     this (new FileOutputStream(new File(fileName)), false, encoding);
191   }
192
193   /**
194    * This method intializes a new <code>PrintStream</code> object to write
195    * to the specified output sink.  This constructor also allows "auto-flush"
196    * functionality to be specified where the stream will be flushed after
197    * every <code>print</code> or <code>println</code> call, when the 
198    * <code>write</code> methods with array arguments are called, or when a 
199    * single new-line character is written.
200    * <p>
201    *
202    * @param out The <code>OutputStream</code> to write to.
203    * @param auto_flush <code>true</code> to flush the stream after every 
204    * line, <code>false</code> otherwise
205    * @param encoding The name of the character encoding to use for this
206    * object.
207    */
208   public PrintStream (OutputStream out, boolean auto_flush, String encoding)
209     throws UnsupportedEncodingException
210   {
211     super (out);
212
213     converter = UnicodeToBytes.getEncoder (encoding);
214     this.auto_flush = auto_flush;
215   }
216
217   /**
218    * This method checks to see if an error has occurred on this stream.  Note
219    * that once an error has occurred, this method will continue to report
220    * <code>true</code> forever for this stream.  Before checking for an
221    * error condition, this method flushes the stream.
222    *
223    * @return <code>true</code> if an error has occurred, 
224    * <code>false</code> otherwise
225    */
226   public boolean checkError ()
227   {
228     flush ();
229     return error_occurred;
230   }
231
232   /**
233    * This method can be called by subclasses to indicate that an error
234    * has occurred and should be reported by <code>checkError</code>.
235    */
236   protected void setError ()
237   {
238     error_occurred = true;
239   }
240
241   /**
242    * This method closes this stream and all underlying streams.
243    */
244   public void close ()
245   {
246     try
247       {
248         converter.setFinished();
249         writeChars(new char[0], 0, 0);
250         flush();
251         out.close();
252       }
253     catch (InterruptedIOException iioe)
254       {
255         Thread.currentThread().interrupt();
256       }
257     catch (IOException e)
258       {
259         setError ();
260       }
261   }
262
263   /**
264    * This method flushes any buffered bytes to the underlying stream and
265    * then flushes that stream as well.
266    */
267   public void flush ()
268   {
269     try
270       {
271         out.flush();
272       }
273     catch (InterruptedIOException iioe)
274       {
275         Thread.currentThread().interrupt();
276       }
277     catch (IOException e)
278       {
279         setError ();
280       }
281   }
282
283   private synchronized void print (String str, boolean println)
284   {
285     try
286       {
287         writeChars(str, 0, str.length());
288         if (println)
289           writeChars(line_separator, 0, line_separator.length);
290         if (auto_flush)
291           flush();
292       }
293     catch (InterruptedIOException iioe)
294       {
295         Thread.currentThread().interrupt();
296       }
297     catch (IOException e)
298       {
299         setError ();
300       }
301   }
302
303   private synchronized void print (char[] chars, int pos, int len,
304                                    boolean println)
305   {
306     try
307       {
308         writeChars(chars, pos, len);
309         if (println)
310           writeChars(line_separator, 0, line_separator.length);
311         if (auto_flush)
312           flush();
313       }
314     catch (InterruptedIOException iioe)
315       {
316         Thread.currentThread().interrupt();
317       }
318     catch (IOException e)
319       {
320         setError ();
321       }
322   }
323
324   private void writeChars(char[] buf, int offset, int count)
325     throws IOException
326   {
327     do
328       {
329         converter.setOutput(work_bytes, 0);
330         int converted = converter.write(buf, offset, count);
331         offset += converted;
332         count -= converted;
333         out.write(work_bytes, 0, converter.count);
334       }
335     while (count > 0 || converter.havePendingBytes());
336   }
337
338   private void writeChars(String str, int offset, int count)
339     throws IOException
340   {
341     do
342       {
343         converter.setOutput(work_bytes, 0);
344         int converted = converter.write(str, offset, count, work);
345         offset += converted;
346         count -= converted;
347         out.write(work_bytes, 0, converter.count);
348       }
349     while (count > 0 || converter.havePendingBytes());
350   }
351
352   /**
353    * This methods prints a boolean value to the stream.  <code>true</code>
354    * values are printed as "true" and <code>false</code> values are printed
355    * as "false".
356    *
357    * @param bool The <code>boolean</code> value to print
358    */
359   public void print (boolean bool)
360   {
361     print(String.valueOf(bool), false);
362   }
363
364   /**
365    * This method prints an integer to the stream.  The value printed is
366    * determined using the <code>String.valueOf()</code> method.
367    *
368    * @param inum The <code>int</code> value to be printed
369    */
370   public void print (int inum)
371   {
372     print(String.valueOf(inum), false);
373   }
374
375   /**
376    * This method prints a long to the stream.  The value printed is
377    * determined using the <code>String.valueOf()</code> method.
378    *
379    * @param lnum The <code>long</code> value to be printed
380    */
381   public void print (long lnum)
382   {
383     print(String.valueOf(lnum), false);
384   }
385
386   /**
387    * This method prints a float to the stream.  The value printed is
388    * determined using the <code>String.valueOf()</code> method.
389    *
390    * @param fnum The <code>float</code> value to be printed
391    */
392   public void print (float fnum)
393   {
394     print(String.valueOf(fnum), false);
395   }
396
397   /**
398    * This method prints a double to the stream.  The value printed is
399    * determined using the <code>String.valueOf()</code> method.
400    *
401    * @param dnum The <code>double</code> value to be printed
402    */
403   public void print (double dnum)
404   {
405     print(String.valueOf(dnum), false);
406   }
407
408   /**
409    * This method prints an <code>Object</code> to the stream.  The actual
410    * value printed is determined by calling the <code>String.valueOf()</code>
411    * method.
412    *
413    * @param obj The <code>Object</code> to print.
414    */
415   public void print (Object obj)
416   {
417     print(obj == null ? "null" : obj.toString(), false);
418   }
419
420   /**
421    * This method prints a <code>String</code> to the stream.  The actual
422    * value printed depends on the system default encoding.
423    *
424    * @param str The <code>String</code> to print.
425    */
426   public void print (String str)
427   {
428     print(str == null ? "null" : str, false);
429   }
430
431   /**
432    * This method prints a char to the stream.  The actual value printed is
433    * determined by the character encoding in use.
434    *
435    * @param ch The <code>char</code> value to be printed
436    */
437   public synchronized void print (char ch)
438   {
439     work[0] = ch;
440     print(work, 0, 1, false);
441   }
442
443   /**
444    * This method prints an array of characters to the stream.  The actual
445    * value printed depends on the system default encoding.
446    *
447    * @param charArray The array of characters to print.
448    */
449   public void print (char[] charArray)
450   {
451     print(charArray, 0, charArray.length, false);
452   }
453
454   /**
455    * This method prints a line separator sequence to the stream.  The value
456    * printed is determined by the system property <xmp>line.separator</xmp>
457    * and is not necessarily the Unix '\n' newline character.
458    */
459   public void println ()
460   {
461     print(line_separator, 0, line_separator.length, false);
462   }
463
464   /**
465    * This methods prints a boolean value to the stream.  <code>true</code>
466    * values are printed as "true" and <code>false</code> values are printed
467    * as "false".
468    * <p>
469    * This method prints a line termination sequence after printing the value.
470    *
471    * @param bool The <code>boolean</code> value to print
472    */
473   public void println (boolean bool)
474   {
475     print(String.valueOf(bool), true);
476   }
477
478   /**
479    * This method prints an integer to the stream.  The value printed is
480    * determined using the <code>String.valueOf()</code> method.
481    * <p>
482    * This method prints a line termination sequence after printing the value.
483    *
484    * @param inum The <code>int</code> value to be printed
485    */
486   public void println (int inum)
487   {
488     print(String.valueOf(inum), true);
489   }
490
491   /**
492    * This method prints a long to the stream.  The value printed is
493    * determined using the <code>String.valueOf()</code> method.
494    * <p>
495    * This method prints a line termination sequence after printing the value.
496    *
497    * @param lnum The <code>long</code> value to be printed
498    */
499   public void println (long lnum)
500   {
501     print(String.valueOf(lnum), true);
502   }
503
504   /**
505    * This method prints a float to the stream.  The value printed is
506    * determined using the <code>String.valueOf()</code> method.
507    * <p>
508    * This method prints a line termination sequence after printing the value.
509    *
510    * @param fnum The <code>float</code> value to be printed
511    */
512   public void println (float fnum)
513   {
514     print(String.valueOf(fnum), true);
515   }
516
517   /**
518    * This method prints a double to the stream.  The value printed is
519    * determined using the <code>String.valueOf()</code> method.
520    * <p>
521    * This method prints a line termination sequence after printing the value.
522    *
523    * @param dnum The <code>double</code> value to be printed
524    */
525   public void println (double dnum)
526   {
527     print(String.valueOf(dnum), true);
528   }
529
530   /**
531    * This method prints an <code>Object</code> to the stream.  The actual
532    * value printed is determined by calling the <code>String.valueOf()</code>
533    * method.
534    * <p>
535    * This method prints a line termination sequence after printing the value.
536    *
537    * @param obj The <code>Object</code> to print.
538    */
539   public void println (Object obj)
540   {
541     print(obj == null ? "null" : obj.toString(), true);
542   }
543
544   /**
545    * This method prints a <code>String</code> to the stream.  The actual
546    * value printed depends on the system default encoding.
547    * <p>
548    * This method prints a line termination sequence after printing the value.
549    *
550    * @param str The <code>String</code> to print.
551    */
552   public void println (String str)
553   {
554     print (str == null ? "null" : str, true);
555   }
556
557   /**
558    * This method prints a char to the stream.  The actual value printed is
559    * determined by the character encoding in use.
560    * <p>
561    * This method prints a line termination sequence after printing the value.
562    *
563    * @param ch The <code>char</code> value to be printed
564    */
565   public synchronized void println (char ch)
566   {
567     work[0] = ch;
568     print(work, 0, 1, true);
569   }
570
571   /**
572    * This method prints an array of characters to the stream.  The actual
573    * value printed depends on the system default encoding.
574    * <p>
575    * This method prints a line termination sequence after printing the value.
576    *
577    * @param charArray The array of characters to print.
578    */
579   public void println (char[] charArray)
580   {
581     print(charArray, 0, charArray.length, true);
582   }
583
584   /**
585    * This method writes a byte of data to the stream.  If auto-flush is
586    * enabled, printing a newline character will cause the stream to be
587    * flushed after the character is written.
588    * 
589    * @param oneByte The byte to be written
590    */
591   public void write (int oneByte)
592   {
593     try
594       {
595         out.write (oneByte & 0xff);
596         
597         if (auto_flush && (oneByte == '\n'))
598           flush ();
599       }
600     catch (InterruptedIOException iioe)
601       {
602         Thread.currentThread ().interrupt ();
603       }
604     catch (IOException e)
605       {
606         setError ();
607       }
608   }
609
610   /**
611    * This method writes <code>len</code> bytes from the specified array
612    * starting at index <code>offset</code> into the array.
613    *
614    * @param buffer The array of bytes to write
615    * @param offset The index into the array to start writing from
616    * @param len The number of bytes to write
617    */
618   public void write (byte[] buffer, int offset, int len)
619   {
620     try
621       {
622         out.write (buffer, offset, len);
623         
624         if (auto_flush)
625           flush ();
626       }
627     catch (InterruptedIOException iioe)
628       {
629         Thread.currentThread ().interrupt ();
630       }
631     catch (IOException e)
632       {
633         setError ();
634       }
635   }
636
637   /** @since 1.5 */
638   public PrintStream append(char c)
639   {
640     print(c);
641     return this;
642   }
643
644   /** @since 1.5 */
645   public PrintStream append(CharSequence cs)
646   {
647     print(cs == null ? "null" : cs.toString());
648     return this;
649   }
650
651   /** @since 1.5 */
652   public PrintStream append(CharSequence cs, int start, int end)
653   {
654     print(cs == null ? "null" : cs.subSequence(start, end).toString());
655     return this;
656   }
657
658   /** @since 1.5 */
659   public PrintStream printf(String format, Object... args)
660   {
661     return format(format, args);
662   }
663
664   /** @since 1.5 */
665   public PrintStream printf(Locale locale, String format, Object... args)
666   {
667     return format(locale, format, args);
668   }
669
670   /** @since 1.5 */
671   public PrintStream format(String format, Object... args)
672   {
673     return format(Locale.getDefault(), format, args);
674   }
675
676   /** @since 1.5 */
677   public PrintStream format(Locale locale, String format, Object... args)
678   {
679     Formatter f = new Formatter(this, locale);
680     f.format(format, args);
681     return this;
682   }
683 } // class PrintStream
684