1. /*
  2. * @(#)DataInputStream.java 1.51 00/02/28
  3. *
  4. * Copyright 1994-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.io;
  11. /**
  12. * A data input stream lets an application read primitive Java data
  13. * types from an underlying input stream in a machine-independent
  14. * way. An application uses a data output stream to write data that
  15. * can later be read by a data input stream.
  16. * <p>
  17. * Data input streams and data output streams represent Unicode
  18. * strings in a format that is a slight modification of UTF-8. (For
  19. * more information, see X/Open Company Ltd., "File System Safe
  20. * UCS Transformation Format (FSS_UTF)", X/Open Preliminary
  21. * Specification, Document Number: P316. This information also
  22. * appears in ISO/IEC 10646, Annex P.)
  23. * <p>
  24. * All characters in the range <code>'\u0001'</code> to
  25. * <code>'\u007F'</code> are represented by a single byte:
  26. * <center><table border="3">
  27. * <tr><td><i>0</i></td> <td>bits 0-7</td></tr>
  28. * </table></center>
  29. * <p>
  30. * The null character <code>'\u0000'</code> and characters in the
  31. * range <code>'\u0080'</code> to <code>'\u07FF'</code> are
  32. * represented by a pair of bytes:
  33. * <center><table border="3">
  34. * <tr><td>1</td> <td>1</td> <td>0</td> <td>bits 6-10</td></tr>
  35. * <tr><td>1</td> <td>0</td> <td colspan=2>bits 0-5</td></tr>
  36. * </table></center><br>
  37. * Characters in the range <code>'\u0800'</code> to
  38. * <code>'\uFFFF'</code> are represented by three bytes:
  39. * <center><table border="3">
  40. * <tr><td>1</td> <td>1</td> <td>1</td> <td>0</td> <td>bits 12-15</td</tr>
  41. * <tr><td>1</td> <td>0</td> <td colspan=3>bits 6-11</td></tr>
  42. * <tr><td>1</td> <td>0</td> <td colspan=3>bits 0-5</td></tr>
  43. * </table></center>
  44. * <p>
  45. * The two differences between this format and the
  46. * "standard" UTF-8 format are the following:
  47. * <ul>
  48. * <li>The null byte <code>'\u0000'</code> is encoded in 2-byte format
  49. * rather than 1-byte, so that the encoded strings never have
  50. * embedded nulls.
  51. * <li>Only the 1-byte, 2-byte, and 3-byte formats are used.
  52. * </ul>
  53. *
  54. * @author Arthur van Hoff
  55. * @version 1.51, 02/28/00
  56. * @see java.io.DataOutputStream
  57. * @since JDK1.0
  58. */
  59. public
  60. class DataInputStream extends FilterInputStream implements DataInput {
  61. /**
  62. * Creates a <code>FilterInputStream</code>
  63. * and saves its argument, the input stream
  64. * <code>in</code>, for later use. An internal
  65. *
  66. * @param in the input stream.
  67. */
  68. public DataInputStream(InputStream in) {
  69. super(in);
  70. }
  71. /**
  72. * See the general contract of the <code>read</code>
  73. * method of <code>DataInput</code>.
  74. * <p>
  75. * Bytes
  76. * for this operation are read from the contained
  77. * input stream.
  78. *
  79. * @param b the buffer into which the data is read.
  80. * @return the total number of bytes read into the buffer, or
  81. * <code>-1</code> if there is no more data because the end
  82. * of the stream has been reached.
  83. * @exception IOException if an I/O error occurs.
  84. * @see java.io.FilterInputStream#in
  85. * @see java.io.InputStream#read(byte[], int, int)
  86. */
  87. public final int read(byte b[]) throws IOException {
  88. return in.read(b, 0, b.length);
  89. }
  90. /**
  91. * See the general contract of the <code>read</code>
  92. * method of <code>DataInput</code>.
  93. * <p>
  94. * Bytes
  95. * for this operation are read from the contained
  96. * input stream.
  97. *
  98. * @param b the buffer into which the data is read.
  99. * @param off the start offset of the data.
  100. * @param len the maximum number of bytes read.
  101. * @return the total number of bytes read into the buffer, or
  102. * <code>-1</code> if there is no more data because the end
  103. * of the stream has been reached.
  104. * @exception IOException if an I/O error occurs.
  105. * @see java.io.FilterInputStream#in
  106. * @see java.io.InputStream#read(byte[], int, int)
  107. */
  108. public final int read(byte b[], int off, int len) throws IOException {
  109. return in.read(b, off, len);
  110. }
  111. /**
  112. * See the general contract of the <code>readFully</code>
  113. * method of <code>DataInput</code>.
  114. * <p>
  115. * Bytes
  116. * for this operation are read from the contained
  117. * input stream.
  118. *
  119. * @param b the buffer into which the data is read.
  120. * @exception EOFException if this input stream reaches the end before
  121. * reading all the bytes.
  122. * @exception IOException if an I/O error occurs.
  123. * @see java.io.FilterInputStream#in
  124. */
  125. public final void readFully(byte b[]) throws IOException {
  126. readFully(b, 0, b.length);
  127. }
  128. /**
  129. * See the general contract of the <code>readFully</code>
  130. * method of <code>DataInput</code>.
  131. * <p>
  132. * Bytes
  133. * for this operation are read from the contained
  134. * input stream.
  135. *
  136. * @param b the buffer into which the data is read.
  137. * @param off the start offset of the data.
  138. * @param len the number of bytes to 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[], int off, int len) throws IOException {
  145. if (len < 0)
  146. throw new IndexOutOfBoundsException();
  147. InputStream in = this.in;
  148. int n = 0;
  149. while (n < len) {
  150. int count = in.read(b, off + n, len - n);
  151. if (count < 0)
  152. throw new EOFException();
  153. n += count;
  154. }
  155. }
  156. /**
  157. * See the general contract of the <code>skipBytes</code>
  158. * method of <code>DataInput</code>.
  159. * <p>
  160. * Bytes
  161. * for this operation are read from the contained
  162. * input stream.
  163. *
  164. * @param n the number of bytes to be skipped.
  165. * @return the actual number of bytes skipped.
  166. * @exception IOException if an I/O error occurs.
  167. */
  168. public final int skipBytes(int n) throws IOException {
  169. InputStream in = this.in;
  170. int total = 0;
  171. int cur = 0;
  172. while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {
  173. total += cur;
  174. }
  175. return total;
  176. }
  177. /**
  178. * See the general contract of the <code>readBoolean</code>
  179. * method of <code>DataInput</code>.
  180. * <p>
  181. * Bytes
  182. * for this operation are read from the contained
  183. * input stream.
  184. *
  185. * @return the <code>boolean</code> value read.
  186. * @exception EOFException if this input stream has reached the end.
  187. * @exception IOException if an I/O error occurs.
  188. * @see java.io.FilterInputStream#in
  189. */
  190. public final boolean readBoolean() throws IOException {
  191. int ch = in.read();
  192. if (ch < 0)
  193. throw new EOFException();
  194. return (ch != 0);
  195. }
  196. /**
  197. * See the general contract of the <code>readByte</code>
  198. * method of <code>DataInput</code>.
  199. * <p>
  200. * Bytes
  201. * for this operation are read from the contained
  202. * input stream.
  203. *
  204. * @return the next byte of this input stream as a signed 8-bit
  205. * <code>byte</code>.
  206. * @exception EOFException if this input stream has reached the end.
  207. * @exception IOException if an I/O error occurs.
  208. * @see java.io.FilterInputStream#in
  209. */
  210. public final byte readByte() throws IOException {
  211. int ch = in.read();
  212. if (ch < 0)
  213. throw new EOFException();
  214. return (byte)(ch);
  215. }
  216. /**
  217. * See the general contract of the <code>readUnsignedByte</code>
  218. * method of <code>DataInput</code>.
  219. * <p>
  220. * Bytes
  221. * for this operation are read from the contained
  222. * input stream.
  223. *
  224. * @return the next byte of this input stream, interpreted as an
  225. * unsigned 8-bit number.
  226. * @exception EOFException if this input stream has reached the end.
  227. * @exception IOException if an I/O error occurs.
  228. * @see java.io.FilterInputStream#in
  229. */
  230. public final int readUnsignedByte() throws IOException {
  231. int ch = in.read();
  232. if (ch < 0)
  233. throw new EOFException();
  234. return ch;
  235. }
  236. /**
  237. * See the general contract of the <code>readShort</code>
  238. * method of <code>DataInput</code>.
  239. * <p>
  240. * Bytes
  241. * for this operation are read from the contained
  242. * input stream.
  243. *
  244. * @return the next two bytes of this input stream, interpreted as a
  245. * signed 16-bit number.
  246. * @exception EOFException if this input stream reaches the end before
  247. * reading two bytes.
  248. * @exception IOException if an I/O error occurs.
  249. * @see java.io.FilterInputStream#in
  250. */
  251. public final short readShort() throws IOException {
  252. InputStream in = this.in;
  253. int ch1 = in.read();
  254. int ch2 = in.read();
  255. if ((ch1 | ch2) < 0)
  256. throw new EOFException();
  257. return (short)((ch1 << 8) + (ch2 << 0));
  258. }
  259. /**
  260. * See the general contract of the <code>readUnsignedShort</code>
  261. * method of <code>DataInput</code>.
  262. * <p>
  263. * Bytes
  264. * for this operation are read from the contained
  265. * input stream.
  266. *
  267. * @return the next two bytes of this input stream, interpreted as an
  268. * unsigned 16-bit integer.
  269. * @exception EOFException if this input stream reaches the end before
  270. * reading two bytes.
  271. * @exception IOException if an I/O error occurs.
  272. * @see java.io.FilterInputStream#in
  273. */
  274. public final int readUnsignedShort() throws IOException {
  275. InputStream in = this.in;
  276. int ch1 = in.read();
  277. int ch2 = in.read();
  278. if ((ch1 | ch2) < 0)
  279. throw new EOFException();
  280. return (ch1 << 8) + (ch2 << 0);
  281. }
  282. /**
  283. * See the general contract of the <code>readChar</code>
  284. * method of <code>DataInput</code>.
  285. * <p>
  286. * Bytes
  287. * for this operation are read from the contained
  288. * input stream.
  289. *
  290. * @return the next two bytes of this input stream as a Unicode
  291. * character.
  292. * @exception EOFException if this input stream reaches the end before
  293. * reading two bytes.
  294. * @exception IOException if an I/O error occurs.
  295. * @see java.io.FilterInputStream#in
  296. */
  297. public final char readChar() throws IOException {
  298. InputStream in = this.in;
  299. int ch1 = in.read();
  300. int ch2 = in.read();
  301. if ((ch1 | ch2) < 0)
  302. throw new EOFException();
  303. return (char)((ch1 << 8) + (ch2 << 0));
  304. }
  305. /**
  306. * See the general contract of the <code>readInt</code>
  307. * method of <code>DataInput</code>.
  308. * <p>
  309. * Bytes
  310. * for this operation are read from the contained
  311. * input stream.
  312. *
  313. * @return the next four bytes of this input stream, interpreted as an
  314. * <code>int</code>.
  315. * @exception EOFException if this input stream reaches the end before
  316. * reading four bytes.
  317. * @exception IOException if an I/O error occurs.
  318. * @see java.io.FilterInputStream#in
  319. */
  320. public final int readInt() throws IOException {
  321. InputStream in = this.in;
  322. int ch1 = in.read();
  323. int ch2 = in.read();
  324. int ch3 = in.read();
  325. int ch4 = in.read();
  326. if ((ch1 | ch2 | ch3 | ch4) < 0)
  327. throw new EOFException();
  328. return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
  329. }
  330. /**
  331. * See the general contract of the <code>readLong</code>
  332. * method of <code>DataInput</code>.
  333. * <p>
  334. * Bytes
  335. * for this operation are read from the contained
  336. * input stream.
  337. *
  338. * @return the next eight bytes of this input stream, interpreted as a
  339. * <code>long</code>.
  340. * @exception EOFException if this input stream reaches the end before
  341. * reading eight bytes.
  342. * @exception IOException if an I/O error occurs.
  343. * @see java.io.FilterInputStream#in
  344. */
  345. public final long readLong() throws IOException {
  346. InputStream in = this.in;
  347. return ((long)(readInt()) << 32) + (readInt() & 0xFFFFFFFFL);
  348. }
  349. /**
  350. * See the general contract of the <code>readFloat</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 four bytes of this input stream, interpreted as a
  358. * <code>float</code>.
  359. * @exception EOFException if this input stream reaches the end before
  360. * reading four bytes.
  361. * @exception IOException if an I/O error occurs.
  362. * @see java.io.DataInputStream#readInt()
  363. * @see java.lang.Float#intBitsToFloat(int)
  364. */
  365. public final float readFloat() throws IOException {
  366. return Float.intBitsToFloat(readInt());
  367. }
  368. /**
  369. * See the general contract of the <code>readDouble</code>
  370. * method of <code>DataInput</code>.
  371. * <p>
  372. * Bytes
  373. * for this operation are read from the contained
  374. * input stream.
  375. *
  376. * @return the next eight bytes of this input stream, interpreted as a
  377. * <code>double</code>.
  378. * @exception EOFException if this input stream reaches the end before
  379. * reading eight bytes.
  380. * @exception IOException if an I/O error occurs.
  381. * @see java.io.DataInputStream#readLong()
  382. * @see java.lang.Double#longBitsToDouble(long)
  383. */
  384. public final double readDouble() throws IOException {
  385. return Double.longBitsToDouble(readLong());
  386. }
  387. private char lineBuffer[];
  388. /**
  389. * See the general contract of the <code>readLine</code>
  390. * method of <code>DataInput</code>.
  391. * <p>
  392. * Bytes
  393. * for this operation are read from the contained
  394. * input stream.
  395. *
  396. * @deprecated This method does not properly convert bytes to characters.
  397. * As of JDK 1.1, the preferred way to read lines of text is via the
  398. * <code>BufferedReader.readLine()</code> method. Programs that use the
  399. * <code>DataInputStream</code> class to read lines can be converted to use
  400. * the <code>BufferedReader</code> class by replacing code of the form:
  401. * <blockquote><pre>
  402. * DataInputStream d = new DataInputStream(in);
  403. * </pre></blockquote>
  404. * with:
  405. * <blockquote><pre>
  406. * BufferedReader d
  407. * = new BufferedReader(new InputStreamReader(in));
  408. * </pre></blockquote>
  409. *
  410. * @return the next line of text from this input stream.
  411. * @exception IOException if an I/O error occurs.
  412. * @see java.io.BufferedReader#readLine()
  413. * @see java.io.FilterInputStream#in
  414. */
  415. public final String readLine() throws IOException {
  416. InputStream in = this.in;
  417. char buf[] = lineBuffer;
  418. if (buf == null) {
  419. buf = lineBuffer = new char[128];
  420. }
  421. int room = buf.length;
  422. int offset = 0;
  423. int c;
  424. loop: while (true) {
  425. switch (c = in.read()) {
  426. case -1:
  427. case '\n':
  428. break loop;
  429. case '\r':
  430. int c2 = in.read();
  431. if ((c2 != '\n') && (c2 != -1)) {
  432. if (!(in instanceof PushbackInputStream)) {
  433. in = this.in = new PushbackInputStream(in);
  434. }
  435. ((PushbackInputStream)in).unread(c2);
  436. }
  437. break loop;
  438. default:
  439. if (--room < 0) {
  440. buf = new char[offset + 128];
  441. room = buf.length - offset - 1;
  442. System.arraycopy(lineBuffer, 0, buf, 0, offset);
  443. lineBuffer = buf;
  444. }
  445. buf[offset++] = (char) c;
  446. break;
  447. }
  448. }
  449. if ((c == -1) && (offset == 0)) {
  450. return null;
  451. }
  452. return String.copyValueOf(buf, 0, offset);
  453. }
  454. /**
  455. * See the general contract of the <code>readUTF</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 a Unicode string.
  463. * @exception EOFException if this input stream reaches the end before
  464. * reading all the bytes.
  465. * @exception IOException if an I/O error occurs.
  466. * @see java.io.DataInputStream#readUTF(java.io.DataInput)
  467. */
  468. public final String readUTF() throws IOException {
  469. return readUTF(this);
  470. }
  471. /**
  472. * Reads from the
  473. * stream <code>in</code> a representation
  474. * of a Unicode character string encoded in
  475. * Java modified UTF-8 format; this string
  476. * of characters is then returned as a <code>String</code>.
  477. * The details of the modified UTF-8 representation
  478. * are exactly the same as for the <code>readUTF</code>
  479. * method of <code>DataInput</code>.
  480. *
  481. * @param in a data input stream.
  482. * @return a Unicode string.
  483. * @exception EOFException if the input stream reaches the end
  484. * before all the bytes.
  485. * @exception IOException if an I/O error occurs.
  486. * @exception UTFDataFormatException if the bytes do not represent a
  487. * valid UTF-8 encoding of a Unicode string.
  488. * @see java.io.DataInputStream#readUnsignedShort()
  489. */
  490. public final static String readUTF(DataInput in) throws IOException {
  491. int utflen = in.readUnsignedShort();
  492. char str[] = new char[utflen];
  493. byte bytearr [] = new byte[utflen];
  494. int c, char2, char3;
  495. int count = 0;
  496. int strlen = 0;
  497. in.readFully(bytearr, 0, utflen);
  498. while (count < utflen) {
  499. c = (int) bytearr[count] & 0xff;
  500. switch (c >> 4) {
  501. case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
  502. /* 0xxxxxxx*/
  503. count++;
  504. str[strlen++] = (char)c;
  505. break;
  506. case 12: case 13:
  507. /* 110x xxxx 10xx xxxx*/
  508. count += 2;
  509. if (count > utflen)
  510. throw new UTFDataFormatException();
  511. char2 = (int) bytearr[count-1];
  512. if ((char2 & 0xC0) != 0x80)
  513. throw new UTFDataFormatException();
  514. str[strlen++] = (char)(((c & 0x1F) << 6) | (char2 & 0x3F));
  515. break;
  516. case 14:
  517. /* 1110 xxxx 10xx xxxx 10xx xxxx */
  518. count += 3;
  519. if (count > utflen)
  520. throw new UTFDataFormatException();
  521. char2 = (int) bytearr[count-2];
  522. char3 = (int) bytearr[count-1];
  523. if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
  524. throw new UTFDataFormatException();
  525. str[strlen++] = (char)(((c & 0x0F) << 12) |
  526. ((char2 & 0x3F) << 6) |
  527. ((char3 & 0x3F) << 0));
  528. break;
  529. default:
  530. /* 10xx xxxx, 1111 xxxx */
  531. throw new UTFDataFormatException();
  532. }
  533. }
  534. // The number of chars produced may be less than utflen
  535. return new String(str, 0, strlen);
  536. }
  537. }