143a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes/*
243a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes * Copyright (C) 2010 The Android Open Source Project
343a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes *
443a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
543a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes * you may not use this file except in compliance with the License.
643a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes * You may obtain a copy of the License at
743a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes *
843a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
943a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes *
1043a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes * Unless required by applicable law or agreed to in writing, software
1143a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
1243a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1343a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes * See the License for the specific language governing permissions and
1443a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes * limitations under the License.
1543a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes */
1643a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes
1743a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughespackage libcore.io;
1843a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes
1943a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughesimport java.nio.ByteOrder;
20f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughesimport libcore.io.Memory;
2143a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes
2243a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes/**
2343a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes * Iterates over big- or little-endian bytes in a Java byte[].
2443a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes *
2543a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes * @hide don't make this public without adding bounds checking.
2643a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes */
2743a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughespublic final class HeapBufferIterator extends BufferIterator {
2843a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    private final byte[] buffer;
2943a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    private final int offset;
3043a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    private final int byteCount;
3143a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    private final ByteOrder order;
3243a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes
3343a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    private int position;
3443a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes
3543a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    HeapBufferIterator(byte[] buffer, int offset, int byteCount, ByteOrder order) {
3643a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        this.buffer = buffer;
3743a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        this.offset = offset;
3843a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        this.byteCount = byteCount;
3943a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        this.order = order;
4043a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    }
4143a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes
42b5bde2fd72189192b52e726a2d606d70c3c8a34bElliott Hughes    public void seek(int offset) {
43b5bde2fd72189192b52e726a2d606d70c3c8a34bElliott Hughes        position = offset;
44b5bde2fd72189192b52e726a2d606d70c3c8a34bElliott Hughes    }
45b5bde2fd72189192b52e726a2d606d70c3c8a34bElliott Hughes
4643a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    public void skip(int byteCount) {
4743a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        position += byteCount;
4843a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    }
4943a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes
5043a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    public void readByteArray(byte[] dst, int dstOffset, int byteCount) {
5143a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        System.arraycopy(buffer, offset + position, dst, dstOffset, byteCount);
5243a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        position += byteCount;
5343a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    }
5443a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes
5543a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    public byte readByte() {
5643a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        byte result = buffer[offset + position];
5743a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        ++position;
5843a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        return result;
5943a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    }
6043a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes
6143a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    public int readInt() {
62f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughes        int result = Memory.peekInt(buffer, offset + position, order);
6343a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        position += SizeOf.INT;
6443a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        return result;
6543a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    }
6643a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes
6743a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    public void readIntArray(int[] dst, int dstOffset, int intCount) {
6843a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        final int byteCount = intCount * SizeOf.INT;
69f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughes        Memory.unsafeBulkGet(dst, dstOffset, byteCount, buffer, offset + position, SizeOf.INT, order.needsSwap);
7043a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        position += byteCount;
7143a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    }
7243a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes
7343a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    public short readShort() {
74f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughes        short result = Memory.peekShort(buffer, offset + position, order);
7543a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        position += SizeOf.SHORT;
7643a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        return result;
7743a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    }
7843a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes
7943a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    /**
8043a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes     * Returns a new iterator over {@code buffer}, starting at {@code offset} and continuing for
8143a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes     * {@code byteCount} bytes. Items larger than a byte are interpreted using the given byte order.
8243a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes     */
8343a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    public static BufferIterator iterator(byte[] buffer, int offset, int byteCount, ByteOrder order) {
8443a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes        return new HeapBufferIterator(buffer, offset, byteCount, order);
8543a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes    }
8643a9f774d075e0e441d8b996e3f6c81ea483ec89Elliott Hughes}
87