1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dialer.callcomposer.camera.exif; 18 19 import com.android.dialer.common.Assert; 20 import java.io.EOFException; 21 import java.io.FilterInputStream; 22 import java.io.IOException; 23 import java.io.InputStream; 24 import java.nio.ByteBuffer; 25 import java.nio.ByteOrder; 26 import java.nio.charset.Charset; 27 28 class CountedDataInputStream extends FilterInputStream { 29 30 private int mCount = 0; 31 32 // allocate a byte buffer for a long value; 33 private final byte[] mByteArray = new byte[8]; 34 private final ByteBuffer mByteBuffer = ByteBuffer.wrap(mByteArray); 35 CountedDataInputStream(InputStream in)36 CountedDataInputStream(InputStream in) { 37 super(in); 38 } 39 getReadByteCount()40 int getReadByteCount() { 41 return mCount; 42 } 43 44 @Override read(byte[] b)45 public int read(byte[] b) throws IOException { 46 int r = in.read(b); 47 mCount += (r >= 0) ? r : 0; 48 return r; 49 } 50 51 @Override read(byte[] b, int off, int len)52 public int read(byte[] b, int off, int len) throws IOException { 53 int r = in.read(b, off, len); 54 mCount += (r >= 0) ? r : 0; 55 return r; 56 } 57 58 @Override read()59 public int read() throws IOException { 60 int r = in.read(); 61 mCount += (r >= 0) ? 1 : 0; 62 return r; 63 } 64 65 @Override skip(long length)66 public long skip(long length) throws IOException { 67 long skip = in.skip(length); 68 mCount += skip; 69 return skip; 70 } 71 skipOrThrow(long length)72 private void skipOrThrow(long length) throws IOException { 73 if (skip(length) != length) { 74 throw new EOFException(); 75 } 76 } 77 skipTo(long target)78 void skipTo(long target) throws IOException { 79 long cur = mCount; 80 long diff = target - cur; 81 Assert.checkArgument(diff >= 0); 82 skipOrThrow(diff); 83 } 84 readOrThrow(byte[] b, int off, int len)85 private void readOrThrow(byte[] b, int off, int len) throws IOException { 86 int r = read(b, off, len); 87 if (r != len) { 88 throw new EOFException(); 89 } 90 } 91 readOrThrow(byte[] b)92 private void readOrThrow(byte[] b) throws IOException { 93 readOrThrow(b, 0, b.length); 94 } 95 setByteOrder(ByteOrder order)96 void setByteOrder(ByteOrder order) { 97 mByteBuffer.order(order); 98 } 99 getByteOrder()100 ByteOrder getByteOrder() { 101 return mByteBuffer.order(); 102 } 103 readShort()104 short readShort() throws IOException { 105 readOrThrow(mByteArray, 0, 2); 106 mByteBuffer.rewind(); 107 return mByteBuffer.getShort(); 108 } 109 readUnsignedShort()110 int readUnsignedShort() throws IOException { 111 return readShort() & 0xffff; 112 } 113 readInt()114 int readInt() throws IOException { 115 readOrThrow(mByteArray, 0, 4); 116 mByteBuffer.rewind(); 117 return mByteBuffer.getInt(); 118 } 119 readUnsignedInt()120 long readUnsignedInt() throws IOException { 121 return readInt() & 0xffffffffL; 122 } 123 readString(int n, Charset charset)124 String readString(int n, Charset charset) throws IOException { 125 byte[] buf = new byte[n]; 126 readOrThrow(buf); 127 return new String(buf, charset); 128 } 129 } 130