OSDN Git Service

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