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