emul/src/main/java/java/io/DataInputStream.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sat, 10 Nov 2012 17:27:07 +0100
branchjdk7-b147
changeset 146 394379b81e73
child 149 32653a09f0db
permissions -rw-r--r--
For purposes of running javap we may need DataInputStream
     1 /*
     2  * Copyright (c) 1994, 2006, 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   JDK1.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</code>
   154      * method of <code>DataInput</code>.
   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      * @exception  EOFException  if this input stream reaches the end before
   162      *             reading all the bytes.
   163      * @exception  IOException   the stream has been closed and the contained
   164      *             input stream does not support reading after close, or
   165      *             another I/O error occurs.
   166      * @see        java.io.FilterInputStream#in
   167      */
   168     public final void readFully(byte b[]) throws IOException {
   169         readFully(b, 0, b.length);
   170     }
   171 
   172     /**
   173      * See the general contract of the <code>readFully</code>
   174      * method of <code>DataInput</code>.
   175      * <p>
   176      * Bytes
   177      * for this operation are read from the contained
   178      * input stream.
   179      *
   180      * @param      b     the buffer into which the data is read.
   181      * @param      off   the start offset of the data.
   182      * @param      len   the number of bytes to read.
   183      * @exception  EOFException  if this input stream reaches the end before
   184      *               reading all the bytes.
   185      * @exception  IOException   the stream has been closed and the contained
   186      *             input stream does not support reading after close, or
   187      *             another I/O error occurs.
   188      * @see        java.io.FilterInputStream#in
   189      */
   190     public final void readFully(byte b[], int off, int len) throws IOException {
   191         if (len < 0)
   192             throw new IndexOutOfBoundsException();
   193         int n = 0;
   194         while (n < len) {
   195             int count = in.read(b, off + n, len - n);
   196             if (count < 0)
   197                 throw new EOFException();
   198             n += count;
   199         }
   200     }
   201 
   202     /**
   203      * See the general contract of the <code>skipBytes</code>
   204      * method of <code>DataInput</code>.
   205      * <p>
   206      * Bytes for this operation are read from the contained
   207      * input stream.
   208      *
   209      * @param      n   the number of bytes to be skipped.
   210      * @return     the actual number of bytes skipped.
   211      * @exception  IOException  if the contained input stream does not support
   212      *             seek, or the stream has been closed and
   213      *             the contained input stream does not support
   214      *             reading after close, or another I/O error occurs.
   215      */
   216     public final int skipBytes(int n) throws IOException {
   217         int total = 0;
   218         int cur = 0;
   219 
   220         while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {
   221             total += cur;
   222         }
   223 
   224         return total;
   225     }
   226 
   227     /**
   228      * See the general contract of the <code>readBoolean</code>
   229      * method of <code>DataInput</code>.
   230      * <p>
   231      * Bytes for this operation are read from the contained
   232      * input stream.
   233      *
   234      * @return     the <code>boolean</code> value read.
   235      * @exception  EOFException  if this input stream has reached the end.
   236      * @exception  IOException   the stream has been closed and the contained
   237      *             input stream does not support reading after close, or
   238      *             another I/O error occurs.
   239      * @see        java.io.FilterInputStream#in
   240      */
   241     public final boolean readBoolean() throws IOException {
   242         int ch = in.read();
   243         if (ch < 0)
   244             throw new EOFException();
   245         return (ch != 0);
   246     }
   247 
   248     /**
   249      * See the general contract of the <code>readByte</code>
   250      * method of <code>DataInput</code>.
   251      * <p>
   252      * Bytes
   253      * for this operation are read from the contained
   254      * input stream.
   255      *
   256      * @return     the next byte of this input stream as a signed 8-bit
   257      *             <code>byte</code>.
   258      * @exception  EOFException  if this input stream has reached the end.
   259      * @exception  IOException   the stream has been closed and the contained
   260      *             input stream does not support reading after close, or
   261      *             another I/O error occurs.
   262      * @see        java.io.FilterInputStream#in
   263      */
   264     public final byte readByte() throws IOException {
   265         int ch = in.read();
   266         if (ch < 0)
   267             throw new EOFException();
   268         return (byte)(ch);
   269     }
   270 
   271     /**
   272      * See the general contract of the <code>readUnsignedByte</code>
   273      * method of <code>DataInput</code>.
   274      * <p>
   275      * Bytes
   276      * for this operation are read from the contained
   277      * input stream.
   278      *
   279      * @return     the next byte of this input stream, interpreted as an
   280      *             unsigned 8-bit number.
   281      * @exception  EOFException  if this input stream has reached the end.
   282      * @exception  IOException   the stream has been closed and the contained
   283      *             input stream does not support reading after close, or
   284      *             another I/O error occurs.
   285      * @see         java.io.FilterInputStream#in
   286      */
   287     public final int readUnsignedByte() throws IOException {
   288         int ch = in.read();
   289         if (ch < 0)
   290             throw new EOFException();
   291         return ch;
   292     }
   293 
   294     /**
   295      * See the general contract of the <code>readShort</code>
   296      * method of <code>DataInput</code>.
   297      * <p>
   298      * Bytes
   299      * for this operation are read from the contained
   300      * input stream.
   301      *
   302      * @return     the next two bytes of this input stream, interpreted as a
   303      *             signed 16-bit number.
   304      * @exception  EOFException  if this input stream reaches the end before
   305      *               reading two bytes.
   306      * @exception  IOException   the stream has been closed and the contained
   307      *             input stream does not support reading after close, or
   308      *             another I/O error occurs.
   309      * @see        java.io.FilterInputStream#in
   310      */
   311     public final short readShort() throws IOException {
   312         int ch1 = in.read();
   313         int ch2 = in.read();
   314         if ((ch1 | ch2) < 0)
   315             throw new EOFException();
   316         return (short)((ch1 << 8) + (ch2 << 0));
   317     }
   318 
   319     /**
   320      * See the general contract of the <code>readUnsignedShort</code>
   321      * method of <code>DataInput</code>.
   322      * <p>
   323      * Bytes
   324      * for this operation are read from the contained
   325      * input stream.
   326      *
   327      * @return     the next two bytes of this input stream, interpreted as an
   328      *             unsigned 16-bit integer.
   329      * @exception  EOFException  if this input stream reaches the end before
   330      *             reading two bytes.
   331      * @exception  IOException   the stream has been closed and the contained
   332      *             input stream does not support reading after close, or
   333      *             another I/O error occurs.
   334      * @see        java.io.FilterInputStream#in
   335      */
   336     public final int readUnsignedShort() throws IOException {
   337         int ch1 = in.read();
   338         int ch2 = in.read();
   339         if ((ch1 | ch2) < 0)
   340             throw new EOFException();
   341         return (ch1 << 8) + (ch2 << 0);
   342     }
   343 
   344     /**
   345      * See the general contract of the <code>readChar</code>
   346      * method of <code>DataInput</code>.
   347      * <p>
   348      * Bytes
   349      * for this operation are read from the contained
   350      * input stream.
   351      *
   352      * @return     the next two bytes of this input stream, interpreted as a
   353      *             <code>char</code>.
   354      * @exception  EOFException  if this input stream reaches the end before
   355      *               reading two bytes.
   356      * @exception  IOException   the stream has been closed and the contained
   357      *             input stream does not support reading after close, or
   358      *             another I/O error occurs.
   359      * @see        java.io.FilterInputStream#in
   360      */
   361     public final char readChar() throws IOException {
   362         int ch1 = in.read();
   363         int ch2 = in.read();
   364         if ((ch1 | ch2) < 0)
   365             throw new EOFException();
   366         return (char)((ch1 << 8) + (ch2 << 0));
   367     }
   368 
   369     /**
   370      * See the general contract of the <code>readInt</code>
   371      * method of <code>DataInput</code>.
   372      * <p>
   373      * Bytes
   374      * for this operation are read from the contained
   375      * input stream.
   376      *
   377      * @return     the next four bytes of this input stream, interpreted as an
   378      *             <code>int</code>.
   379      * @exception  EOFException  if this input stream reaches the end before
   380      *               reading four bytes.
   381      * @exception  IOException   the stream has been closed and the contained
   382      *             input stream does not support reading after close, or
   383      *             another I/O error occurs.
   384      * @see        java.io.FilterInputStream#in
   385      */
   386     public final int readInt() throws IOException {
   387         int ch1 = in.read();
   388         int ch2 = in.read();
   389         int ch3 = in.read();
   390         int ch4 = in.read();
   391         if ((ch1 | ch2 | ch3 | ch4) < 0)
   392             throw new EOFException();
   393         return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
   394     }
   395 
   396     private byte readBuffer[] = new byte[8];
   397 
   398     /**
   399      * See the general contract of the <code>readLong</code>
   400      * method of <code>DataInput</code>.
   401      * <p>
   402      * Bytes
   403      * for this operation are read from the contained
   404      * input stream.
   405      *
   406      * @return     the next eight bytes of this input stream, interpreted as a
   407      *             <code>long</code>.
   408      * @exception  EOFException  if this input stream reaches the end before
   409      *               reading eight bytes.
   410      * @exception  IOException   the stream has been closed and the contained
   411      *             input stream does not support reading after close, or
   412      *             another I/O error occurs.
   413      * @see        java.io.FilterInputStream#in
   414      */
   415     public final long readLong() throws IOException {
   416         readFully(readBuffer, 0, 8);
   417         return (((long)readBuffer[0] << 56) +
   418                 ((long)(readBuffer[1] & 255) << 48) +
   419                 ((long)(readBuffer[2] & 255) << 40) +
   420                 ((long)(readBuffer[3] & 255) << 32) +
   421                 ((long)(readBuffer[4] & 255) << 24) +
   422                 ((readBuffer[5] & 255) << 16) +
   423                 ((readBuffer[6] & 255) <<  8) +
   424                 ((readBuffer[7] & 255) <<  0));
   425     }
   426 
   427     /**
   428      * See the general contract of the <code>readFloat</code>
   429      * method of <code>DataInput</code>.
   430      * <p>
   431      * Bytes
   432      * for this operation are read from the contained
   433      * input stream.
   434      *
   435      * @return     the next four bytes of this input stream, interpreted as a
   436      *             <code>float</code>.
   437      * @exception  EOFException  if this input stream reaches the end before
   438      *               reading four bytes.
   439      * @exception  IOException   the stream has been closed and the contained
   440      *             input stream does not support reading after close, or
   441      *             another I/O error occurs.
   442      * @see        java.io.DataInputStream#readInt()
   443      * @see        java.lang.Float#intBitsToFloat(int)
   444      */
   445     public final float readFloat() throws IOException {
   446         return Float.intBitsToFloat(readInt());
   447     }
   448 
   449     /**
   450      * See the general contract of the <code>readDouble</code>
   451      * method of <code>DataInput</code>.
   452      * <p>
   453      * Bytes
   454      * for this operation are read from the contained
   455      * input stream.
   456      *
   457      * @return     the next eight bytes of this input stream, interpreted as a
   458      *             <code>double</code>.
   459      * @exception  EOFException  if this input stream reaches the end before
   460      *               reading eight bytes.
   461      * @exception  IOException   the stream has been closed and the contained
   462      *             input stream does not support reading after close, or
   463      *             another I/O error occurs.
   464      * @see        java.io.DataInputStream#readLong()
   465      * @see        java.lang.Double#longBitsToDouble(long)
   466      */
   467     public final double readDouble() throws IOException {
   468         return Double.longBitsToDouble(readLong());
   469     }
   470 
   471     private char lineBuffer[];
   472 
   473     /**
   474      * See the general contract of the <code>readLine</code>
   475      * method of <code>DataInput</code>.
   476      * <p>
   477      * Bytes
   478      * for this operation are read from the contained
   479      * input stream.
   480      *
   481      * @deprecated This method does not properly convert bytes to characters.
   482      * As of JDK&nbsp;1.1, the preferred way to read lines of text is via the
   483      * <code>BufferedReader.readLine()</code> method.  Programs that use the
   484      * <code>DataInputStream</code> class to read lines can be converted to use
   485      * the <code>BufferedReader</code> class by replacing code of the form:
   486      * <blockquote><pre>
   487      *     DataInputStream d =&nbsp;new&nbsp;DataInputStream(in);
   488      * </pre></blockquote>
   489      * with:
   490      * <blockquote><pre>
   491      *     BufferedReader d
   492      *          =&nbsp;new&nbsp;BufferedReader(new&nbsp;InputStreamReader(in));
   493      * </pre></blockquote>
   494      *
   495      * @return     the next line of text from this input stream.
   496      * @exception  IOException  if an I/O error occurs.
   497      * @see        java.io.BufferedReader#readLine()
   498      * @see        java.io.FilterInputStream#in
   499      */
   500     @Deprecated
   501     public final String readLine() throws IOException {
   502         char buf[] = lineBuffer;
   503 
   504         if (buf == null) {
   505             buf = lineBuffer = new char[128];
   506         }
   507 
   508         int room = buf.length;
   509         int offset = 0;
   510         int c;
   511 
   512 loop:   while (true) {
   513             switch (c = in.read()) {
   514               case -1:
   515               case '\n':
   516                 break loop;
   517 
   518               case '\r':
   519                 int c2 = in.read();
   520                 if ((c2 != '\n') && (c2 != -1)) {
   521                     if (!(in instanceof PushbackInputStream)) {
   522                         this.in = new PushbackInputStream(in);
   523                     }
   524                     ((PushbackInputStream)in).unread(c2);
   525                 }
   526                 break loop;
   527 
   528               default:
   529                 if (--room < 0) {
   530                     buf = new char[offset + 128];
   531                     room = buf.length - offset - 1;
   532                     System.arraycopy(lineBuffer, 0, buf, 0, offset);
   533                     lineBuffer = buf;
   534                 }
   535                 buf[offset++] = (char) c;
   536                 break;
   537             }
   538         }
   539         if ((c == -1) && (offset == 0)) {
   540             return null;
   541         }
   542         return String.copyValueOf(buf, 0, offset);
   543     }
   544 
   545     /**
   546      * See the general contract of the <code>readUTF</code>
   547      * method of <code>DataInput</code>.
   548      * <p>
   549      * Bytes
   550      * for this operation are read from the contained
   551      * input stream.
   552      *
   553      * @return     a Unicode string.
   554      * @exception  EOFException  if this input stream reaches the end before
   555      *               reading all the bytes.
   556      * @exception  IOException   the stream has been closed and the contained
   557      *             input stream does not support reading after close, or
   558      *             another I/O error occurs.
   559      * @exception  UTFDataFormatException if the bytes do not represent a valid
   560      *             modified UTF-8 encoding of a string.
   561      * @see        java.io.DataInputStream#readUTF(java.io.DataInput)
   562      */
   563     public final String readUTF() throws IOException {
   564         return readUTF(this);
   565     }
   566 
   567     /**
   568      * Reads from the
   569      * stream <code>in</code> a representation
   570      * of a Unicode  character string encoded in
   571      * <a href="DataInput.html#modified-utf-8">modified UTF-8</a> format;
   572      * this string of characters is then returned as a <code>String</code>.
   573      * The details of the modified UTF-8 representation
   574      * are  exactly the same as for the <code>readUTF</code>
   575      * method of <code>DataInput</code>.
   576      *
   577      * @param      in   a data input stream.
   578      * @return     a Unicode string.
   579      * @exception  EOFException            if the input stream reaches the end
   580      *               before all the bytes.
   581      * @exception  IOException   the stream has been closed and the contained
   582      *             input stream does not support reading after close, or
   583      *             another I/O error occurs.
   584      * @exception  UTFDataFormatException  if the bytes do not represent a
   585      *               valid modified UTF-8 encoding of a Unicode string.
   586      * @see        java.io.DataInputStream#readUnsignedShort()
   587      */
   588     public final static String readUTF(DataInput in) throws IOException {
   589         int utflen = in.readUnsignedShort();
   590         byte[] bytearr = null;
   591         char[] chararr = null;
   592         if (in instanceof DataInputStream) {
   593             DataInputStream dis = (DataInputStream)in;
   594             if (dis.bytearr.length < utflen){
   595                 dis.bytearr = new byte[utflen*2];
   596                 dis.chararr = new char[utflen*2];
   597             }
   598             chararr = dis.chararr;
   599             bytearr = dis.bytearr;
   600         } else {
   601             bytearr = new byte[utflen];
   602             chararr = new char[utflen];
   603         }
   604 
   605         int c, char2, char3;
   606         int count = 0;
   607         int chararr_count=0;
   608 
   609         in.readFully(bytearr, 0, utflen);
   610 
   611         while (count < utflen) {
   612             c = (int) bytearr[count] & 0xff;
   613             if (c > 127) break;
   614             count++;
   615             chararr[chararr_count++]=(char)c;
   616         }
   617 
   618         while (count < utflen) {
   619             c = (int) bytearr[count] & 0xff;
   620             switch (c >> 4) {
   621                 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
   622                     /* 0xxxxxxx*/
   623                     count++;
   624                     chararr[chararr_count++]=(char)c;
   625                     break;
   626                 case 12: case 13:
   627                     /* 110x xxxx   10xx xxxx*/
   628                     count += 2;
   629                     if (count > utflen)
   630                         throw new UTFDataFormatException(
   631                             "malformed input: partial character at end");
   632                     char2 = (int) bytearr[count-1];
   633                     if ((char2 & 0xC0) != 0x80)
   634                         throw new UTFDataFormatException(
   635                             "malformed input around byte " + count);
   636                     chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
   637                                                     (char2 & 0x3F));
   638                     break;
   639                 case 14:
   640                     /* 1110 xxxx  10xx xxxx  10xx xxxx */
   641                     count += 3;
   642                     if (count > utflen)
   643                         throw new UTFDataFormatException(
   644                             "malformed input: partial character at end");
   645                     char2 = (int) bytearr[count-2];
   646                     char3 = (int) bytearr[count-1];
   647                     if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
   648                         throw new UTFDataFormatException(
   649                             "malformed input around byte " + (count-1));
   650                     chararr[chararr_count++]=(char)(((c     & 0x0F) << 12) |
   651                                                     ((char2 & 0x3F) << 6)  |
   652                                                     ((char3 & 0x3F) << 0));
   653                     break;
   654                 default:
   655                     /* 10xx xxxx,  1111 xxxx */
   656                     throw new UTFDataFormatException(
   657                         "malformed input around byte " + count);
   658             }
   659         }
   660         // The number of chars produced may be less than utflen
   661         return new String(chararr, 0, chararr_count);
   662     }
   663 }