Merge from mainline.
[official-gcc.git] / libjava / classpath / java / io / DataOutputStream.java
blob6670c2dba1391248e261ab4a960cc2df2e94eeca
1 /* DataOutputStream.java -- Writes primitive Java datatypes to streams
2 Copyright (C) 1998, 2001, 2003, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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.
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.
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.
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.
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. */
39 package java.io;
41 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
42 * "The Java Language Specification", ISBN 0-201-63451-1
43 * Status: Complete to version 1.1.
46 /**
47 * This class provides a mechanism for writing primitive Java datatypes
48 * to an <code>OutputStream</code> in a portable way. Data written to
49 * a stream using this class can be read back in using the
50 * <code>DataInputStream</code> class on any platform.
52 * @see DataInputStream
54 * @author Aaron M. Renn (arenn@urbanophile.com)
55 * @author Tom Tromey (tromey@cygnus.com)
57 public class DataOutputStream extends FilterOutputStream implements DataOutput
59 /**
60 * This is the total number of bytes that have been written to the
61 * stream by this object instance.
63 protected int written;
65 /**
66 * Utf8 byte buffer, used by writeUTF()
68 private byte[] buf;
70 /**
71 * This method initializes an instance of <code>DataOutputStream</code> to
72 * write its data to the specified underlying <code>OutputStream</code>
74 * @param out The subordinate <code>OutputStream</code> to which this
75 * object will write
77 public DataOutputStream (OutputStream out)
79 super (out);
80 written = 0;
83 /**
84 * This method flushes any unwritten bytes to the underlying stream.
86 * @exception IOException If an error occurs.
88 public void flush () throws IOException
90 out.flush();
93 /**
94 * This method returns the total number of bytes that have been written to
95 * the underlying output stream so far. This is the value of the
96 * <code>written</code> instance variable
98 * @return The number of bytes written to the stream.
100 public final int size ()
102 return written;
106 * This method writes the specified byte (passed as an <code>int</code>)
107 * to the underlying output stream.
109 * @param value The <code>byte</code> to write, passed as an <code>int</code>.
111 * @exception IOException If an error occurs.
113 public synchronized void write (int value) throws IOException
115 out.write (value);
116 ++written;
120 * This method writes <code>len</code> bytes from the specified byte array
121 * <code>buf</code> starting at position <code>offset</code> into the
122 * buffer to the underlying output stream.
124 * @param buf The byte array to write from.
125 * @param offset The index into the byte array to start writing from.
126 * @param len The number of bytes to write.
128 * @exception IOException If an error occurs.
130 public synchronized void write (byte[] buf, int offset, int len)
131 throws IOException
133 out.write(buf, offset, len);
134 written += len;
138 * This method writes a Java boolean value to an output stream. If
139 * <code>value</code> is <code>true</code>, a byte with the value of
140 * 1 will be written, otherwise a byte with the value of 0 will be
141 * written.
143 * The value written can be read using the <code>readBoolean</code>
144 * method in <code>DataInput</code>.
146 * @param value The <code>boolean</code> value to write to the stream
148 * @exception IOException If an error occurs
150 * @see DataInput#readBoolean
152 public final void writeBoolean (boolean value) throws IOException
154 write (value ? 1 : 0);
158 * This method writes a Java byte value to an output stream. The
159 * byte to be written will be in the lowest 8 bits of the
160 * <code>int</code> value passed.
162 * The value written can be read using the <code>readByte</code> or
163 * <code>readUnsignedByte</code> methods in <code>DataInput</code>.
165 * @param value The <code>byte</code> to write to the stream, passed as
166 * the low eight bits of an <code>int</code>.
168 * @exception IOException If an error occurs
170 * @see DataInput#readByte
171 * @see DataInput#readUnsignedByte
173 public final void writeByte (int value) throws IOException
175 write (value & 0xff);
179 * This method writes a Java short value to an output stream. The
180 * char to be written will be in the lowest 16 bits of the <code>int</code>
181 * value passed. These bytes will be written "big endian". That is,
182 * with the high byte written first in the following manner:
183 * <p>
184 * <code>byte0 = (byte)((value & 0xFF00) >> 8);<br>
185 * byte1 = (byte)(value & 0x00FF);</code>
186 * <p>
188 * The value written can be read using the <code>readShort</code> and
189 * <code>readUnsignedShort</code> methods in <code>DataInput</code>.
191 * @param value The <code>short</code> value to write to the stream,
192 * passed as an <code>int</code>.
194 * @exception IOException If an error occurs
196 * @see DataInput#readShort
197 * @see DataInput#readUnsignedShort
199 public final synchronized void writeShort (int value) throws IOException
201 write ((byte) (0xff & (value >> 8)));
202 write ((byte) (0xff & value));
206 * This method writes a Java char value to an output stream. The
207 * char to be written will be in the lowest 16 bits of the <code>int</code>
208 * value passed. These bytes will be written "big endian". That is,
209 * with the high byte written first in the following manner:
210 * <p>
211 * <code>byte0 = (byte)((value & 0xFF00) >> 8);<br>
212 * byte1 = (byte)(value & 0x00FF);</code>
213 * <p>
215 * The value written can be read using the <code>readChar</code>
216 * method in <code>DataInput</code>.
218 * @param value The <code>char</code> value to write,
219 * passed as an <code>int</code>.
221 * @exception IOException If an error occurs
223 * @see DataInput#readChar
225 public final synchronized void writeChar (int value) throws IOException
227 write ((byte) (0xff & (value >> 8)));
228 write ((byte) (0xff & value));
232 * This method writes a Java int value to an output stream. The 4 bytes
233 * of the passed value will be written "big endian". That is, with
234 * the high byte written first in the following manner:
235 * <p>
236 * <code>byte0 = (byte)((value & 0xFF000000) >> 24);<br>
237 * byte1 = (byte)((value & 0x00FF0000) >> 16);<br>
238 * byte2 = (byte)((value & 0x0000FF00) >> 8);<br>
239 * byte3 = (byte)(value & 0x000000FF);</code>
240 * <p>
242 * The value written can be read using the <code>readInt</code>
243 * method in <code>DataInput</code>.
245 * @param value The <code>int</code> value to write to the stream
247 * @exception IOException If an error occurs
249 * @see DataInput#readInt
251 public final synchronized void writeInt (int value) throws IOException
253 write ((byte) (0xff & (value >> 24)));
254 write ((byte) (0xff & (value >> 16)));
255 write ((byte) (0xff & (value >> 8)));
256 write ((byte) (0xff & value));
260 * This method writes a Java long value to an output stream. The 8 bytes
261 * of the passed value will be written "big endian". That is, with
262 * the high byte written first in the following manner:
263 * <p>
264 * <code>byte0 = (byte)((value & 0xFF00000000000000L) >> 56);<br>
265 * byte1 = (byte)((value & 0x00FF000000000000L) >> 48);<br>
266 * byte2 = (byte)((value & 0x0000FF0000000000L) >> 40);<br>
267 * byte3 = (byte)((value & 0x000000FF00000000L) >> 32);<br>
268 * byte4 = (byte)((value & 0x00000000FF000000L) >> 24);<br>
269 * byte5 = (byte)((value & 0x0000000000FF0000L) >> 16);<br>
270 * byte6 = (byte)((value & 0x000000000000FF00L) >> 8);<br>
271 * byte7 = (byte)(value & 0x00000000000000FFL);</code>
272 * <p>
274 * The value written can be read using the <code>readLong</code>
275 * method in <code>DataInput</code>.
277 * @param value The <code>long</code> value to write to the stream
279 * @exception IOException If an error occurs
281 * @see DataInput#readLong
283 public final synchronized void writeLong (long value) throws IOException
285 write ((byte) (0xff & (value >> 56)));
286 write ((byte) (0xff & (value>> 48)));
287 write ((byte) (0xff & (value>> 40)));
288 write ((byte) (0xff & (value>> 32)));
289 write ((byte) (0xff & (value>> 24)));
290 write ((byte) (0xff & (value>> 16)));
291 write ((byte) (0xff & (value>> 8)));
292 write ((byte) (0xff & value));
296 * This method writes a Java <code>float</code> value to the stream. This
297 * value is written by first calling the method
298 * <code>Float.floatToIntBits</code>
299 * to retrieve an <code>int</code> representing the floating point number,
300 * then writing this <code>int</code> value to the stream exactly the same
301 * as the <code>writeInt()</code> method does.
303 * The value written can be read using the <code>readFloat</code>
304 * method in <code>DataInput</code>.
306 * @param value The <code>float</code> value to write to the stream
308 * @exception IOException If an error occurs
310 * @see #writeInt(int)
311 * @see DataInput#readFloat
312 * @see Float#floatToIntBits
314 public final void writeFloat (float value) throws IOException
316 writeInt (Float.floatToIntBits (value));
320 * This method writes a Java <code>double</code> value to the stream. This
321 * value is written by first calling the method
322 * <code>Double.doubleToLongBits</code>
323 * to retrieve an <code>long</code> representing the floating point number,
324 * then writing this <code>long</code> value to the stream exactly the same
325 * as the <code>writeLong()</code> method does.
327 * The value written can be read using the <code>readDouble</code>
328 * method in <code>DataInput</code>.
330 * @param value The <code>double</code> value to write to the stream
332 * @exception IOException If an error occurs
334 * @see #writeLong(long)
335 * @see DataInput#readDouble
336 * @see Double#doubleToLongBits
338 public final void writeDouble (double value) throws IOException
340 writeLong (Double.doubleToLongBits (value));
344 * This method writes all the bytes in a <code>String</code> out to the
345 * stream. One byte is written for each character in the
346 * <code>String</code>.
347 * The high eight bits of each character are discarded, thus this
348 * method is inappropriate for completely representing Unicode characters.
350 * @param value The <code>String</code> to write to the stream
352 * @exception IOException If an error occurs
354 public final void writeBytes (String value) throws IOException
356 int len = value.length();
357 for (int i = 0; i < len; ++i)
358 writeByte (value.charAt(i));
362 * This method writes all the characters of a <code>String</code> to an
363 * output stream as an array of <code>char</code>'s. Each character
364 * is written using the method specified in the <code>writeChar</code>
365 * method.
367 * @param value The <code>String</code> to write to the stream
369 * @exception IOException If an error occurs
371 * @see #writeChar(char)
373 public final void writeChars (String value) throws IOException
375 int len = value.length();
376 for (int i = 0; i < len; ++i)
377 writeChar (value.charAt(i));
381 * Calculate the length, in bytes, of a <code>String</code> in Utf8 format.
383 * @param value The <code>String</code> to measure
384 * @param start String index at which to begin count
385 * @param sum Starting Utf8 byte count
387 * @throws UTFDataFormatException if result would exceed 65535
389 private int getUTFlength(String value, int start, int sum)
390 throws IOException
392 int len = value.length();
394 for (int i = start; i < len && sum <= 65535; ++i)
396 char c = value.charAt(i);
397 if (c >= '\u0001' && c <= '\u007f')
398 sum += 1;
399 else if (c == '\u0000' || (c >= '\u0080' && c <= '\u07ff'))
400 sum += 2;
401 else
402 sum += 3;
405 if (sum > 65535)
406 throw new UTFDataFormatException ();
408 return sum;
412 * This method writes a Java <code>String</code> to the stream in a modified
413 * UTF-8 format. First, two bytes are written to the stream indicating the
414 * number of bytes to follow. Note that this is the number of bytes in the
415 * encoded <code>String</code> not the <code>String</code> length. Next
416 * come the encoded characters. Each character in the <code>String</code>
417 * is encoded as either one, two or three bytes. For characters in the
418 * range of <code>\u0001</code> to <\u007F>, one byte is used. The character
419 * value goes into bits 0-7 and bit eight is 0. For characters in the range
420 * of <code>\u0080</code> to <code>\u007FF</code>, two bytes are used. Bits
421 * 6-10 of the character value are encoded bits 0-4 of the first byte, with
422 * the high bytes having a value of "110". Bits 0-5 of the character value
423 * are stored in bits 0-5 of the second byte, with the high bits set to
424 * "10". This type of encoding is also done for the null character
425 * <code>\u0000</code>. This eliminates any C style NUL character values
426 * in the output. All remaining characters are stored as three bytes.
427 * Bits 12-15 of the character value are stored in bits 0-3 of the first
428 * byte. The high bits of the first bytes are set to "1110". Bits 6-11
429 * of the character value are stored in bits 0-5 of the second byte. The
430 * high bits of the second byte are set to "10". And bits 0-5 of the
431 * character value are stored in bits 0-5 of byte three, with the high bits
432 * of that byte set to "10".
434 * The value written can be read using the <code>readUTF</code>
435 * method in <code>DataInput</code>.
437 * @param value The <code>String</code> to write to the output in UTF format
439 * @exception IOException If an error occurs
441 * @see DataInput#readUTF
443 public final synchronized void writeUTF(String value) throws IOException
445 int len = value.length();
446 int i = 0;
447 int pos = 0;
448 boolean lengthWritten = false;
450 if (buf == null)
451 buf = new byte[512];
455 while (i < len && pos < buf.length - 3)
457 char c = value.charAt(i++);
458 if (c >= '\u0001' && c <= '\u007f')
459 buf[pos++] = (byte) c;
460 else if (c == '\u0000' || (c >= '\u0080' && c <= '\u07ff'))
462 buf[pos++] = (byte) (0xc0 | (0x1f & (c >> 6)));
463 buf[pos++] = (byte) (0x80 | (0x3f & c));
465 else
467 // JSL says the first byte should be or'd with 0xc0, but
468 // that is a typo. Unicode says 0xe0, and that is what is
469 // consistent with DataInputStream.
470 buf[pos++] = (byte) (0xe0 | (0x0f & (c >> 12)));
471 buf[pos++] = (byte) (0x80 | (0x3f & (c >> 6)));
472 buf[pos++] = (byte) (0x80 | (0x3f & c));
475 if (! lengthWritten)
477 if (i == len)
478 writeShort(pos);
479 else
480 writeShort(getUTFlength(value, i, pos));
481 lengthWritten = true;
483 write(buf, 0, pos);
484 pos = 0;
486 while (i < len);
489 } // class DataOutputStream