1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 /** 18 * @author Rustem V. Rafikov 19 * @version $Revision: 1.3 $ 20 */ 21 22 package javax.imageio.stream; 23 24 import java.io.EOFException; 25 import java.io.IOException; 26 import java.nio.ByteOrder; 27 28 /** 29 * The ImageInputStreamImpl abstract class implements the ImageInputStream 30 * interface. 31 * 32 * @since Android 1.0 33 */ 34 public abstract class ImageInputStreamImpl implements ImageInputStream { 35 36 /** 37 * The byte order. 38 */ 39 protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN; 40 41 /** 42 * The stream position. 43 */ 44 protected long streamPos = 0; 45 46 /** 47 * The flushed position. 48 */ 49 protected long flushedPos = 0; 50 51 /** 52 * The bit offset. 53 */ 54 protected int bitOffset = 0; 55 56 /** 57 * The closed. 58 */ 59 private boolean closed = false; 60 61 /** 62 * The position stack. 63 */ 64 private final PositionStack posStack = new PositionStack(); 65 66 /** 67 * Instantiates a new ImageInputStreamImpl. 68 */ ImageInputStreamImpl()69 public ImageInputStreamImpl() { 70 } 71 72 /** 73 * Check if the stream is closed and if true, throws an IOException. 74 * 75 * @throws IOException 76 * if the stream is closed. 77 */ checkClosed()78 protected final void checkClosed() throws IOException { 79 if (closed) { 80 throw new IOException("stream is closed"); 81 } 82 } 83 setByteOrder(ByteOrder byteOrder)84 public void setByteOrder(ByteOrder byteOrder) { 85 this.byteOrder = byteOrder; 86 } 87 getByteOrder()88 public ByteOrder getByteOrder() { 89 return byteOrder; 90 } 91 read()92 public abstract int read() throws IOException; 93 read(byte[] b)94 public int read(byte[] b) throws IOException { 95 return read(b, 0, b.length); 96 } 97 read(byte[] b, int off, int len)98 public abstract int read(byte[] b, int off, int len) throws IOException; 99 readBytes(IIOByteBuffer buf, int len)100 public void readBytes(IIOByteBuffer buf, int len) throws IOException { 101 if (buf == null) { 102 throw new NullPointerException("buffer is NULL"); 103 } 104 105 byte[] b = new byte[len]; 106 len = read(b, 0, b.length); 107 108 buf.setData(b); 109 buf.setOffset(0); 110 buf.setLength(len); 111 } 112 readBoolean()113 public boolean readBoolean() throws IOException { 114 int b = read(); 115 if (b < 0) { 116 throw new EOFException("EOF reached"); 117 } 118 return b != 0; 119 } 120 readByte()121 public byte readByte() throws IOException { 122 int b = read(); 123 if (b < 0) { 124 throw new EOFException("EOF reached"); 125 } 126 return (byte)b; 127 } 128 readUnsignedByte()129 public int readUnsignedByte() throws IOException { 130 int b = read(); 131 if (b < 0) { 132 throw new EOFException("EOF reached"); 133 } 134 return b; 135 } 136 readShort()137 public short readShort() throws IOException { 138 int b1 = read(); 139 int b2 = read(); 140 141 if (b1 < 0 || b2 < 0) { 142 throw new EOFException("EOF reached"); 143 } 144 145 return byteOrder == ByteOrder.BIG_ENDIAN ? (short)((b1 << 8) | (b2 & 0xff)) 146 : (short)((b2 << 8) | (b1 & 0xff)); 147 } 148 readUnsignedShort()149 public int readUnsignedShort() throws IOException { 150 // -- TODO implement 151 throw new UnsupportedOperationException("Not implemented yet"); 152 } 153 readChar()154 public char readChar() throws IOException { 155 // -- TODO implement 156 throw new UnsupportedOperationException("Not implemented yet"); 157 } 158 readInt()159 public int readInt() throws IOException { 160 // -- TODO implement 161 throw new UnsupportedOperationException("Not implemented yet"); 162 } 163 readUnsignedInt()164 public long readUnsignedInt() throws IOException { 165 // -- TODO implement 166 throw new UnsupportedOperationException("Not implemented yet"); 167 } 168 readLong()169 public long readLong() throws IOException { 170 // -- TODO implement 171 throw new UnsupportedOperationException("Not implemented yet"); 172 } 173 readFloat()174 public float readFloat() throws IOException { 175 // -- TODO implement 176 throw new UnsupportedOperationException("Not implemented yet"); 177 } 178 readDouble()179 public double readDouble() throws IOException { 180 // -- TODO implement 181 throw new UnsupportedOperationException("Not implemented yet"); 182 } 183 readLine()184 public String readLine() throws IOException { 185 // -- TODO implement 186 throw new UnsupportedOperationException("Not implemented yet"); 187 } 188 readUTF()189 public String readUTF() throws IOException { 190 // -- TODO implement 191 throw new UnsupportedOperationException("Not implemented yet"); 192 } 193 readFully(byte[] b, int off, int len)194 public void readFully(byte[] b, int off, int len) throws IOException { 195 // -- TODO implement 196 throw new UnsupportedOperationException("Not implemented yet"); 197 } 198 readFully(byte[] b)199 public void readFully(byte[] b) throws IOException { 200 readFully(b, 0, b.length); 201 } 202 readFully(short[] s, int off, int len)203 public void readFully(short[] s, int off, int len) throws IOException { 204 // -- TODO implement 205 throw new UnsupportedOperationException("Not implemented yet"); 206 } 207 readFully(char[] c, int off, int len)208 public void readFully(char[] c, int off, int len) throws IOException { 209 // -- TODO implement 210 throw new UnsupportedOperationException("Not implemented yet"); 211 } 212 readFully(int[] i, int off, int len)213 public void readFully(int[] i, int off, int len) throws IOException { 214 // -- TODO implement 215 throw new UnsupportedOperationException("Not implemented yet"); 216 } 217 readFully(long[] l, int off, int len)218 public void readFully(long[] l, int off, int len) throws IOException { 219 // -- TODO implement 220 throw new UnsupportedOperationException("Not implemented yet"); 221 } 222 readFully(float[] f, int off, int len)223 public void readFully(float[] f, int off, int len) throws IOException { 224 // -- TODO implement 225 throw new UnsupportedOperationException("Not implemented yet"); 226 } 227 readFully(double[] d, int off, int len)228 public void readFully(double[] d, int off, int len) throws IOException { 229 // -- TODO implement 230 throw new UnsupportedOperationException("Not implemented yet"); 231 } 232 getStreamPosition()233 public long getStreamPosition() throws IOException { 234 checkClosed(); 235 return streamPos; 236 } 237 getBitOffset()238 public int getBitOffset() throws IOException { 239 checkClosed(); 240 return bitOffset; 241 } 242 setBitOffset(int bitOffset)243 public void setBitOffset(int bitOffset) throws IOException { 244 checkClosed(); 245 this.bitOffset = bitOffset; 246 } 247 readBit()248 public int readBit() throws IOException { 249 // -- TODO implement 250 throw new UnsupportedOperationException("Not implemented yet"); 251 } 252 readBits(int numBits)253 public long readBits(int numBits) throws IOException { 254 // -- TODO implement 255 throw new UnsupportedOperationException("Not implemented yet"); 256 } 257 length()258 public long length() { 259 return -1L; 260 } 261 skipBytes(int n)262 public int skipBytes(int n) throws IOException { 263 // -- TODO implement 264 throw new UnsupportedOperationException("Not implemented yet"); 265 } 266 skipBytes(long n)267 public long skipBytes(long n) throws IOException { 268 // -- TODO implement 269 throw new UnsupportedOperationException("Not implemented yet"); 270 } 271 seek(long pos)272 public void seek(long pos) throws IOException { 273 checkClosed(); 274 if (pos < getFlushedPosition()) { 275 throw new IllegalArgumentException("trying to seek before flushed pos"); 276 } 277 bitOffset = 0; 278 streamPos = pos; 279 } 280 mark()281 public void mark() { 282 try { 283 posStack.push(getStreamPosition()); 284 } catch (IOException e) { 285 e.printStackTrace(); 286 throw new RuntimeException("Stream marking error"); 287 } 288 } 289 reset()290 public void reset() throws IOException { 291 // -- TODO bit pos 292 if (!posStack.isEmpty()) { 293 long p = posStack.pop(); 294 if (p < flushedPos) { 295 throw new IOException("marked position lies in the flushed portion of the stream"); 296 } 297 seek(p); 298 } 299 } 300 flushBefore(long pos)301 public void flushBefore(long pos) throws IOException { 302 if (pos > getStreamPosition()) { 303 throw new IndexOutOfBoundsException("Trying to flush outside of current position"); 304 } 305 if (pos < flushedPos) { 306 throw new IndexOutOfBoundsException("Trying to flush within already flushed portion"); 307 } 308 flushedPos = pos; 309 // -- TODO implement 310 } 311 flush()312 public void flush() throws IOException { 313 flushBefore(getStreamPosition()); 314 } 315 getFlushedPosition()316 public long getFlushedPosition() { 317 return flushedPos; 318 } 319 isCached()320 public boolean isCached() { 321 return false; // def 322 } 323 isCachedMemory()324 public boolean isCachedMemory() { 325 return false; // def 326 } 327 isCachedFile()328 public boolean isCachedFile() { 329 return false; // def 330 } 331 close()332 public void close() throws IOException { 333 checkClosed(); 334 closed = true; 335 336 } 337 338 /** 339 * Finalizes this object. 340 * 341 * @throws Throwable 342 * if an error occurs. 343 */ 344 @Override finalize()345 protected void finalize() throws Throwable { 346 if (!closed) { 347 try { 348 close(); 349 } finally { 350 super.finalize(); 351 } 352 } 353 } 354 355 /** 356 * The Class PositionStack. 357 */ 358 private static class PositionStack { 359 360 /** 361 * The Constant SIZE. 362 */ 363 private static final int SIZE = 10; 364 365 /** 366 * The values. 367 */ 368 private long[] values = new long[SIZE]; 369 370 /** 371 * The pos. 372 */ 373 private int pos = 0; 374 375 /** 376 * Push. 377 * 378 * @param v 379 * the v. 380 */ push(long v)381 void push(long v) { 382 if (pos >= values.length) { 383 ensure(pos + 1); 384 } 385 values[pos++] = v; 386 } 387 388 /** 389 * Pop. 390 * 391 * @return the long. 392 */ pop()393 long pop() { 394 return values[--pos]; 395 } 396 397 /** 398 * Checks if is empty. 399 * 400 * @return true, if is empty. 401 */ isEmpty()402 boolean isEmpty() { 403 return pos == 0; 404 } 405 406 /** 407 * Ensure. 408 * 409 * @param size 410 * the size. 411 */ ensure(int size)412 private void ensure(int size) { 413 long[] arr = new long[Math.max(2 * values.length, size)]; 414 System.arraycopy(values, 0, arr, 0, values.length); 415 values = arr; 416 } 417 } 418 } 419