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