src/java.base/share/classes/java/io/DataInputStream.java
changeset 47216 71c04702a3d5
parent 37591 b71bda3ce058
child 58242 94bb65cb37d3
child 58678 9cf78a70fa4f
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package java.io;
       
    27 
       
    28 /**
       
    29  * A data input stream lets an application read primitive Java data
       
    30  * types from an underlying input stream in a machine-independent
       
    31  * way. An application uses a data output stream to write data that
       
    32  * can later be read by a data input stream.
       
    33  * <p>
       
    34  * DataInputStream is not necessarily safe for multithreaded access.
       
    35  * Thread safety is optional and is the responsibility of users of
       
    36  * methods in this class.
       
    37  *
       
    38  * @author  Arthur van Hoff
       
    39  * @see     java.io.DataOutputStream
       
    40  * @since   1.0
       
    41  */
       
    42 public
       
    43 class DataInputStream extends FilterInputStream implements DataInput {
       
    44 
       
    45     /**
       
    46      * Creates a DataInputStream that uses the specified
       
    47      * underlying InputStream.
       
    48      *
       
    49      * @param  in   the specified input stream
       
    50      */
       
    51     public DataInputStream(InputStream in) {
       
    52         super(in);
       
    53     }
       
    54 
       
    55     /**
       
    56      * working arrays initialized on demand by readUTF
       
    57      */
       
    58     private byte bytearr[] = new byte[80];
       
    59     private char chararr[] = new char[80];
       
    60 
       
    61     /**
       
    62      * Reads some number of bytes from the contained input stream and
       
    63      * stores them into the buffer array <code>b</code>. The number of
       
    64      * bytes actually read is returned as an integer. This method blocks
       
    65      * until input data is available, end of file is detected, or an
       
    66      * exception is thrown.
       
    67      *
       
    68      * <p>If <code>b</code> is null, a <code>NullPointerException</code> is
       
    69      * thrown. If the length of <code>b</code> is zero, then no bytes are
       
    70      * read and <code>0</code> is returned; otherwise, there is an attempt
       
    71      * to read at least one byte. If no byte is available because the
       
    72      * stream is at end of file, the value <code>-1</code> is returned;
       
    73      * otherwise, at least one byte is read and stored into <code>b</code>.
       
    74      *
       
    75      * <p>The first byte read is stored into element <code>b[0]</code>, the
       
    76      * next one into <code>b[1]</code>, and so on. The number of bytes read
       
    77      * is, at most, equal to the length of <code>b</code>. Let <code>k</code>
       
    78      * be the number of bytes actually read; these bytes will be stored in
       
    79      * elements <code>b[0]</code> through <code>b[k-1]</code>, leaving
       
    80      * elements <code>b[k]</code> through <code>b[b.length-1]</code>
       
    81      * unaffected.
       
    82      *
       
    83      * <p>The <code>read(b)</code> method has the same effect as:
       
    84      * <blockquote><pre>
       
    85      * read(b, 0, b.length)
       
    86      * </pre></blockquote>
       
    87      *
       
    88      * @param      b   the buffer into which the data is read.
       
    89      * @return     the total number of bytes read into the buffer, or
       
    90      *             <code>-1</code> if there is no more data because the end
       
    91      *             of the stream has been reached.
       
    92      * @exception  IOException if the first byte cannot be read for any reason
       
    93      * other than end of file, the stream has been closed and the underlying
       
    94      * input stream does not support reading after close, or another I/O
       
    95      * error occurs.
       
    96      * @see        java.io.FilterInputStream#in
       
    97      * @see        java.io.InputStream#read(byte[], int, int)
       
    98      */
       
    99     public final int read(byte b[]) throws IOException {
       
   100         return in.read(b, 0, b.length);
       
   101     }
       
   102 
       
   103     /**
       
   104      * Reads up to <code>len</code> bytes of data from the contained
       
   105      * input stream into an array of bytes.  An attempt is made to read
       
   106      * as many as <code>len</code> bytes, but a smaller number may be read,
       
   107      * possibly zero. The number of bytes actually read is returned as an
       
   108      * integer.
       
   109      *
       
   110      * <p> This method blocks until input data is available, end of file is
       
   111      * detected, or an exception is thrown.
       
   112      *
       
   113      * <p> If <code>len</code> is zero, then no bytes are read and
       
   114      * <code>0</code> is returned; otherwise, there is an attempt to read at
       
   115      * least one byte. If no byte is available because the stream is at end of
       
   116      * file, the value <code>-1</code> is returned; otherwise, at least one
       
   117      * byte is read and stored into <code>b</code>.
       
   118      *
       
   119      * <p> The first byte read is stored into element <code>b[off]</code>, the
       
   120      * next one into <code>b[off+1]</code>, and so on. The number of bytes read
       
   121      * is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
       
   122      * bytes actually read; these bytes will be stored in elements
       
   123      * <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
       
   124      * leaving elements <code>b[off+</code><i>k</i><code>]</code> through
       
   125      * <code>b[off+len-1]</code> unaffected.
       
   126      *
       
   127      * <p> In every case, elements <code>b[0]</code> through
       
   128      * <code>b[off]</code> and elements <code>b[off+len]</code> through
       
   129      * <code>b[b.length-1]</code> are unaffected.
       
   130      *
       
   131      * @param      b     the buffer into which the data is read.
       
   132      * @param off the start offset in the destination array <code>b</code>
       
   133      * @param      len   the maximum number of bytes read.
       
   134      * @return     the total number of bytes read into the buffer, or
       
   135      *             <code>-1</code> if there is no more data because the end
       
   136      *             of the stream has been reached.
       
   137      * @exception  NullPointerException If <code>b</code> is <code>null</code>.
       
   138      * @exception  IndexOutOfBoundsException If <code>off</code> is negative,
       
   139      * <code>len</code> is negative, or <code>len</code> is greater than
       
   140      * <code>b.length - off</code>
       
   141      * @exception  IOException if the first byte cannot be read for any reason
       
   142      * other than end of file, the stream has been closed and the underlying
       
   143      * input stream does not support reading after close, or another I/O
       
   144      * error occurs.
       
   145      * @see        java.io.FilterInputStream#in
       
   146      * @see        java.io.InputStream#read(byte[], int, int)
       
   147      */
       
   148     public final int read(byte b[], int off, int len) throws IOException {
       
   149         return in.read(b, off, len);
       
   150     }
       
   151 
       
   152     /**
       
   153      * See the general contract of the {@code readFully}
       
   154      * method of {@code DataInput}.
       
   155      * <p>
       
   156      * Bytes
       
   157      * for this operation are read from the contained
       
   158      * input stream.
       
   159      *
       
   160      * @param   b   the buffer into which the data is read.
       
   161      * @throws  NullPointerException if {@code b} is {@code null}.
       
   162      * @throws  EOFException  if this input stream reaches the end before
       
   163      *          reading all the bytes.
       
   164      * @throws  IOException   the stream has been closed and the contained
       
   165      *          input stream does not support reading after close, or
       
   166      *          another I/O error occurs.
       
   167      * @see     java.io.FilterInputStream#in
       
   168      */
       
   169     public final void readFully(byte b[]) throws IOException {
       
   170         readFully(b, 0, b.length);
       
   171     }
       
   172 
       
   173     /**
       
   174      * See the general contract of the {@code readFully}
       
   175      * method of {@code DataInput}.
       
   176      * <p>
       
   177      * Bytes
       
   178      * for this operation are read from the contained
       
   179      * input stream.
       
   180      *
       
   181      * @param      b     the buffer into which the data is read.
       
   182      * @param      off   the start offset in the data array {@code b}.
       
   183      * @param      len   the number of bytes to read.
       
   184      * @exception  NullPointerException if {@code b} is {@code null}.
       
   185      * @exception  IndexOutOfBoundsException if {@code off} is negative,
       
   186      *             {@code len} is negative, or {@code len} is greater than
       
   187      *             {@code b.length - off}.
       
   188      * @exception  EOFException  if this input stream reaches the end before
       
   189      *             reading all the bytes.
       
   190      * @exception  IOException   the stream has been closed and the contained
       
   191      *             input stream does not support reading after close, or
       
   192      *             another I/O error occurs.
       
   193      * @see        java.io.FilterInputStream#in
       
   194      */
       
   195     public final void readFully(byte b[], int off, int len) throws IOException {
       
   196         if (len < 0)
       
   197             throw new IndexOutOfBoundsException();
       
   198         int n = 0;
       
   199         while (n < len) {
       
   200             int count = in.read(b, off + n, len - n);
       
   201             if (count < 0)
       
   202                 throw new EOFException();
       
   203             n += count;
       
   204         }
       
   205     }
       
   206 
       
   207     /**
       
   208      * See the general contract of the <code>skipBytes</code>
       
   209      * method of <code>DataInput</code>.
       
   210      * <p>
       
   211      * Bytes for this operation are read from the contained
       
   212      * input stream.
       
   213      *
       
   214      * @param      n   the number of bytes to be skipped.
       
   215      * @return     the actual number of bytes skipped.
       
   216      * @exception  IOException  if the contained input stream does not support
       
   217      *             seek, or the stream has been closed and
       
   218      *             the contained input stream does not support
       
   219      *             reading after close, or another I/O error occurs.
       
   220      */
       
   221     public final int skipBytes(int n) throws IOException {
       
   222         int total = 0;
       
   223         int cur = 0;
       
   224 
       
   225         while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {
       
   226             total += cur;
       
   227         }
       
   228 
       
   229         return total;
       
   230     }
       
   231 
       
   232     /**
       
   233      * See the general contract of the <code>readBoolean</code>
       
   234      * method of <code>DataInput</code>.
       
   235      * <p>
       
   236      * Bytes for this operation are read from the contained
       
   237      * input stream.
       
   238      *
       
   239      * @return     the <code>boolean</code> value read.
       
   240      * @exception  EOFException  if this input stream has reached the end.
       
   241      * @exception  IOException   the stream has been closed and the contained
       
   242      *             input stream does not support reading after close, or
       
   243      *             another I/O error occurs.
       
   244      * @see        java.io.FilterInputStream#in
       
   245      */
       
   246     public final boolean readBoolean() throws IOException {
       
   247         int ch = in.read();
       
   248         if (ch < 0)
       
   249             throw new EOFException();
       
   250         return (ch != 0);
       
   251     }
       
   252 
       
   253     /**
       
   254      * See the general contract of the <code>readByte</code>
       
   255      * method of <code>DataInput</code>.
       
   256      * <p>
       
   257      * Bytes
       
   258      * for this operation are read from the contained
       
   259      * input stream.
       
   260      *
       
   261      * @return     the next byte of this input stream as a signed 8-bit
       
   262      *             <code>byte</code>.
       
   263      * @exception  EOFException  if this input stream has reached the end.
       
   264      * @exception  IOException   the stream has been closed and the contained
       
   265      *             input stream does not support reading after close, or
       
   266      *             another I/O error occurs.
       
   267      * @see        java.io.FilterInputStream#in
       
   268      */
       
   269     public final byte readByte() throws IOException {
       
   270         int ch = in.read();
       
   271         if (ch < 0)
       
   272             throw new EOFException();
       
   273         return (byte)(ch);
       
   274     }
       
   275 
       
   276     /**
       
   277      * See the general contract of the <code>readUnsignedByte</code>
       
   278      * method of <code>DataInput</code>.
       
   279      * <p>
       
   280      * Bytes
       
   281      * for this operation are read from the contained
       
   282      * input stream.
       
   283      *
       
   284      * @return     the next byte of this input stream, interpreted as an
       
   285      *             unsigned 8-bit number.
       
   286      * @exception  EOFException  if this input stream has reached the end.
       
   287      * @exception  IOException   the stream has been closed and the contained
       
   288      *             input stream does not support reading after close, or
       
   289      *             another I/O error occurs.
       
   290      * @see         java.io.FilterInputStream#in
       
   291      */
       
   292     public final int readUnsignedByte() throws IOException {
       
   293         int ch = in.read();
       
   294         if (ch < 0)
       
   295             throw new EOFException();
       
   296         return ch;
       
   297     }
       
   298 
       
   299     /**
       
   300      * See the general contract of the <code>readShort</code>
       
   301      * method of <code>DataInput</code>.
       
   302      * <p>
       
   303      * Bytes
       
   304      * for this operation are read from the contained
       
   305      * input stream.
       
   306      *
       
   307      * @return     the next two bytes of this input stream, interpreted as a
       
   308      *             signed 16-bit number.
       
   309      * @exception  EOFException  if this input stream reaches the end before
       
   310      *               reading two bytes.
       
   311      * @exception  IOException   the stream has been closed and the contained
       
   312      *             input stream does not support reading after close, or
       
   313      *             another I/O error occurs.
       
   314      * @see        java.io.FilterInputStream#in
       
   315      */
       
   316     public final short readShort() throws IOException {
       
   317         int ch1 = in.read();
       
   318         int ch2 = in.read();
       
   319         if ((ch1 | ch2) < 0)
       
   320             throw new EOFException();
       
   321         return (short)((ch1 << 8) + (ch2 << 0));
       
   322     }
       
   323 
       
   324     /**
       
   325      * See the general contract of the <code>readUnsignedShort</code>
       
   326      * method of <code>DataInput</code>.
       
   327      * <p>
       
   328      * Bytes
       
   329      * for this operation are read from the contained
       
   330      * input stream.
       
   331      *
       
   332      * @return     the next two bytes of this input stream, interpreted as an
       
   333      *             unsigned 16-bit integer.
       
   334      * @exception  EOFException  if this input stream reaches the end before
       
   335      *             reading two bytes.
       
   336      * @exception  IOException   the stream has been closed and the contained
       
   337      *             input stream does not support reading after close, or
       
   338      *             another I/O error occurs.
       
   339      * @see        java.io.FilterInputStream#in
       
   340      */
       
   341     public final int readUnsignedShort() throws IOException {
       
   342         int ch1 = in.read();
       
   343         int ch2 = in.read();
       
   344         if ((ch1 | ch2) < 0)
       
   345             throw new EOFException();
       
   346         return (ch1 << 8) + (ch2 << 0);
       
   347     }
       
   348 
       
   349     /**
       
   350      * See the general contract of the <code>readChar</code>
       
   351      * method of <code>DataInput</code>.
       
   352      * <p>
       
   353      * Bytes
       
   354      * for this operation are read from the contained
       
   355      * input stream.
       
   356      *
       
   357      * @return     the next two bytes of this input stream, interpreted as a
       
   358      *             <code>char</code>.
       
   359      * @exception  EOFException  if this input stream reaches the end before
       
   360      *               reading two bytes.
       
   361      * @exception  IOException   the stream has been closed and the contained
       
   362      *             input stream does not support reading after close, or
       
   363      *             another I/O error occurs.
       
   364      * @see        java.io.FilterInputStream#in
       
   365      */
       
   366     public final char readChar() throws IOException {
       
   367         int ch1 = in.read();
       
   368         int ch2 = in.read();
       
   369         if ((ch1 | ch2) < 0)
       
   370             throw new EOFException();
       
   371         return (char)((ch1 << 8) + (ch2 << 0));
       
   372     }
       
   373 
       
   374     /**
       
   375      * See the general contract of the <code>readInt</code>
       
   376      * method of <code>DataInput</code>.
       
   377      * <p>
       
   378      * Bytes
       
   379      * for this operation are read from the contained
       
   380      * input stream.
       
   381      *
       
   382      * @return     the next four bytes of this input stream, interpreted as an
       
   383      *             <code>int</code>.
       
   384      * @exception  EOFException  if this input stream reaches the end before
       
   385      *               reading four bytes.
       
   386      * @exception  IOException   the stream has been closed and the contained
       
   387      *             input stream does not support reading after close, or
       
   388      *             another I/O error occurs.
       
   389      * @see        java.io.FilterInputStream#in
       
   390      */
       
   391     public final int readInt() throws IOException {
       
   392         int ch1 = in.read();
       
   393         int ch2 = in.read();
       
   394         int ch3 = in.read();
       
   395         int ch4 = in.read();
       
   396         if ((ch1 | ch2 | ch3 | ch4) < 0)
       
   397             throw new EOFException();
       
   398         return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
       
   399     }
       
   400 
       
   401     private byte readBuffer[] = new byte[8];
       
   402 
       
   403     /**
       
   404      * See the general contract of the <code>readLong</code>
       
   405      * method of <code>DataInput</code>.
       
   406      * <p>
       
   407      * Bytes
       
   408      * for this operation are read from the contained
       
   409      * input stream.
       
   410      *
       
   411      * @return     the next eight bytes of this input stream, interpreted as a
       
   412      *             <code>long</code>.
       
   413      * @exception  EOFException  if this input stream reaches the end before
       
   414      *               reading eight bytes.
       
   415      * @exception  IOException   the stream has been closed and the contained
       
   416      *             input stream does not support reading after close, or
       
   417      *             another I/O error occurs.
       
   418      * @see        java.io.FilterInputStream#in
       
   419      */
       
   420     public final long readLong() throws IOException {
       
   421         readFully(readBuffer, 0, 8);
       
   422         return (((long)readBuffer[0] << 56) +
       
   423                 ((long)(readBuffer[1] & 255) << 48) +
       
   424                 ((long)(readBuffer[2] & 255) << 40) +
       
   425                 ((long)(readBuffer[3] & 255) << 32) +
       
   426                 ((long)(readBuffer[4] & 255) << 24) +
       
   427                 ((readBuffer[5] & 255) << 16) +
       
   428                 ((readBuffer[6] & 255) <<  8) +
       
   429                 ((readBuffer[7] & 255) <<  0));
       
   430     }
       
   431 
       
   432     /**
       
   433      * See the general contract of the <code>readFloat</code>
       
   434      * method of <code>DataInput</code>.
       
   435      * <p>
       
   436      * Bytes
       
   437      * for this operation are read from the contained
       
   438      * input stream.
       
   439      *
       
   440      * @return     the next four bytes of this input stream, interpreted as a
       
   441      *             <code>float</code>.
       
   442      * @exception  EOFException  if this input stream reaches the end before
       
   443      *               reading four bytes.
       
   444      * @exception  IOException   the stream has been closed and the contained
       
   445      *             input stream does not support reading after close, or
       
   446      *             another I/O error occurs.
       
   447      * @see        java.io.DataInputStream#readInt()
       
   448      * @see        java.lang.Float#intBitsToFloat(int)
       
   449      */
       
   450     public final float readFloat() throws IOException {
       
   451         return Float.intBitsToFloat(readInt());
       
   452     }
       
   453 
       
   454     /**
       
   455      * See the general contract of the <code>readDouble</code>
       
   456      * method of <code>DataInput</code>.
       
   457      * <p>
       
   458      * Bytes
       
   459      * for this operation are read from the contained
       
   460      * input stream.
       
   461      *
       
   462      * @return     the next eight bytes of this input stream, interpreted as a
       
   463      *             <code>double</code>.
       
   464      * @exception  EOFException  if this input stream reaches the end before
       
   465      *               reading eight bytes.
       
   466      * @exception  IOException   the stream has been closed and the contained
       
   467      *             input stream does not support reading after close, or
       
   468      *             another I/O error occurs.
       
   469      * @see        java.io.DataInputStream#readLong()
       
   470      * @see        java.lang.Double#longBitsToDouble(long)
       
   471      */
       
   472     public final double readDouble() throws IOException {
       
   473         return Double.longBitsToDouble(readLong());
       
   474     }
       
   475 
       
   476     private char lineBuffer[];
       
   477 
       
   478     /**
       
   479      * See the general contract of the <code>readLine</code>
       
   480      * method of <code>DataInput</code>.
       
   481      * <p>
       
   482      * Bytes
       
   483      * for this operation are read from the contained
       
   484      * input stream.
       
   485      *
       
   486      * @deprecated This method does not properly convert bytes to characters.
       
   487      * As of JDK&nbsp;1.1, the preferred way to read lines of text is via the
       
   488      * <code>BufferedReader.readLine()</code> method.  Programs that use the
       
   489      * <code>DataInputStream</code> class to read lines can be converted to use
       
   490      * the <code>BufferedReader</code> class by replacing code of the form:
       
   491      * <blockquote><pre>
       
   492      *     DataInputStream d =&nbsp;new&nbsp;DataInputStream(in);
       
   493      * </pre></blockquote>
       
   494      * with:
       
   495      * <blockquote><pre>
       
   496      *     BufferedReader d
       
   497      *          =&nbsp;new&nbsp;BufferedReader(new&nbsp;InputStreamReader(in));
       
   498      * </pre></blockquote>
       
   499      *
       
   500      * @return     the next line of text from this input stream.
       
   501      * @exception  IOException  if an I/O error occurs.
       
   502      * @see        java.io.BufferedReader#readLine()
       
   503      * @see        java.io.FilterInputStream#in
       
   504      */
       
   505     @Deprecated
       
   506     public final String readLine() throws IOException {
       
   507         char buf[] = lineBuffer;
       
   508 
       
   509         if (buf == null) {
       
   510             buf = lineBuffer = new char[128];
       
   511         }
       
   512 
       
   513         int room = buf.length;
       
   514         int offset = 0;
       
   515         int c;
       
   516 
       
   517 loop:   while (true) {
       
   518             switch (c = in.read()) {
       
   519               case -1:
       
   520               case '\n':
       
   521                 break loop;
       
   522 
       
   523               case '\r':
       
   524                 int c2 = in.read();
       
   525                 if ((c2 != '\n') && (c2 != -1)) {
       
   526                     if (!(in instanceof PushbackInputStream)) {
       
   527                         this.in = new PushbackInputStream(in);
       
   528                     }
       
   529                     ((PushbackInputStream)in).unread(c2);
       
   530                 }
       
   531                 break loop;
       
   532 
       
   533               default:
       
   534                 if (--room < 0) {
       
   535                     buf = new char[offset + 128];
       
   536                     room = buf.length - offset - 1;
       
   537                     System.arraycopy(lineBuffer, 0, buf, 0, offset);
       
   538                     lineBuffer = buf;
       
   539                 }
       
   540                 buf[offset++] = (char) c;
       
   541                 break;
       
   542             }
       
   543         }
       
   544         if ((c == -1) && (offset == 0)) {
       
   545             return null;
       
   546         }
       
   547         return String.copyValueOf(buf, 0, offset);
       
   548     }
       
   549 
       
   550     /**
       
   551      * See the general contract of the <code>readUTF</code>
       
   552      * method of <code>DataInput</code>.
       
   553      * <p>
       
   554      * Bytes
       
   555      * for this operation are read from the contained
       
   556      * input stream.
       
   557      *
       
   558      * @return     a Unicode string.
       
   559      * @exception  EOFException  if this input stream reaches the end before
       
   560      *               reading all the bytes.
       
   561      * @exception  IOException   the stream has been closed and the contained
       
   562      *             input stream does not support reading after close, or
       
   563      *             another I/O error occurs.
       
   564      * @exception  UTFDataFormatException if the bytes do not represent a valid
       
   565      *             modified UTF-8 encoding of a string.
       
   566      * @see        java.io.DataInputStream#readUTF(java.io.DataInput)
       
   567      */
       
   568     public final String readUTF() throws IOException {
       
   569         return readUTF(this);
       
   570     }
       
   571 
       
   572     /**
       
   573      * Reads from the
       
   574      * stream <code>in</code> a representation
       
   575      * of a Unicode  character string encoded in
       
   576      * <a href="DataInput.html#modified-utf-8">modified UTF-8</a> format;
       
   577      * this string of characters is then returned as a <code>String</code>.
       
   578      * The details of the modified UTF-8 representation
       
   579      * are  exactly the same as for the <code>readUTF</code>
       
   580      * method of <code>DataInput</code>.
       
   581      *
       
   582      * @param      in   a data input stream.
       
   583      * @return     a Unicode string.
       
   584      * @exception  EOFException            if the input stream reaches the end
       
   585      *               before all the bytes.
       
   586      * @exception  IOException   the stream has been closed and the contained
       
   587      *             input stream does not support reading after close, or
       
   588      *             another I/O error occurs.
       
   589      * @exception  UTFDataFormatException  if the bytes do not represent a
       
   590      *               valid modified UTF-8 encoding of a Unicode string.
       
   591      * @see        java.io.DataInputStream#readUnsignedShort()
       
   592      */
       
   593     public static final String readUTF(DataInput in) throws IOException {
       
   594         int utflen = in.readUnsignedShort();
       
   595         byte[] bytearr = null;
       
   596         char[] chararr = null;
       
   597         if (in instanceof DataInputStream) {
       
   598             DataInputStream dis = (DataInputStream)in;
       
   599             if (dis.bytearr.length < utflen){
       
   600                 dis.bytearr = new byte[utflen*2];
       
   601                 dis.chararr = new char[utflen*2];
       
   602             }
       
   603             chararr = dis.chararr;
       
   604             bytearr = dis.bytearr;
       
   605         } else {
       
   606             bytearr = new byte[utflen];
       
   607             chararr = new char[utflen];
       
   608         }
       
   609 
       
   610         int c, char2, char3;
       
   611         int count = 0;
       
   612         int chararr_count=0;
       
   613 
       
   614         in.readFully(bytearr, 0, utflen);
       
   615 
       
   616         while (count < utflen) {
       
   617             c = (int) bytearr[count] & 0xff;
       
   618             if (c > 127) break;
       
   619             count++;
       
   620             chararr[chararr_count++]=(char)c;
       
   621         }
       
   622 
       
   623         while (count < utflen) {
       
   624             c = (int) bytearr[count] & 0xff;
       
   625             switch (c >> 4) {
       
   626                 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
       
   627                     /* 0xxxxxxx*/
       
   628                     count++;
       
   629                     chararr[chararr_count++]=(char)c;
       
   630                     break;
       
   631                 case 12: case 13:
       
   632                     /* 110x xxxx   10xx xxxx*/
       
   633                     count += 2;
       
   634                     if (count > utflen)
       
   635                         throw new UTFDataFormatException(
       
   636                             "malformed input: partial character at end");
       
   637                     char2 = (int) bytearr[count-1];
       
   638                     if ((char2 & 0xC0) != 0x80)
       
   639                         throw new UTFDataFormatException(
       
   640                             "malformed input around byte " + count);
       
   641                     chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
       
   642                                                     (char2 & 0x3F));
       
   643                     break;
       
   644                 case 14:
       
   645                     /* 1110 xxxx  10xx xxxx  10xx xxxx */
       
   646                     count += 3;
       
   647                     if (count > utflen)
       
   648                         throw new UTFDataFormatException(
       
   649                             "malformed input: partial character at end");
       
   650                     char2 = (int) bytearr[count-2];
       
   651                     char3 = (int) bytearr[count-1];
       
   652                     if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
       
   653                         throw new UTFDataFormatException(
       
   654                             "malformed input around byte " + (count-1));
       
   655                     chararr[chararr_count++]=(char)(((c     & 0x0F) << 12) |
       
   656                                                     ((char2 & 0x3F) << 6)  |
       
   657                                                     ((char3 & 0x3F) << 0));
       
   658                     break;
       
   659                 default:
       
   660                     /* 10xx xxxx,  1111 xxxx */
       
   661                     throw new UTFDataFormatException(
       
   662                         "malformed input around byte " + count);
       
   663             }
       
   664         }
       
   665         // The number of chars produced may be less than utflen
       
   666         return new String(chararr, 0, chararr_count);
       
   667     }
       
   668 }