PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/javax/imageio/stream/ImageInputStreamImpl.java

https://github.com/penberg/classpath
Java | 542 lines | 399 code | 94 blank | 49 comment | 39 complexity | 204dc156ce648a9cbb63a4aa240a9aa6 MD5 | raw file
  1. /* ImageInputStream.java --
  2. Copyright (C) 2004 Free Software Foundation, Inc.
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. 02110-1301 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. package javax.imageio.stream;
  32. import gnu.java.lang.CPStringBuilder;
  33. import java.io.DataInputStream;
  34. import java.io.EOFException;
  35. import java.io.IOException;
  36. import java.nio.ByteOrder;
  37. import java.util.Stack;
  38. /**
  39. * @author Michael Koch (konqueror@gmx.de)
  40. */
  41. public abstract class ImageInputStreamImpl implements ImageInputStream
  42. {
  43. private boolean closed;
  44. private Stack markStack = new Stack();
  45. byte[] buffer = new byte[8];
  46. protected int bitOffset;
  47. protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
  48. protected long flushedPos;
  49. protected long streamPos;
  50. public ImageInputStreamImpl()
  51. {
  52. // Do nothing here.
  53. }
  54. protected final void checkClosed()
  55. throws IOException
  56. {
  57. if (closed)
  58. throw new IOException("stream closed");
  59. }
  60. public void close()
  61. throws IOException
  62. {
  63. checkClosed();
  64. closed = true;
  65. }
  66. protected void finalize()
  67. throws Throwable
  68. {
  69. if (!closed)
  70. close();
  71. }
  72. public void flush()
  73. throws IOException
  74. {
  75. flushBefore(getStreamPosition());
  76. }
  77. public void flushBefore(long position)
  78. throws IOException
  79. {
  80. if (position < flushedPos)
  81. throw new IndexOutOfBoundsException();
  82. if (position > streamPos)
  83. throw new IndexOutOfBoundsException();
  84. flushedPos = position;
  85. }
  86. public int getBitOffset()
  87. throws IOException
  88. {
  89. checkClosed();
  90. return bitOffset;
  91. }
  92. public ByteOrder getByteOrder()
  93. {
  94. return byteOrder;
  95. }
  96. public long getFlushedPosition()
  97. {
  98. return flushedPos;
  99. }
  100. public long getStreamPosition()
  101. throws IOException
  102. {
  103. checkClosed();
  104. return streamPos;
  105. }
  106. public boolean isCached()
  107. {
  108. return false;
  109. }
  110. public boolean isCachedFile()
  111. {
  112. return false;
  113. }
  114. public boolean isCachedMemory()
  115. {
  116. return false;
  117. }
  118. public long length()
  119. {
  120. return -1L;
  121. }
  122. public void mark()
  123. {
  124. try
  125. {
  126. markStack.push(new Long(getStreamPosition()));
  127. }
  128. catch (IOException e)
  129. {
  130. throw new RuntimeException(e);
  131. }
  132. }
  133. public abstract int read()
  134. throws IOException;
  135. public abstract int read(byte[] data, int offset, int len)
  136. throws IOException;
  137. public int read(byte[] data)
  138. throws IOException
  139. {
  140. return read(data, 0, data.length);
  141. }
  142. public int readBit()
  143. throws IOException
  144. {
  145. checkClosed();
  146. // Calculate new bit offset here as readByte clears it.
  147. int newOffset = (bitOffset + 1) & 0x7;
  148. // Clears bitOffset.
  149. byte data = readByte();
  150. // If newOffset is 0 it means we just read the 8th bit in a byte
  151. // and therefore we want to advance to the next byte. Otherwise
  152. // we want to roll back the stream one byte so that future readBit
  153. // calls read bits from the same current byte.
  154. if (newOffset != 0)
  155. {
  156. seek(getStreamPosition() - 1);
  157. data = (byte) (data >> (8 - newOffset));
  158. }
  159. bitOffset = newOffset;
  160. return data & 0x1;
  161. }
  162. public long readBits(int numBits)
  163. throws IOException
  164. {
  165. checkClosed();
  166. if (numBits < 0 || numBits > 64)
  167. throw new IllegalArgumentException();
  168. long bits = 0L;
  169. for (int i = 0; i < numBits; i++)
  170. {
  171. bits <<= 1;
  172. bits |= readBit();
  173. }
  174. return bits;
  175. }
  176. public boolean readBoolean()
  177. throws IOException
  178. {
  179. byte data = readByte();
  180. return data != 0;
  181. }
  182. public byte readByte()
  183. throws IOException
  184. {
  185. checkClosed();
  186. int data = read();
  187. if (data == -1)
  188. throw new EOFException();
  189. return (byte) data;
  190. }
  191. public void readBytes(IIOByteBuffer buffer, int len)
  192. throws IOException
  193. {
  194. readFullyPrivate(buffer.getData(), buffer.getOffset(), len);
  195. buffer.setLength(len);
  196. }
  197. public char readChar()
  198. throws IOException
  199. {
  200. return (char) readShort();
  201. }
  202. public double readDouble()
  203. throws IOException
  204. {
  205. return Double.longBitsToDouble(readLong());
  206. }
  207. public float readFloat()
  208. throws IOException
  209. {
  210. return Float.intBitsToFloat(readInt());
  211. }
  212. public void readFully(byte[] data)
  213. throws IOException
  214. {
  215. readFully(data, 0, data.length);
  216. }
  217. public void readFully(byte[] data, int offset, int len)
  218. throws IOException
  219. {
  220. readFullyPrivate(data, offset, len);
  221. }
  222. public void readFully(char[] data, int offset, int len)
  223. throws IOException
  224. {
  225. for (int i = 0; i < len; ++i)
  226. data[offset + i] = readChar();
  227. }
  228. public void readFully(double[] data, int offset, int len)
  229. throws IOException
  230. {
  231. for (int i = 0; i < len; ++i)
  232. data[offset + i] = readDouble();
  233. }
  234. public void readFully(float[] data, int offset, int len)
  235. throws IOException
  236. {
  237. for (int i = 0; i < len; ++i)
  238. data[offset + i] = readFloat();
  239. }
  240. public void readFully(int[] data, int offset, int len)
  241. throws IOException
  242. {
  243. for (int i = 0; i < len; ++i)
  244. data[offset + i] = readInt();
  245. }
  246. public void readFully(long[] data, int offset, int len)
  247. throws IOException
  248. {
  249. for (int i = 0; i < len; ++i)
  250. data[offset + i] = readLong();
  251. }
  252. public void readFully(short[] data, int offset, int len)
  253. throws IOException
  254. {
  255. for (int i = 0; i < len; ++i)
  256. data[offset + i] = readShort();
  257. }
  258. public int readInt()
  259. throws IOException
  260. {
  261. readFullyPrivate(buffer, 0, 4);
  262. if (getByteOrder() == ByteOrder.LITTLE_ENDIAN)
  263. return (int)
  264. (((int) (buffer[0] & 0xff) << 0)
  265. | ((int) (buffer[1] & 0xff) << 8)
  266. | ((int) (buffer[2] & 0xff) << 16)
  267. | ((int) (buffer[3] & 0xff) << 24));
  268. return (int)
  269. (((int) (buffer[0] & 0xff) << 24)
  270. + ((int) (buffer[1] & 0xff) << 16)
  271. + ((int) (buffer[2] & 0xff) << 8)
  272. + ((int) (buffer[3] & 0xff) << 0));
  273. }
  274. public String readLine()
  275. throws IOException
  276. {
  277. checkClosed();
  278. int c = -1;
  279. boolean eol = false;
  280. CPStringBuilder buffer = new CPStringBuilder();
  281. c = read();
  282. if (c == -1)
  283. return null;
  284. while (!eol)
  285. {
  286. switch(c)
  287. {
  288. case '\r':
  289. // Check for following '\n'.
  290. long oldPosition = getStreamPosition();
  291. c = read();
  292. if (c == -1 || c == '\n')
  293. eol = true;
  294. else
  295. {
  296. seek(oldPosition);
  297. eol = true;
  298. }
  299. continue;
  300. case '\n':
  301. eol = true;
  302. continue;
  303. default:
  304. buffer.append((char) c);
  305. break;
  306. }
  307. c = read();
  308. if (c == -1)
  309. eol = true;
  310. }
  311. return buffer.toString();
  312. }
  313. public long readLong()
  314. throws IOException
  315. {
  316. readFullyPrivate(buffer, 0, 8);
  317. if (getByteOrder() == ByteOrder.LITTLE_ENDIAN)
  318. return (long)
  319. (((long) (buffer[0] & 0xff) << 0)
  320. | ((long) (buffer[1] & 0xff) << 8)
  321. | ((long) (buffer[2] & 0xff) << 16)
  322. | ((long) (buffer[3] & 0xff) << 24)
  323. | ((long) (buffer[4] & 0xff) << 32)
  324. | ((long) (buffer[5] & 0xff) << 40)
  325. | ((long) (buffer[6] & 0xff) << 48)
  326. | ((long) (buffer[7] & 0xff) << 56));
  327. return (long)
  328. (((long) (buffer[0] & 0xff) << 56)
  329. | ((long) (buffer[1] & 0xff) << 48)
  330. | ((long) (buffer[2] & 0xff) << 40)
  331. | ((long) (buffer[3] & 0xff) << 32)
  332. | ((long) (buffer[4] & 0xff) << 24)
  333. | ((long) (buffer[5] & 0xff) << 16)
  334. | ((long) (buffer[6] & 0xff) << 8)
  335. | ((long) (buffer[7] & 0xff) << 0));
  336. }
  337. public short readShort()
  338. throws IOException
  339. {
  340. readFullyPrivate(buffer, 0, 2);
  341. if (getByteOrder() == ByteOrder.LITTLE_ENDIAN)
  342. return (short)
  343. (((short) (buffer[0] & 0xff) << 0)
  344. | ((short) (buffer[1] & 0xff) << 8));
  345. return (short)
  346. (((short) (buffer[0] & 0xff) << 8)
  347. | ((short) (buffer[1] & 0xff) << 0));
  348. }
  349. public int readUnsignedByte()
  350. throws IOException
  351. {
  352. return (int) readByte() & 0xff;
  353. }
  354. public long readUnsignedInt()
  355. throws IOException
  356. {
  357. return (long) readInt() & 0xffffffffL;
  358. }
  359. public int readUnsignedShort()
  360. throws IOException
  361. {
  362. return (int) readShort() & 0xffff;
  363. }
  364. public String readUTF()
  365. throws IOException
  366. {
  367. checkClosed();
  368. String data;
  369. ByteOrder old = getByteOrder();
  370. // Strings are always big endian.
  371. setByteOrder(ByteOrder.BIG_ENDIAN);
  372. try
  373. {
  374. data = DataInputStream.readUTF(this);
  375. }
  376. finally
  377. {
  378. setByteOrder(old);
  379. }
  380. return data;
  381. }
  382. public void reset()
  383. throws IOException
  384. {
  385. checkClosed();
  386. long mark = ((Long) markStack.pop()).longValue();
  387. seek(mark);
  388. }
  389. public void seek(long position)
  390. throws IOException
  391. {
  392. checkClosed();
  393. if (position < getFlushedPosition())
  394. throw new IndexOutOfBoundsException("position < flushed position");
  395. streamPos = position;
  396. bitOffset = 0;
  397. }
  398. public void setBitOffset (int bitOffset)
  399. throws IOException
  400. {
  401. checkClosed();
  402. if (bitOffset < 0 || bitOffset > 7)
  403. throw new IllegalArgumentException("bitOffset not between 0 and 7 inclusive");
  404. this.bitOffset = bitOffset;
  405. }
  406. public void setByteOrder(ByteOrder byteOrder)
  407. {
  408. this.byteOrder = byteOrder;
  409. }
  410. public int skipBytes(int num)
  411. throws IOException
  412. {
  413. checkClosed();
  414. seek(getStreamPosition() + num);
  415. bitOffset = 0;
  416. return num;
  417. }
  418. public long skipBytes(long num)
  419. throws IOException
  420. {
  421. checkClosed();
  422. seek(getStreamPosition() + num);
  423. bitOffset = 0;
  424. return num;
  425. }
  426. private void readFullyPrivate (byte[] buf, int offset, int len) throws IOException
  427. {
  428. checkClosed();
  429. if (len < 0)
  430. throw new IndexOutOfBoundsException("Negative length: " + len);
  431. while (len > 0)
  432. {
  433. // read will block until some data is available.
  434. int numread = read (buf, offset, len);
  435. if (numread < 0)
  436. throw new EOFException ();
  437. len -= numread;
  438. offset += numread;
  439. }
  440. bitOffset = 0;
  441. }
  442. }