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