/[classpath]/classpath/java/io/DataOutputStream.java
ViewVC logotype

Diff of /classpath/java/io/DataOutputStream.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.9 by mark, Tue Jan 22 22:26:59 2002 UTC revision 1.10 by arenn, Sun Mar 2 01:24:34 2003 UTC
# Line 1  Line 1 
1  /* DataOutputStream.java -- Writes primitive Java datatypes to streams  /* DataOutputStream.java -- Writes primitive Java datatypes to streams
2     Copyright (C) 1998, 2001 Free Software Foundation, Inc.     Copyright (C) 1998, 2001, 2003 Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 46  package java.io; Line 46  package java.io;
46    *    *
47    * @see DataInputStream    * @see DataInputStream
48    *    *
   * @version 0.0  
   *  
49    * @author Aaron M. Renn (arenn@urbanophile.com)    * @author Aaron M. Renn (arenn@urbanophile.com)
50      * @author Tom Tromey <tromey@cygnus.com>
51    */    */
52  public class DataOutputStream extends FilterOutputStream implements DataOutput  public class DataOutputStream extends FilterOutputStream implements DataOutput
53  {  {
54      
55  /*************************************************************************/    private byte[] buf = new byte[8];
56      
57  /*    // FIXME: This method should eventually die.  I'd bet there are
58   * Instance Variables    // at least half a dozen UTF converters scattered throughout the
59   */    // code.  String getBytes("UTF-8") would work as well, but might
60      // have higher overhead. Perhaps a shared internal method for
61  /**    // this someplace?
62    * This is the total number of bytes that have been written to the    static final byte[] convertToUTF(String s) throws IOException
63    * stream by this object instance.    {
64    */      ByteArrayOutputStream os = new ByteArrayOutputStream(s.length());
65  protected int written;    
66        for (int i = 0; i < s.length(); i++)
67  /*************************************************************************/        {
68            char c = s.charAt(i);
69  /*          if ((c <= 0x007F) && (c != 0))
70   * Class Methods            {
71   */              os.write(c);
72              }
73  /*          else if ((c <= 0x07FF) || (c == 0))
74   * These converter methods are called by instance methods of this class            {
75   * and by instance methods of RandomAccessFile to convert data read.  For              byte b1 = (byte)(0xC0 | (c >> 6));
76   * documentation on what these do, please see the corresponding instance              byte b2 = (byte)(0x80 | (c & 0x3F));
77   * method documentation    
78   */              os.write(b1);
79                os.write(b2);
80  static final int            }
81  convertFromBoolean(boolean b)          else
82  {            {
83    if (b)              byte b1 = (byte)(0xE0 | (c >> 12));
84      return(1);              byte b2 = (byte)(0x80 | ((c >> 6) & 0x3F));
85    else              byte b3 = (byte)(0x80 | (c & 0x3F));
86      return(0);    
87  }              os.write(b1);
88                os.write(b2);
89  /*************************************************************************/              os.write(b3);
90              }
91  static final byte[]        }
92  convertFromChar(int c)    
93  {      return(os.toByteArray());
94    byte[] buf = new byte[2];    }
95      
96    buf[0] = (byte)((c & 0xFF00) >> 8);    /*************************************************************************/
97    buf[1] = (byte)((int)c & 0x00FF);    
98      /*
99    return(buf);     * Instance Variables
100  }     */
101      
102  /*************************************************************************/    /**
103        * This is the total number of bytes that have been written to the
104  static final byte[]      * stream by this object instance.
105  getConvertedStringChars(String s)      */
106  {    protected int written = 0;
107    byte[] buf = new byte[s.length() * 2];    
108      /*************************************************************************/
109    for (int i = 0; i < s.length(); i++)    
110      {    /*
111        buf[i * 2] = (byte)(s.charAt(i) & 0xFF00);     * Constructors
112        buf[(i * 2) + 1] = (byte)(s.charAt(i) & 0x00FF);     */
113      }    
114      /**
115    return(buf);      * This method initializes an instance of <code>DataOutputStream</code> to
116  }      * write its data to the specified underlying <code>OutputStream</code>
117        *
118  /*************************************************************************/      * @param out The subordinate <code>OutputStream</code> to which this
119        * object will write
120  static final byte[]      */
121  convertFromShort(int s)    public DataOutputStream(OutputStream out)
122  {    {
123    byte[] buf = new byte[2];      super(out);
124      }
125    buf[0] = (byte)((s & 0xFF00) >> 8);    
126    buf[1] = (byte)(s & 0x00FF);    /*************************************************************************/
127      
128    return(buf);    /*
129  }     * Instance Methods
130       */
131  /*************************************************************************/    
132      /**
133  static final byte[]      * This method returns the total number of bytes that have been written to
134  convertFromInt(int i)      * the underlying output stream so far.  This is the value of the
135  {      * <code>written</code> instance variable
136    byte[] buf = new byte[4];      *
137        * @return The number of bytes written to the stream.
138    buf[0] = (byte)((i & 0xFF000000) >> 24);      */
139    buf[1] = (byte)((i & 0x00FF0000) >> 16);    public final int size()
140    buf[2] = (byte)((i & 0x0000FF00) >> 8);    {
141    buf[3] = (byte)(i & 0x000000FF);      return(written);
142      }
143    return(buf);    
144  }    /*************************************************************************/
145      
146  /*************************************************************************/    /**
147        * This method writes a Java <code>boolean</code> to the underlying output
148  static final byte[]      * stream. For a value of <code>true</code>, 1 is written to the stream.
149  convertFromLong(long l)      * For a value of <code>false</code>, 0 is written.
150  {      *
151    byte[] buf = new byte[8];      * @param b The <code>boolean</code> value to write to the stream
152        *
153    buf[0] = (byte)((l & 0xFF00000000000000L) >> 56);      * @exception IOException If an error occurs
154    buf[1] = (byte)((l & 0x00FF000000000000L) >> 48);      */
155    buf[2] = (byte)((l & 0x0000FF0000000000L) >> 40);    public final void writeBoolean(boolean b) throws IOException
156    buf[3] = (byte)((l & 0x000000FF00000000L) >> 32);    {
157    buf[4] = (byte)((l & 0x00000000FF000000L) >> 24);      if (b)
158    buf[5] = (byte)((l & 0x0000000000FF0000L) >> 16);        write(1);
159    buf[6] = (byte)((l & 0x000000000000FF00L) >> 8);      else
160    buf[7] = (byte)(l & 0x00000000000000FFL);        write(0);
161      }
162    return(buf);    
163  }    /*************************************************************************/
164      
165  /*************************************************************************/    /**
166        * This method writes a Java <code>byte</code> value to the underlying
167  static final byte[]      * output stream.
168  convertToUTF(String s) throws IOException      *
169  {      * @param b The <code>byte</code> to write to the stream, passed as
170    ByteArrayOutputStream os = new ByteArrayOutputStream(s.length());      * the low eight bits of an <code>int</code>.
171        *
172    for (int i = 0; i < s.length(); i++)      * @exception IOException If an error occurs
173      {      */
174        char c = s.charAt(i);    public final void writeByte(int b) throws IOException
175        if ((c <= 0x007F) && (c != 0))    {
176          {      write(b & 0xFF);
177            os.write(c);    }
178          }    
179        else if ((c <= 0x07FF) || (c == 0))    /*************************************************************************/
180          {    
181            byte b1 = (byte)(0xC0 | (c >> 6));    /**
182            byte b2 = (byte)(0x80 | (c & 0x3F));      * This method writes all the bytes in a <code>String</code> out to the
183        * stream.  One byte is written for each character in the
184            os.write(b1);      * <code>String</code>.
185            os.write(b2);      * The high eight bits of each character are discarded.
186          }      *
187        else      * @param s The <code>String</code> to write to the stream
188          {      *
189            byte b1 = (byte)(0xE0 | (c >> 12));      * @exception IOException If an error occurs
190            byte b2 = (byte)(0x80 | ((c >> 6) & 0x3F));      */
191            byte b3 = (byte)(0x80 | (c & 0x3F));    public final void writeBytes(String s) throws IOException
192      {
193            os.write(b1);      int len = s.length();
194            os.write(b2);      if (len == 0)
195            os.write(b3);        return;
196          }    
197      }      byte[] buf = new byte[len];
198      
199    return(os.toByteArray());      for (int i = 0; i < len; i++)
200  }        buf[i] = (byte)(s.charAt(i) & 0xFF);
201      
202  /*************************************************************************/      write(buf, 0, buf.length);
203      }
204  /*    
205   * Constructors    /*************************************************************************/
206   */    
207      /**
208  /**      * This method writes a single <code>char</code> value to the stream,
209    * This method initializes an instance of <code>DataOutputStream</code> to      * high byte first.
210    * write its data to the specified underlying <code>OutputStream</code>      *
211    *      * @param c The <code>char</code> value to write,
212    * @param out The subordinate <code>OutputStream</code> to which this object will write      * passed as an <code>int</code>.
213    */      *
214  public      * @exception IOException If an error occurs
215  DataOutputStream(OutputStream out)      */
216  {    public final synchronized void writeChar(int c) throws IOException
217    super(out);    {
218  }      buf[0] = (byte)((c & 0xFF00) >> 8);
219        buf[1] = (byte)((int)c & 0x00FF);
220  /*************************************************************************/    
221        write(buf, 0, 2);
222  /*    }
223   * Instance Methods    
224   */    /*************************************************************************/
225      
226  /**    /**
227    * This method returns the total number of bytes that have been written to      * This method writes all the characters in a <code>String</code> to the
228    * the underlying output stream so far.  This is the value of the      * stream.  There will be two bytes for each character value.  The high
229    * <code>written</code> instance variable      * byte of the character will be written first.
230    *      *
231    * @return The number of bytes written to the stream.      * @param s The <code>String</code> to write to the stream.
232    */      *
233  public final int      * @exception IOException If an error occurs
234  size()      */
235  {    public final void writeChars(String s) throws IOException
236    return(written);    {
237  }      int len = s.length();
238        if (len == 0)
239  /*************************************************************************/        return;
240      
241  /**      byte[] buf = new byte[len * 2];
242    * This method writes a Java <code>boolean</code> to the underlying output    
243    * stream. For a value of <code>true</code>, 1 is written to the stream.      for (int i = 0; i < len; i++)
244    * For a value of <code>false</code>, 0 is written.        {
245    *          buf[i * 2] = (byte)((s.charAt(i) & 0xFF00) >> 8);
246    * @param b The <code>boolean</code> value to write to the stream          buf[(i * 2) + 1] = (byte)(s.charAt(i) & 0x00FF);
247    *        }
248    * @exception IOException If an error occurs    
249    */      write(buf, 0, buf.length);
250  public final void    }
251  writeBoolean(boolean b) throws IOException    
252  {    /*************************************************************************/
253    int bool = convertFromBoolean(b);    
254    out.write(bool);    /**
255    ++written;      * This method writes a Java <code>short</code> to the stream, high byte
256  }      * first.  This method requires two bytes to encode the value.
257        *
258  /*************************************************************************/      * @param s The <code>short</code> value to write to the stream,
259        * passed as an <code>int</code>.
260  /**      *
261    * This method writes a Java <code>byte</code> value to the underlying      * @exception IOException If an error occurs
262    * output stream.      */
263    *    public final synchronized void writeShort(int s) throws IOException
264    * @param b The <code>byte</code> to write to the stream, passed as an <code>int</code>.    {
265    *      buf[0] = (byte)((s & 0xFF00) >> 8);
266    * @exception IOException If an error occurs      buf[1] = (byte)(s & 0x00FF);
267    */    
268  public final void      write(buf, 0, 2);
269  writeByte(int b) throws IOException    }
270  {    
271    out.write(b);    /*************************************************************************/
272      
273    ++written;    /**
274  }      * This method writes a Java <code>int</code> to the stream, high bytes
275        * first.  This method requires four bytes to encode the value.
276  /*************************************************************************/      *
277        * @param i The <code>int</code> value to write to the stream.
278  /**      *
279    * This method writes all the bytes in a <code>String</code> out to the      * @exception IOException If an error occurs
280    * stream.  One byte is written for each character in the <code>String</code>.      */
281    * The high eight bits of each character are discarded.    public final synchronized void writeInt(int i) throws IOException
282    *    {
283    * @param s The <code>String</code> to write to the stream      buf[0] = (byte)((i & 0xFF000000) >> 24);
284    *      buf[1] = (byte)((i & 0x00FF0000) >> 16);
285    * @exception IOException If an error occurs      buf[2] = (byte)((i & 0x0000FF00) >> 8);
286    */      buf[3] = (byte)(i & 0x000000FF);
287  public final void    
288  writeBytes(String s) throws IOException      write(buf, 0, 4);
289  {    }
290    if (s.length() == 0)    
291      return;    /*************************************************************************/
292      
293    byte[] buf = new byte[s.length()];    /**
294        * This method writes a Java <code>long</code> to the stream, high bytes
295    for (int i = 0; i < s.length(); i++)      * first.  This method requires eight bytes to encode the value.
296      buf[i] = (byte)(s.charAt(i) & 0xFF);      *
297        * @param l The <code>long</code> value to write to the stream.
298    out.write(buf);      *
299        * @exception IOException If an error occurs
300    written += buf.length;      */
301  }    public final synchronized void writeLong(long l) throws IOException
302      {
303  /*************************************************************************/      buf[0] = (byte)((l & 0xFF00000000000000L) >> 56);
304        buf[1] = (byte)((l & 0x00FF000000000000L) >> 48);
305  /**      buf[2] = (byte)((l & 0x0000FF0000000000L) >> 40);
306    * This method writes a single <code>char</code> value to the stream,      buf[3] = (byte)((l & 0x000000FF00000000L) >> 32);
307    * high byte first.      buf[4] = (byte)((l & 0x00000000FF000000L) >> 24);
308    *      buf[5] = (byte)((l & 0x0000000000FF0000L) >> 16);
309    * @param c The <code>char</code> value to write, passed as an <code>int</code>.      buf[6] = (byte)((l & 0x000000000000FF00L) >> 8);
310    *      buf[7] = (byte)(l & 0x00000000000000FFL);
311    * @exception IOException If an error occurs    
312    */      write(buf, 0, 8);
313  public final void    }
314  writeChar(int c) throws IOException    
315  {    /*************************************************************************/
316    out.write(convertFromChar(c));    
317      /**
318    written += 2;      * This method writes a Java <code>float</code> value to the stream.  This
319  }      * value is written by first calling the method
320        * <code>Float.floatToIntBits</code>
321  /*************************************************************************/      * to retrieve an <code>int</code> representing the floating point number,
322        * then writing this <code>int</code> value to the stream exactly the same
323  /**      * as the <code>writeInt()</code> method does.
324    * This method writes all the characters in a <code>String</code> to the      *
325    * stream.  There will be two bytes for each character value.  The high      * @param f The floating point number to write to the stream.
326    * byte of the character will be written first.      *
327    *      * @exception IOException If an error occurs
328    * @param s The <code>String</code> to write to the stream.      *
329    *      * @see writeInt
330    * @exception IOException If an error occurs      */
331    */    public final void writeFloat(float f) throws IOException
332  public final void    {
333  writeChars(String s) throws IOException      writeInt(Float.floatToIntBits(f));
334  {    }
335    if (s.length() == 0)    
336      return;    /*************************************************************************/
337      
338    byte[] buf = getConvertedStringChars(s);    /**
339    out.write(buf);      * This method writes a Java <code>double</code> value to the stream.  This
340        * value is written by first calling the method
341    written += buf.length;      * <code>Double.doubleToLongBits</code>
342  }      * to retrieve an <code>long</code> representing the floating point number,
343        * then writing this <code>long</code> value to the stream exactly the same
344  /*************************************************************************/      * as the <code>writeLong()</code> method does.
345        *
346  /**      * @param d The double precision floating point number to write to
347    * This method writes a Java <code>short</code> to the stream, high byte      * the stream.
348    * first.  This method requires two bytes to encode the value.      *
349    *      * @exception IOException If an error occurs
350    * @param s The <code>short</code> value to write to the stream, passed as an <code>int</code>.      *
351    *      * @see writeLong
352    * @exception IOException If an error occurs      */
353    */    public final void writeDouble(double d) throws IOException
354  public final void    {
355  writeShort(int s) throws IOException      writeLong(Double.doubleToLongBits(d));
356  {    }
357    out.write(convertFromShort(s));    
358      /*************************************************************************/
359    written += 2;    
360  }    /**
361        * This method writes a Java <code>String</code> to the stream in a modified
362  /*************************************************************************/      * UTF-8 format.  First, two bytes are written to the stream indicating the
363        * number of bytes to follow.  Note that this is the number of bytes in the
364  /**      * encoded <code>String</code> not the <code>String</code> length.  Next
365    * This method writes a Java <code>int</code> to the stream, high bytes      * come the encoded characters.  Each character in the <code>String</code>
366    * first.  This method requires four bytes to encode the value.      * is encoded as either one, two or three bytes.  For characters in the
367    *      * range of <code>\u0001</code> to <\u007F>, one byte is used.  The character
368    * @param i The <code>int</code> value to write to the stream.      * value goes into bits 0-7 and bit eight is 0.  For characters in the range
369    *      * of <code>\u0080</code> to <code>\u007FF</code>, two bytes are used.  Bits
370    * @exception IOException If an error occurs      * 6-10 of the character value are encoded bits 0-4 of the first byte, with
371    */      * the high bytes having a value of "110".  Bits 0-5 of the character value
372  public final void      * are stored in bits 0-5 of the second byte, with the high bits set to
373  writeInt(int i) throws IOException      * "10".  This type of encoding is also done for the null character
374  {      * <code>\u0000</code>.  This eliminates any C style NUL character values
375    out.write(convertFromInt(i));      * in the output.  All remaining characters are stored as three bytes.
376        * Bits 12-15 of the character value are stored in bits 0-3 of the first
377    written += 4;      * byte.  The high bits of the first bytes are set to "1110".  Bits 6-11
378  }      * of the character value are stored in bits 0-5 of the second byte.  The
379        * high bits of the second byte are set to "10".  And bits 0-5 of the
380  /*************************************************************************/      * character value are stored in bits 0-5 of byte three, with the high bits
381        * of that byte set to "10".
382  /**      *
383    * This method writes a Java <code>long</code> to the stream, high bytes      * @param s The <code>String</code> to write to the output in UTF format
384    * first.  This method requires eight bytes to encode the value.      *
385    *      * @exception IOException If an error occurs
386    * @param l The <code>long</code> value to write to the stream.      */
387    *    public synchronized final void writeUTF(String s) throws IOException
388    * @exception IOException If an error occurs    {
389    */      // FIXME:  Stylistically, replacing this with s.getBytes("UTF-8")
390  public final void      // would be better. However, that's likely to be expensive because of
391  writeLong(long l) throws IOException      // the char encoder overhead. Maybe we should have an easily
392  {      // invokable UTF-8 converter function, but I'm not sure this is the
393    out.write(convertFromLong(l));      // right class for it to live in.
394        byte[] buf = convertToUTF(s);
395    written += 8;    
396  }      writeShort(buf.length);
397        write(buf, 0, buf.length);
398  /*************************************************************************/    }
399      
400  /**    /*************************************************************************/
401    * This method writes a Java <code>float</code> value to the stream.  This    
402    * value is written by first calling the method <code>Float.floatToIntBits</code>    /**
403    * to retrieve an <code>int</code> representing the floating point number,      * This method writes the specified byte (passed as an <code>int</code>)
404    * then writing this <code>int</code> value to the stream exactly the same      * to the underlying output stream.
405    * as the <code>writeInt()</code> method does.      *
406    *      * @param b The byte to write, passed as an <code>int</code>.
407    * @param f The floating point number to write to the stream.      *
408    *      * @exception IOException If an error occurs.
409    * @exception IOException If an error occurs      */
410    *    public synchronized void write(int b) throws IOException
411    * @see writeInt    {
412    */      out.write(b);
413  public final void      ++written;
414  writeFloat(float f) throws IOException    }
415  {    
416    int i = Float.floatToIntBits(f);    /*************************************************************************/
417    writeInt(i);    
418  }    /**
419        * This method writes <code>len</code> bytes from the specified byte array
420  /*************************************************************************/      * <code>buf</code> starting at position <code>offset</code> into the
421        * buffer to the underlying output stream.
422  /**      *
423    * This method writes a Java <code>double</code> value to the stream.  This      * @param buf The byte array to write from.
424    * value is written by first calling the method <code>Double.doubleToLongBits</code>      * @param offset The index into the byte array to start writing from.
425    * to retrieve an <code>long</code> representing the floating point number,      * @param len The number of bytes to write.
426    * then writing this <code>long</code> value to the stream exactly the same      *
427    * as the <code>writeLong()</code> method does.      * @exception IOException If an error occurs.
428    *      */
429    * @param d The double precision floating point number to write to the stream.    public synchronized void write(byte[] buf, int offset, int len)
430    *       throws IOException
431    * @exception IOException If an error occurs    {
432    *      out.write(buf, offset, len);
433    * @see writeLong      written += len;
434    */    }
435  public final void    
436  writeDouble(double d) throws IOException    /*************************************************************************/
437  {    
438    long l = Double.doubleToLongBits(d);    /**
439    writeLong(l);      * This method flushes any unwritten bytes to the underlying stream.
440  }      *
441        * @exception IOException If an error occurs.
442  /*************************************************************************/      */
443      public void flush() throws IOException
444  /**    {
445    * This method writes a Java <code>String</code> to the stream in a modified      out.flush();
446    * UTF-8 format.  First, two bytes are written to the stream indicating the    }
447    * number of bytes to follow.  Note that this is the number of bytes in the    
   * encoded <code>String</code> not the <code>String</code> length.  Next  
   * come the encoded characters.  Each character in the <code>String</code>  
   * is encoded as either one, two or three bytes.  For characters in the  
   * range of <code>\u0001</code> 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 <code>\u0080</code> to <code>\u007FF</code>, 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  
   * <code>\u0000</code>.  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".  
   *  
   * @param s The <code>String</code> to write to the output in UTF format  
   *  
   * @exception IOException If an error occurs  
   */  
 public synchronized final void  
 writeUTF(String s) throws IOException  
 {  
   byte[] buf = convertToUTF(s);  
   
   writeShort(buf.length);  
   out.write(buf);  
   
   written += buf.length;  
 }  
   
 /*************************************************************************/  
   
 /**  
   * This method writes the specified byte (passed as an <code>int</code>)  
   * to the underlying output stream.  
   *  
   * @param b The byte to write, passed as an <code>int</code>.  
   *  
   * @exception IOException If an error occurs.  
   */  
 public void  
 write(int b) throws IOException  
 {  
   out.write(b);  
   ++written;  
 }  
   
 /*************************************************************************/  
   
 /**  
   * This method writes <code>len</code> bytes from the specified byte array  
   * <code>buf</code> starting at position <code>offset</code> 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 void  
 write(byte[] buf, int offset, int len) throws IOException  
 {  
   out.write(buf, offset, len);  
   written += len;  
 }  
   
 /*************************************************************************/  
   
 /**  
   * This method flushes any unwritten bytes to the underlying stream.  
   *  
   * @exception IOException If an error occurs.  
   */  
 public void  
 flush() throws IOException  
 {  
   out.flush();  
 }  
   
448  } // class DataOutputStream  } // class DataOutputStream
449    

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26