12523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan/*
22523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Copyright (C) 2012 The Android Open Source Project
32523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan *
42523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Licensed under the Apache License, Version 2.0 (the "License");
52523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * you may not use this file except in compliance with the License.
62523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * You may obtain a copy of the License at
72523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan *
82523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan *      http://www.apache.org/licenses/LICENSE-2.0
92523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan *
102523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Unless required by applicable law or agreed to in writing, software
112523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * distributed under the License is distributed on an "AS IS" BASIS,
122523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * See the License for the specific language governing permissions and
142523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * limitations under the License.
152523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */
162523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
17a16e7b50f3148f581439509279f242092e254309ztenghuipackage com.android.camera.exif;
182523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
192523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.io.EOFException;
202523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.io.FilterInputStream;
212523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.io.IOException;
222523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.io.InputStream;
232523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.nio.ByteBuffer;
242523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.nio.ByteOrder;
252523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.nio.charset.Charset;
262523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
272523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanclass CountedDataInputStream extends FilterInputStream {
282523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
292523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    private int mCount = 0;
302523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
312523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    // allocate a byte buffer for a long value;
322523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    private final byte mByteArray[] = new byte[8];
332523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    private final ByteBuffer mByteBuffer = ByteBuffer.wrap(mByteArray);
342523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
352523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    protected CountedDataInputStream(InputStream in) {
362523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        super(in);
372523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
382523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
392523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public int getReadByteCount() {
402523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return mCount;
412523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
422523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
432523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    @Override
442523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public int read(byte[] b) throws IOException {
452523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        int r = in.read(b);
462523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        mCount += (r >= 0) ? r : 0;
472523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return r;
482523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
492523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
502523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    @Override
512523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public int read(byte[] b, int off, int len) throws IOException {
522523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        int r = in.read(b, off, len);
532523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        mCount += (r >= 0) ? r : 0;
542523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return r;
552523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
562523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
572523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    @Override
582523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public int read() throws IOException {
592523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        int r = in.read();
602523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        mCount += (r >= 0) ? 1 : 0;
612523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return r;
622523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
632523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
642523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    @Override
652523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public long skip(long length) throws IOException {
662523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        long skip = in.skip(length);
672523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        mCount += skip;
682523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return skip;
692523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
702523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
712523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public void skipOrThrow(long length) throws IOException {
722523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        if (skip(length) != length) throw new EOFException();
732523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
742523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
752523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public void skipTo(long target) throws IOException {
762523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        long cur = mCount;
772523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        long diff = target - cur;
782523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        assert(diff >= 0);
792523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        skipOrThrow(diff);
802523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
812523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
822523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public void readOrThrow(byte[] b, int off, int len) throws IOException {
832523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        int r = read(b, off, len);
842523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        if (r != len) throw new EOFException();
852523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
862523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
872523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public void readOrThrow(byte[] b) throws IOException {
882523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        readOrThrow(b, 0, b.length);
892523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
902523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
912523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public void setByteOrder(ByteOrder order) {
922523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        mByteBuffer.order(order);
932523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
942523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
952523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public ByteOrder getByteOrder() {
962523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return mByteBuffer.order();
972523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
982523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
992523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public short readShort() throws IOException {
1002523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        readOrThrow(mByteArray, 0 ,2);
1012523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        mByteBuffer.rewind();
1022523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return mByteBuffer.getShort();
1032523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1042523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
1052523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public int readUnsignedShort() throws IOException {
1062523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return readShort() & 0xffff;
1072523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1082523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
1092523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public int readInt() throws IOException {
1102523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        readOrThrow(mByteArray, 0 , 4);
1112523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        mByteBuffer.rewind();
1122523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return mByteBuffer.getInt();
1132523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1142523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
1152523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public long readUnsignedInt() throws IOException {
1162523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return readInt() & 0xffffffffL;
1172523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1182523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
1192523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public long readLong() throws IOException {
1202523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        readOrThrow(mByteArray, 0 , 8);
1212523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        mByteBuffer.rewind();
1222523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return mByteBuffer.getLong();
1232523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1242523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
1252523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public String readString(int n) throws IOException {
1262523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        byte buf[] = new byte[n];
1272523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        readOrThrow(buf);
1282523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return new String(buf, "UTF8");
1292523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1302523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
1312523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public String readString(int n, Charset charset) throws IOException {
1322523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        byte buf[] = new byte[n];
1332523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        readOrThrow(buf);
1342523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return new String(buf, charset);
1352523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1362523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan}