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 }