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