OutputStream
in a portable way. Data written to
* a stream using this class can be read back in using the
* DataInputStream
class on any platform.
*
* @see DataInputStream
*
* @author Aaron M. Renn DataOutputStream
to
* write its data to the specified underlying OutputStream
*
* @param out The subordinate OutputStream
to which this
* object will write
*/
public DataOutputStream (OutputStream out)
{
super (out);
written = 0;
}
/**
* This method flushes any unwritten bytes to the underlying stream.
*
* @exception IOException If an error occurs.
*/
public void flush () throws IOException
{
out.flush();
}
/**
* This method returns the total number of bytes that have been written to
* the underlying output stream so far. This is the value of the
* written
instance variable
*
* @return The number of bytes written to the stream.
*/
public final int size ()
{
return written;
}
/**
* This method writes the specified byte (passed as an int
)
* to the underlying output stream.
*
* @param value The byte
to write, passed as an int
.
*
* @exception IOException If an error occurs.
*/
public synchronized void write (int value) throws IOException
{
out.write (value);
++written;
}
/**
* This method writes len
bytes from the specified byte array
* buf
starting at position offset
into the
* buffer to the underlying output stream.
*
* @param buf The byte array to write from.
* @param offset The index into the byte array to start writing from.
* @param len The number of bytes to write.
*
* @exception IOException If an error occurs.
*/
public synchronized void write (byte[] buf, int offset, int len)
throws IOException
{
out.write(buf, offset, len);
written += len;
}
/**
* This method writes a Java boolean value to an output stream. If
* value
is true
, a byte with the value of
* 1 will be written, otherwise a byte with the value of 0 will be
* written.
*
* The value written can be read using the readBoolean
* method in DataInput
.
*
* @param value The boolean
value to write to the stream
*
* @exception IOException If an error occurs
*
* @see DataInput#readBoolean
*/
public final void writeBoolean (boolean value) throws IOException
{
write (value ? 1 : 0);
}
/**
* This method writes a Java byte value to an output stream. The
* byte to be written will be in the lowest 8 bits of the
* int
value passed.
*
* The value written can be read using the readByte
or
* readUnsignedByte
methods in DataInput
.
*
* @param value The byte
to write to the stream, passed as
* the low eight bits of an int
.
*
* @exception IOException If an error occurs
*
* @see DataInput#readByte
* @see DataInput#readUnsignedByte
*/
public final void writeByte (int value) throws IOException
{
write (value & 0xff);
}
/**
* This method writes a Java short value to an output stream. The
* char to be written will be in the lowest 16 bits of the int
* value passed. These bytes will be written "big endian". That is,
* with the high byte written first in the following manner:
*
* byte0 = (byte)((value & 0xFF00) >> 8);
*
* byte1 = (byte)(value & 0x00FF);
*
* The value written can be read using the readShort
and
* readUnsignedShort
methods in DataInput
.
*
* @param value The short
value to write to the stream,
* passed as an int
.
*
* @exception IOException If an error occurs
*
* @see DataInput#readShort
* @see DataInput#readUnsignedShort
*/
public final synchronized void writeShort (int value) throws IOException
{
write ((byte) (0xff & (value >> 8)));
write ((byte) (0xff & value));
}
/**
* This method writes a Java char value to an output stream. The
* char to be written will be in the lowest 16 bits of the int
* value passed. These bytes will be written "big endian". That is,
* with the high byte written first in the following manner:
*
* byte0 = (byte)((value & 0xFF00) >> 8);
*
* byte1 = (byte)(value & 0x00FF);
*
* The value written can be read using the readChar
* method in DataInput
.
*
* @param value The char
value to write,
* passed as an int
.
*
* @exception IOException If an error occurs
*
* @see DataInput#readChar
*/
public final synchronized void writeChar (int value) throws IOException
{
write ((byte) (0xff & (value >> 8)));
write ((byte) (0xff & value));
}
/**
* This method writes a Java int value to an output stream. The 4 bytes
* of the passed value will be written "big endian". That is, with
* the high byte written first in the following manner:
*
* byte0 = (byte)((value & 0xFF000000) >> 24);
*
* byte1 = (byte)((value & 0x00FF0000) >> 16);
* byte2 = (byte)((value & 0x0000FF00) >> 8);
* byte3 = (byte)(value & 0x000000FF);
*
* The value written can be read using the readInt
* method in DataInput
.
*
* @param value The int
value to write to the stream
*
* @exception IOException If an error occurs
*
* @see DataInput#readInt
*/
public final synchronized void writeInt (int value) throws IOException
{
write ((byte) (0xff & (value >> 24)));
write ((byte) (0xff & (value >> 16)));
write ((byte) (0xff & (value >> 8)));
write ((byte) (0xff & value));
}
/**
* This method writes a Java long value to an output stream. The 8 bytes
* of the passed value will be written "big endian". That is, with
* the high byte written first in the following manner:
*
* byte0 = (byte)((value & 0xFF00000000000000L) >> 56);
*
* byte1 = (byte)((value & 0x00FF000000000000L) >> 48);
* byte2 = (byte)((value & 0x0000FF0000000000L) >> 40);
* byte3 = (byte)((value & 0x000000FF00000000L) >> 32);
* byte4 = (byte)((value & 0x00000000FF000000L) >> 24);
* byte5 = (byte)((value & 0x0000000000FF0000L) >> 16);
* byte6 = (byte)((value & 0x000000000000FF00L) >> 8);
* byte7 = (byte)(value & 0x00000000000000FFL);
*
* The value written can be read using the readLong
* method in DataInput
.
*
* @param value The long
value to write to the stream
*
* @exception IOException If an error occurs
*
* @see DataInput#readLong
*/
public final synchronized void writeLong (long value) throws IOException
{
write ((byte) (0xff & (value >> 56)));
write ((byte) (0xff & (value>> 48)));
write ((byte) (0xff & (value>> 40)));
write ((byte) (0xff & (value>> 32)));
write ((byte) (0xff & (value>> 24)));
write ((byte) (0xff & (value>> 16)));
write ((byte) (0xff & (value>> 8)));
write ((byte) (0xff & value));
}
/**
* This method writes a Java float
value to the stream. This
* value is written by first calling the method
* Float.floatToIntBits
* to retrieve an int
representing the floating point number,
* then writing this int
value to the stream exactly the same
* as the writeInt()
method does.
*
* The value written can be read using the readFloat
* method in DataInput
.
*
* @param value The float
value to write to the stream
*
* @exception IOException If an error occurs
*
* @see writeInt
* @see DataInput#readFloat
* @see Float#floatToIntBits
*/
public final void writeFloat (float value) throws IOException
{
writeInt (Float.floatToIntBits (value));
}
/**
* This method writes a Java double
value to the stream. This
* value is written by first calling the method
* Double.doubleToLongBits
* to retrieve an long
representing the floating point number,
* then writing this long
value to the stream exactly the same
* as the writeLong()
method does.
*
* The value written can be read using the readDouble
* method in DataInput
.
*
* @param value The double
value to write to the stream
*
* @exception IOException If an error occurs
*
* @see writeLong
* @see DataInput#readDouble
* @see Double#doubleToLongBits
*/
public final void writeDouble (double value) throws IOException
{
writeLong (Double.doubleToLongBits (value));
}
/**
* This method writes all the bytes in a String
out to the
* stream. One byte is written for each character in the
* String
.
* The high eight bits of each character are discarded, thus this
* method is inappropriate for completely representing Unicode characters.
*
* @param value The String
to write to the stream
*
* @exception IOException If an error occurs
*/
public final void writeBytes (String value) throws IOException
{
int len = value.length();
for (int i = 0; i < len; ++i)
writeByte (value.charAt(i));
}
/**
* This method writes all the characters of a String
to an
* output stream as an array of char
's. Each character
* is written using the method specified in the writeChar
* method.
*
* @param value The String
to write to the stream
*
* @exception IOException If an error occurs
*
* @see writeChar
*/
public final void writeChars (String value) throws IOException
{
int len = value.length();
for (int i = 0; i < len; ++i)
writeChar (value.charAt(i));
}
/**
* This method writes a Java String
to the stream in a modified
* UTF-8 format. First, two bytes are written to the stream indicating the
* number of bytes to follow. Note that this is the number of bytes in the
* encoded String
not the String
length. Next
* come the encoded characters. Each character in the String
* is encoded as either one, two or three bytes. For characters in the
* range of \u0001
to <\u007F>, one byte is used. The character
* value goes into bits 0-7 and bit eight is 0. For characters in the range
* of \u0080
to \u007FF
, two bytes are used. Bits
* 6-10 of the character value are encoded bits 0-4 of the first byte, with
* the high bytes having a value of "110". Bits 0-5 of the character value
* are stored in bits 0-5 of the second byte, with the high bits set to
* "10". This type of encoding is also done for the null character
* \u0000
. This eliminates any C style NUL character values
* in the output. All remaining characters are stored as three bytes.
* Bits 12-15 of the character value are stored in bits 0-3 of the first
* byte. The high bits of the first bytes are set to "1110". Bits 6-11
* of the character value are stored in bits 0-5 of the second byte. The
* high bits of the second byte are set to "10". And bits 0-5 of the
* character value are stored in bits 0-5 of byte three, with the high bits
* of that byte set to "10".
*
* The value written can be read using the readUTF
* method in DataInput
.
*
* @param value The String
to write to the output in UTF format
*
* @exception IOException If an error occurs
*
* @see DataInput#readUTF
*/
public synchronized final void writeUTF (String value) throws IOException
{
int len = value.length();
int sum = 0;
for (int i = 0; i < len && sum <= 65535; ++i)
{
char c = value.charAt(i);
if (c >= '\u0001' && c <= '\u007f')
sum += 1;
else if (c == '\u0000' || (c >= '\u0080' && c <= '\u07ff'))
sum += 2;
else
sum += 3;
}
if (sum > 65535)
throw new UTFDataFormatException ();
writeShort (sum);
for (int i = 0; i < len; ++i)
{
char c = value.charAt(i);
if (c >= '\u0001' && c <= '\u007f')
write (c);
else if (c == '\u0000' || (c >= '\u0080' && c <= '\u07ff'))
{
write (0xc0 | (0x1f & (c >> 6)));
write (0x80 | (0x3f & c));
}
else
{
// JSL says the first byte should be or'd with 0xc0, but
// that is a typo. Unicode says 0xe0, and that is what is
// consistent with DataInputStream.
write (0xe0 | (0x0f & (c >> 12)));
write (0x80 | (0x3f & (c >> 6)));
write (0x80 | (0x3f & c));
}
}
}
} // class DataOutputStream