OSDN Git Service

Add license clarification.
[pf3gnuchains/gcc-fork.git] / libjava / java / io / DataInputStream.java
1 /* DataInputStream.java -- FilteredInputStream that implements DataInput
2    Copyright (C) 1998, 1999, 2000, 2001  Free Software Foundation
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 package java.io;
39
40 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
41  * "The Java Language Specification", ISBN 0-201-63451-1
42  * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
43  * Status:  Believed complete and correct.
44  */
45  
46 /**
47  * This subclass of <code>FilteredInputStream</code> implements the
48  * <code>DataInput</code> interface that provides method for reading primitive
49  * Java data types from a stream.
50  *
51  * @see DataInput
52  *
53  * @version 0.0
54  *
55  * @author Warren Levy <warrenl@cygnus.com>
56  * @author Aaron M. Renn (arenn@urbanophile.com)
57  * @date October 20, 1998.  
58  */
59 public class DataInputStream extends FilterInputStream implements DataInput
60 {
61   // readLine() hack to ensure that an '\r' not followed by an '\n' is
62   // handled correctly. If set, readLine() will ignore the first char it sees
63   // if that char is a '\n'
64   boolean ignoreInitialNewline = false;
65
66   // Byte buffer, used to make primitive read calls more efficient.
67   byte[] buf = new byte[8];
68   
69   /**
70    * This constructor initializes a new <code>DataInputStream</code>
71    * to read from the specified subordinate stream.
72    *
73    * @param in The subordinate <code>InputStream</code> to read from
74    */
75   public DataInputStream(InputStream in)
76   {
77     super(in);
78   }
79
80   /**
81    * This method reads bytes from the underlying stream into the specified
82    * byte array buffer.  It will attempt to fill the buffer completely, but
83    * may return a short count if there is insufficient data remaining to be
84    * read to fill the buffer.
85    *
86    * @param b The buffer into which bytes will be read.
87    * 
88    * @return The actual number of bytes read, or -1 if end of stream reached 
89    * before reading any bytes.
90    *
91    * @exception IOException If an error occurs.
92    */
93   public final int read(byte[] b) throws IOException
94   {
95     return in.read(b, 0, b.length);
96   }
97
98   /**
99    * This method reads bytes from the underlying stream into the specified
100    * byte array buffer.  It will attempt to read <code>len</code> bytes and
101    * will start storing them at position <code>off</code> into the buffer.
102    * This method can return a short count if there is insufficient data
103    * remaining to be read to complete the desired read length.
104    *
105    * @param b The buffer into which bytes will be read.
106    * @param off The offset into the buffer to start storing bytes.
107    * @param len The requested number of bytes to read.
108    *
109    * @return The actual number of bytes read, or -1 if end of stream reached
110    * before reading any bytes.
111    *
112    * @exception IOException If an error occurs.
113    */
114   public final int read(byte[] b, int off, int len) throws IOException
115   {
116     return in.read(b, off, len);
117   }
118
119   /**
120    * This method reads a Java boolean value from an input stream.  It does
121    * so by reading a single byte of data.  If that byte is zero, then the
122    * value returned is <code>false</code>.  If the byte is non-zero, then
123    * the value returned is <code>true</code>.
124    * <p>
125    * This method can read a <code>boolean</code> written by an object
126    * implementing the <code>writeBoolean()</code> method in the
127    * <code>DataOutput</code> interface. 
128    *
129    * @return The <code>boolean</code> value read
130    *
131    * @exception EOFException If end of file is reached before reading
132    * the boolean
133    * @exception IOException If any other error occurs
134    */
135   public final boolean readBoolean() throws IOException
136   {
137     return convertToBoolean(in.read());
138   }
139
140   /**
141    * This method reads a Java byte value from an input stream.  The value
142    * is in the range of -128 to 127.
143    * <p>
144    * This method can read a <code>byte</code> written by an object
145    * implementing the <code>writeByte()</code> method in the
146    * <code>DataOutput</code> interface.
147    *
148    * @return The <code>byte</code> value read
149    *
150    * @exception EOFException If end of file is reached before reading the byte
151    * @exception IOException If any other error occurs
152    *
153    * @see DataOutput
154    */
155   public final byte readByte() throws IOException
156   {
157     return convertToByte(in.read());
158   }
159
160   /**
161    * This method reads a Java <code>char</code> value from an input stream.  
162    * It operates by reading two bytes from the stream and converting them to 
163    * a single 16-bit Java <code>char</code>.  The two bytes are stored most
164    * significant byte first (i.e., "big endian") regardless of the native
165    * host byte ordering. 
166    * <p>
167    * As an example, if <code>byte1</code> and <code>byte2</code>
168    * represent the first and second byte read from the stream
169    * respectively, they will be transformed to a <code>char</code> in
170    * the following manner: 
171    * <p>
172    * <code>(char)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)</code>
173    * <p>
174    * This method can read a <code>char</code> written by an object
175    * implementing the <code>writeChar()</code> method in the
176    * <code>DataOutput</code> interface. 
177    *
178    * @return The <code>char</code> value read 
179    *
180    * @exception EOFException If end of file is reached before reading the char
181    * @exception IOException If any other error occurs
182    *
183    * @see DataOutput
184    */
185   public final char readChar() throws IOException
186   {
187     readFully (buf, 0, 2);
188     return convertToChar(buf);
189   }
190
191   /**
192    * This method reads a Java double value from an input stream.  It operates
193    * by first reading a <code>long</code> value from the stream by calling the
194    * <code>readLong()</code> method in this interface, then converts
195    * that <code>long</code> to a <code>double</code> using the
196    * <code>longBitsToDouble</code> method in the class
197    * <code>java.lang.Double</code> 
198    * <p>
199    * This method can read a <code>double</code> written by an object
200    * implementing the <code>writeDouble()</code> method in the
201    * <code>DataOutput</code> interface.
202    *
203    * @return The <code>double</code> value read
204    *
205    * @exception EOFException If end of file is reached before reading
206    * the double
207    * @exception IOException If any other error occurs
208    *
209    * @see java.lang.Double
210    * @see DataOutput
211    */
212   public final double readDouble() throws IOException
213   {
214     return Double.longBitsToDouble(readLong());
215   }
216
217   /**
218    * This method reads a Java float value from an input stream.  It
219    * operates by first reading an <code>int</code> value from the
220    * stream by calling the <code>readInt()</code> method in this
221    * interface, then converts that <code>int</code> to a
222    * <code>float</code> using the <code>intBitsToFloat</code> method
223    * in the class <code>java.lang.Float</code>
224    * <p>
225    * This method can read a <code>float</code> written by an object
226    * implementing the * <code>writeFloat()</code> method in the
227    * <code>DataOutput</code> interface.
228    *
229    * @return The <code>float</code> value read
230    *
231    * @exception EOFException If end of file is reached before reading the float
232    * @exception IOException If any other error occurs
233    *
234    * @see java.lang.Float
235    * @see DataOutput */
236   public final float readFloat() throws IOException
237   {
238     return Float.intBitsToFloat(readInt());
239   }
240
241   /**
242    * This method reads raw bytes into the passed array until the array is
243    * full.  Note that this method blocks until the data is available and
244    * throws an exception if there is not enough data left in the stream to
245    * fill the buffer
246    *
247    * @param b The buffer into which to read the data
248    *
249    * @exception EOFException If end of file is reached before filling
250    * the buffer
251    * @exception IOException If any other error occurs */
252   public final void readFully(byte[] b) throws IOException
253   {
254     readFully(b, 0, b.length);
255   }
256
257   /**
258    * This method reads raw bytes into the passed array
259    * <code>buf</code> starting <code>offset</code> bytes into the
260    * buffer.  The number of bytes read will be exactly
261    * <code>len</code> Note that this method blocks until the data is
262    * available and * throws an exception if there is not enough data
263    * left in the stream to read <code>len</code> bytes.
264    *
265    * @param buf The buffer into which to read the data
266    * @param offset The offset into the buffer to start storing data
267    * @param len The number of bytes to read into the buffer
268    *
269    * @exception EOFException If end of file is reached before filling
270    * the buffer
271    * @exception IOException If any other error occurs
272    */
273   public final void readFully(byte[] b, int off, int len) throws IOException
274   {
275     while (len > 0)
276       {
277         // in.read will block until some data is available.
278         int numread = in.read(b, off, len);
279         if (numread < 0)
280           throw new EOFException();
281         len -= numread;
282         off += numread;
283       }
284   }
285
286   /**
287    * This method reads a Java <code>int</code> value from an input
288    * stream It operates by reading four bytes from the stream and
289    * converting them to a single Java <code>int</code> The bytes are
290    * stored most significant byte first (i.e., "big endian")
291    * regardless of the native host byte ordering.
292    * <p>
293    * As an example, if <code>byte1</code> through <code>byte4</code>
294    * represent the first four bytes read from the stream, they will be
295    * transformed to an <code>int</code> in the following manner:
296    * <p>
297    * <code>(int)(((byte1 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) + 
298    * ((byte3 & 0xFF) << 8) + (byte4 & 0xFF)))</code>
299    * <p>
300    * The value returned is in the range of 0 to 65535.
301    * <p>
302    * This method can read an <code>int</code> written by an object
303    * implementing the <code>writeInt()</code> method in the
304    * <code>DataOutput</code> interface.
305    *
306    * @return The <code>int</code> value read
307    *
308    * @exception EOFException If end of file is reached before reading the int
309    * @exception IOException If any other error occurs
310    *
311    * @see DataOutput
312    */
313   public final int readInt() throws IOException
314   {
315     readFully (buf, 0, 4);
316     return convertToInt(buf);
317   }
318
319   /**
320    * This method reads the next line of text data from an input
321    * stream.  It operates by reading bytes and converting those bytes
322    * to <code>char</code> values by treating the byte read as the low
323    * eight bits of the <code>char</code> and using 0 as the high eight
324    * bits.  Because of this, it does not support the full 16-bit
325    * Unicode character set.
326    * <p>
327    * The reading of bytes ends when either the end of file or a line
328    * terminator is encountered.  The bytes read are then returned as a
329    * <code>String</code> A line terminator is a byte sequence
330    * consisting of either <code>\r</code>, <code>\n</code> or
331    * <code>\r\n</code>.  These termination charaters are discarded and
332    * are not returned as part of the string.
333    * <p>
334    * This method can read data that was written by an object implementing the
335    * <code>writeLine()</code> method in <code>DataOutput</code>.
336    *
337    * @return The line read as a <code>String</code>
338    *
339    * @exception IOException If an error occurs
340    *
341    * @see DataOutput
342    *
343    * @deprecated
344    */
345   public final String readLine() throws IOException
346   {
347     StringBuffer strb = new StringBuffer();
348
349     readloop: while (true)
350       {
351         int c = 0;
352         char ch = ' ';
353         boolean getnext = true;
354         while (getnext)
355           {
356             getnext = false;
357             c = in.read();
358             if (c < 0)  // got an EOF
359               return strb.length() > 0 ? strb.toString() : null;
360             ch = (char) c;
361             if ((ch &= 0xFF) == '\n')
362               // hack to correctly handle '\r\n' sequences
363               if (ignoreInitialNewline)
364                 {
365                   ignoreInitialNewline = false;
366                   getnext = true;
367                 }
368               else
369                 break readloop;
370           }
371
372         if (ch == '\r')
373           {
374             // FIXME: The following code tries to adjust the stream back one
375             // character if the next char read is '\n'.  As a last resort,
376             // it tries to mark the position before reading but the bottom
377             // line is that it is possible that this method will not properly
378             // deal with a '\r' '\n' combination thus not fulfilling the
379             // DataInput contract for readLine.  It's not a particularly
380             // safe approach threadwise since it is unsynchronized and
381             // since it might mark an input stream behind the users back.
382             // Along the same vein it could try the same thing for
383             // ByteArrayInputStream and PushbackInputStream, but that is
384             // probably overkill since this is deprecated & BufferedInputStream
385             // is the most likely type of input stream.
386             //
387             // The alternative is to somehow push back the next byte if it
388             // isn't a '\n' or to have the reading methods of this class
389             // keep track of whether the last byte read was '\r' by readLine
390             // and then skip the very next byte if it is '\n'.  Either way,
391             // this would increase the complexity of the non-deprecated methods
392             // and since it is undesirable to make non-deprecated methods
393             // less efficient, the following seems like the most reasonable
394             // approach.
395             int next_c = 0;
396             char next_ch = ' ';
397             if (in instanceof BufferedInputStream)
398               {
399                 next_c = in.read();
400                 next_ch = (char) (next_c & 0xFF);
401                 if ((next_ch != '\n') && (next_c >= 0)) 
402                   {
403                     BufferedInputStream bin = (BufferedInputStream) in;
404                     if (bin.pos > 0)
405                       bin.pos--;
406                   }
407               }
408             else if (markSupported())
409               {
410                 next_c = in.read();
411                 next_ch = (char) (next_c & 0xFF);
412                 if ((next_ch != '\n') && (next_c >= 0)) 
413                   {
414                     mark(1);
415                     if ((in.read() & 0xFF) != '\n')
416                       reset();
417                   }
418               } 
419             // In order to catch cases where 'in' isn't a BufferedInputStream
420             // and doesn't support mark() (such as reading from a Socket), set 
421             // a flag that instructs readLine() to ignore the first character 
422             // it sees _if_ that character is a '\n'.
423             else ignoreInitialNewline = true;
424             break;
425           }
426         strb.append(ch);
427       }
428
429     return strb.length() > 0 ? strb.toString() : "";
430   }
431
432   /**
433    * This method reads a Java long value from an input stream
434    * It operates by reading eight bytes from the stream and converting them to 
435    * a single Java <code>long</code>  The bytes are stored most
436    * significant byte first (i.e., "big endian") regardless of the native
437    * host byte ordering. 
438    * <p>
439    * As an example, if <code>byte1</code> through <code>byte8</code>
440    * represent the first eight bytes read from the stream, they will
441    * be transformed to an <code>long</code> in the following manner:
442    * <p>
443    * <code>(long)((((long)byte1 & 0xFF) << 56) + (((long)byte2 & 0xFF) << 48) + 
444    * (((long)byte3 & 0xFF) << 40) + (((long)byte4 & 0xFF) << 32) + 
445    * (((long)byte5 & 0xFF) << 24) + (((long)byte6 & 0xFF) << 16) + 
446    * (((long)byte7 & 0xFF) << 8) + ((long)byte9 & 0xFF)))</code>
447    * <p>
448    * The value returned is in the range of 0 to 65535.
449    * <p>
450    * This method can read an <code>long</code> written by an object
451    * implementing the <code>writeLong()</code> method in the
452    * <code>DataOutput</code> interface.
453    *
454    * @return The <code>long</code> value read
455    *
456    * @exception EOFException If end of file is reached before reading the long
457    * @exception IOException If any other error occurs
458    *
459    * @see DataOutput
460    */
461   public final long readLong() throws IOException
462   {
463     readFully (buf, 0, 8);
464     return convertToLong(buf);
465   }
466
467   /**
468    * This method reads a signed 16-bit value into a Java in from the
469    * stream.  It operates by reading two bytes from the stream and
470    * converting them to a single 16-bit Java <code>short</code>.  The
471    * two bytes are stored most significant byte first (i.e., "big
472    * endian") regardless of the native host byte ordering.
473    * <p>
474    * As an example, if <code>byte1</code> and <code>byte2</code>
475    * represent the first and second byte read from the stream
476    * respectively, they will be transformed to a <code>short</code>. in
477    * the following manner:
478    * <p>
479    * <code>(short)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)</code>
480    * <p>
481    * The value returned is in the range of -32768 to 32767.
482    * <p>
483    * This method can read a <code>short</code> written by an object
484    * implementing the <code>writeShort()</code> method in the
485    * <code>DataOutput</code> interface.
486    *
487    * @return The <code>short</code> value read
488    *
489    * @exception EOFException If end of file is reached before reading the value
490    * @exception IOException If any other error occurs
491    *
492    * @see DataOutput
493    */
494   public final short readShort() throws IOException
495   {
496     readFully (buf, 0, 2);
497     return convertToShort(buf);
498   }
499
500   /**
501    * This method reads 8 unsigned bits into a Java <code>int</code>
502    * value from the stream. The value returned is in the range of 0 to
503    * 255.
504    * <p>
505    * This method can read an unsigned byte written by an object
506    * implementing the <code>writeUnsignedByte()</code> method in the
507    * <code>DataOutput</code> interface.
508    *
509    * @return The unsigned bytes value read as a Java <code>int</code>.
510    *
511    * @exception EOFException If end of file is reached before reading the value
512    * @exception IOException If any other error occurs
513    *
514    * @see DataOutput
515    */
516   public final int readUnsignedByte() throws IOException
517   {
518     return convertToUnsignedByte(in.read());
519   }
520
521   /**
522    * This method reads 16 unsigned bits into a Java int value from the stream.
523    * It operates by reading two bytes from the stream and converting them to 
524    * a single Java <code>int</code>  The two bytes are stored most
525    * significant byte first (i.e., "big endian") regardless of the native
526    * host byte ordering. 
527    * <p>
528    * As an example, if <code>byte1</code> and <code>byte2</code>
529    * represent the first and second byte read from the stream
530    * respectively, they will be transformed to an <code>int</code> in
531    * the following manner:
532    * <p>
533    * <code>(int)(((byte1 & 0xFF) << 8) + (byte2 & 0xFF))</code>
534    * <p>
535    * The value returned is in the range of 0 to 65535.
536    * <p>
537    * This method can read an unsigned short written by an object
538    * implementing the <code>writeUnsignedShort()</code> method in the
539    * <code>DataOutput</code> interface.
540    *
541    * @return The unsigned short value read as a Java <code>int</code>
542    *
543    * @exception EOFException If end of file is reached before reading the value
544    * @exception IOException If any other error occurs
545    */
546   public final int readUnsignedShort() throws IOException
547   {
548     readFully (buf, 0, 2);
549     return convertToUnsignedShort(buf);
550   }
551
552   /**
553    * This method reads a <code>String</code> from an input stream that
554    * is encoded in a modified UTF-8 format.  This format has a leading
555    * two byte sequence that contains the remaining number of bytes to
556    * read.  This two byte sequence is read using the
557    * <code>readUnsignedShort()</code> method of this interface.
558    * <p>
559    * After the number of remaining bytes have been determined, these
560    * bytes are read an transformed into <code>char</code> values.
561    * These <code>char</code> values are encoded in the stream using
562    * either a one, two, or three byte format.  The particular format
563    * in use can be determined by examining the first byte read.
564    * <p>
565    * If the first byte has a high order bit of 0, then that character
566    * consists on only one byte.  This character value consists of
567    * seven bits that are at positions 0 through 6 of the byte.  As an
568    * example, if <code>byte1</code> is the byte read from the stream,
569    * it would be converted to a <code>char</code> like so:
570    * <p>
571    * <code>(char)byte1</code>
572    * <p>
573    * If the first byte has 110 as its high order bits, then the 
574    * character consists of two bytes.  The bits that make up the character
575    * value are in positions 0 through 4 of the first byte and bit positions
576    * 0 through 5 of the second byte.  (The second byte should have 
577    * 10 as its high order bits).  These values are in most significant
578    * byte first (i.e., "big endian") order.
579    * <p>
580    * As an example, if <code>byte1</code> and <code>byte2</code> are
581    * the first two bytes read respectively, and the high order bits of
582    * them match the patterns which indicate a two byte character
583    * encoding, then they would be converted to a Java
584    * <code>char</code> like so:
585    * <p>
586    * <code>(char)(((byte1 & 0x1F) << 6) | (byte2 & 0x3F))</code>
587    * <p>
588    * If the first byte has a 1110 as its high order bits, then the
589    * character consists of three bytes.  The bits that make up the character
590    * value are in positions 0 through 3 of the first byte and bit positions
591    * 0 through 5 of the other two bytes.  (The second and third bytes should
592    * have 10 as their high order bits).  These values are in most
593    * significant byte first (i.e., "big endian") order.
594    * <p>
595    * As an example, if <code>byte1</code> <code>byte2</code> and
596    * <code>byte3</code> are the three bytes read, and the high order
597    * bits of them match the patterns which indicate a three byte
598    * character encoding, then they would be converted to a Java
599    * <code>char</code> like so:
600    * <p>
601    * <code>(char)(((byte1 & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F))</code>
602    * <p>
603    * Note that all characters are encoded in the method that requires
604    * the fewest number of bytes with the exception of the character
605    * with the value of <code>&#92;u0000</code> which is encoded as two
606    * bytes.  This is a modification of the UTF standard used to
607    * prevent C language style <code>NUL</code> values from appearing
608    * in the byte stream.
609    * <p>
610    * This method can read data that was written by an object implementing the
611    * <code>writeUTF()</code> method in <code>DataOutput</code>
612    * 
613    * @returns The <code>String</code> read
614    *
615    * @exception EOFException If end of file is reached before reading
616    * the String
617    * @exception UTFDataFormatException If the data is not in UTF-8 format
618    * @exception IOException If any other error occurs
619    *
620    * @see DataOutput
621    */
622   public final String readUTF() throws IOException
623   {
624     return readUTF(this);
625   }
626
627   /**
628    * This method reads a String encoded in UTF-8 format from the 
629    * specified <code>DataInput</code> source.
630    *
631    * @param in The <code>DataInput</code> source to read from
632    *
633    * @return The String read from the source
634    *
635    * @exception IOException If an error occurs
636    */
637   public final static String readUTF(DataInput in) throws IOException
638   {
639     final int UTFlen = in.readUnsignedShort();
640     byte[] buf = new byte[UTFlen];
641
642     // This blocks until the entire string is available rather than
643     // doing partial processing on the bytes that are available and then
644     // blocking.  An advantage of the latter is that Exceptions
645     // could be thrown earlier.  The former is a bit cleaner.
646     in.readFully(buf, 0, UTFlen);
647
648     return convertFromUTF(buf);
649   }
650
651   /**
652    * This method attempts to skip and discard the specified number of bytes 
653    * in the input stream.  It may actually skip fewer bytes than requested. 
654    * This method will not skip any bytes if passed a negative number of bytes 
655    * to skip. 
656    *
657    * @param n The requested number of bytes to skip.
658    * @return The requested number of bytes to skip.
659    * @exception IOException If an error occurs.
660    * @specnote The JDK docs claim that this returns the number of bytes 
661    *  actually skipped. The JCL claims that this method can throw an 
662    *  EOFException. Neither of these appear to be true in the JDK 1.3's
663    *  implementation. This tries to implement the actual JDK behaviour.
664    */
665   public final int skipBytes(int n) throws IOException
666   {
667     if (n <= 0)
668       return 0;    
669     try
670       {
671         return (int) in.skip(n);
672       }
673     catch (EOFException x)
674       {
675         // do nothing.
676       }         
677     return n;
678   }
679   
680   static boolean convertToBoolean(int b) throws EOFException
681   {
682     if (b < 0)
683       throw new EOFException();    
684     return (b != 0);
685   }
686
687   static byte convertToByte(int i) throws EOFException
688   {
689     if (i < 0)
690       throw new EOFException();
691     return (byte) i;
692   }
693
694   static int convertToUnsignedByte(int i) throws EOFException
695   {
696     if (i < 0)
697       throw new EOFException();
698     return (i & 0xFF);
699   }
700
701   static char convertToChar(byte[] buf)
702   {
703     return (char) ((buf[0] << 8) | (buf[1] & 0xff));  
704   }  
705
706   static short convertToShort(byte[] buf)
707   {
708     return (short) ((buf[0] << 8) | (buf[1] & 0xff));  
709   }  
710
711   static int convertToUnsignedShort(byte[] buf)
712   {
713     return (((buf[0] & 0xff) << 8) | (buf[1] & 0xff));  
714   }
715
716   static int convertToInt(byte[] buf)
717   {
718     return (((buf[0] & 0xff) << 24) | ((buf[1] & 0xff) << 16) |
719             ((buf[2] & 0xff) << 8) | (buf[3] & 0xff));  
720   }
721
722   static long convertToLong(byte[] buf)
723   {
724     return (((long)(buf[0] & 0xff) << 56) |
725             ((long)(buf[1] & 0xff) << 48) |
726             ((long)(buf[2] & 0xff) << 40) |
727             ((long)(buf[3] & 0xff) << 32) |
728             ((long)(buf[4] & 0xff) << 24) |
729             ((long)(buf[5] & 0xff) << 16) |
730             ((long)(buf[6] & 0xff) <<  8) |
731             ((long)(buf[7] & 0xff)));  
732   }
733
734   static String convertFromUTF(byte[] buf) 
735     throws EOFException, UTFDataFormatException
736   {
737     StringBuffer strbuf = new StringBuffer();
738
739     for (int i = 0; i < buf.length; )
740       {
741         if ((buf[i] & 0x80) == 0)               // bit pattern 0xxxxxxx
742           strbuf.append((char) (buf[i++] & 0xFF));
743         else if ((buf[i] & 0xE0) == 0xC0)       // bit pattern 110xxxxx
744           {
745             if (i + 1 >= buf.length || (buf[i+1] & 0xC0) != 0x80)
746               throw new UTFDataFormatException();
747
748             strbuf.append((char) (((buf[i++] & 0x1F) << 6) |
749                                   (buf[i++] & 0x3F)));
750           }
751         else if ((buf[i] & 0xF0) == 0xE0)       // bit pattern 1110xxxx
752           {
753             if (i + 2 >= buf.length ||
754                 (buf[i+1] & 0xC0) != 0x80 || (buf[i+2] & 0xC0) != 0x80)
755               throw new UTFDataFormatException();
756
757             strbuf.append((char) (((buf[i++] & 0x0F) << 12) |
758                                   ((buf[i++] & 0x3F) << 6) |
759                                   (buf[i++] & 0x3F)));
760           }
761         else // must be ((buf[i] & 0xF0) == 0xF0 || (buf[i] & 0xC0) == 0x80)
762           throw new UTFDataFormatException();   // bit patterns 1111xxxx or
763                                                 //              10xxxxxx
764       }
765
766     return strbuf.toString();
767   }
768 }