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