DirectByteBuffer.java revision eaa2ff09069424b0f7a95c7cd831cef1b744fe67
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.nio;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.PlatformAddress;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.PlatformAddressFactory;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.nio.internal.DirectBuffer;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.nio.internal.nls.Messages;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * DirectByteBuffer, ReadWriteDirectByteBuffer and ReadOnlyDirectByteBuffer
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * compose the implementation of platform memory based byte buffers.
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * DirectByteBuffer implements all the shared readonly methods and is extended
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * by the other two classes.
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </p>
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * All methods are marked final for runtime performance.
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </p>
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectabstract class DirectByteBuffer extends BaseByteBuffer implements DirectBuffer {
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // This class will help us track whether the address is valid or not.
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static final class SafeAddress {
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected volatile boolean isValid = true;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected final PlatformAddress address;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected SafeAddress(PlatformAddress address) {
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super();
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.address = address;
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // This is a wrapped reference to the base address of the buffer memory.
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected final SafeAddress safeAddress;
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // This is the offset from the base address at which this buffer logically
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // starts.
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected final int offset;
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new direct byte buffer of the given capacity on newly
60eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson     * allocated OS memory. The memory will have been zeroed. When the instance
61eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson     * is discarded the OS memory will be freed if it has not already been done
62eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson     * so by an explicit call to #free(). Callers are encouraged to explicitly
63eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson     * free the memory where possible.
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    DirectByteBuffer(int capacity) {
66eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson        this(new SafeAddress(PlatformAddressFactory.alloc(capacity, (byte) 0)),
67eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson                capacity, 0);
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        safeAddress.address.autoFree();
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    DirectByteBuffer(SafeAddress address, int capacity, int offset) {
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super(capacity);
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // BEGIN android-added
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        PlatformAddress baseAddress = address.address;
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long baseSize = baseAddress.getSize();
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((baseSize >= 0) && ((offset + capacity) > baseSize)) {
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException("slice out of range");
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // END android-added
82eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.safeAddress = address;
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.offset = offset;
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Override ByteBuffer.get(byte[], int, int) to improve performance.
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * (non-Javadoc)
91eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson     *
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see java.nio.ByteBuffer#get(byte[], int, int)
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
94eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final ByteBuffer get(byte[] dest, int off, int len) {
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int length = dest.length;
97eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson        if ((off < 0) || (len < 0) || (long) off + (long) len > length) {
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IndexOutOfBoundsException();
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (len > remaining()) {
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new BufferUnderflowException();
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
103eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson        getBaseAddress().getByteArray(offset + position, dest, off, len);
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        position += len;
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return this;
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
107eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson
108eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final byte get() {
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (position == limit) {
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new BufferUnderflowException();
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getBaseAddress().getByte(offset + position++);
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
116eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final byte get(int index) {
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (index < 0 || index >= limit) {
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IndexOutOfBoundsException();
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getBaseAddress().getByte(offset + index);
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
124eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final double getDouble() {
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int newPosition = position + 8;
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (newPosition > limit) {
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new BufferUnderflowException();
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        double result = getBaseAddress().getDouble(offset + position, order);
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        position = newPosition;
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
135eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final double getDouble(int index) {
137eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson        if (index < 0 || (long) index + 8 > limit) {
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IndexOutOfBoundsException();
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getBaseAddress().getDouble(offset + index, order);
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
143eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final float getFloat() {
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int newPosition = position + 4;
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (newPosition > limit) {
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new BufferUnderflowException();
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        float result = getBaseAddress().getFloat(offset + position, order);
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        position = newPosition;
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
154eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final float getFloat(int index) {
156eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson        if (index < 0 || (long) index + 4 > limit) {
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IndexOutOfBoundsException();
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getBaseAddress().getFloat(offset + index, order);
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
162eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final int getInt() {
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int newPosition = position + 4;
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (newPosition > limit) {
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new BufferUnderflowException();
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int result = getBaseAddress().getInt(offset + position, order);
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        position = newPosition;
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
173eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final int getInt(int index) {
175eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson        if (index < 0 || (long) index + 4 > limit) {
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IndexOutOfBoundsException();
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getBaseAddress().getInt(offset + index, order);
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
181eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final long getLong() {
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int newPosition = position + 8;
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (newPosition > limit) {
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new BufferUnderflowException();
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long result = getBaseAddress().getLong(offset + position, order);
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        position = newPosition;
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
192eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final long getLong(int index) {
194eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson        if (index < 0 || (long) index + 8 > limit) {
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IndexOutOfBoundsException();
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getBaseAddress().getLong(offset + index, order);
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
200eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final short getShort() {
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int newPosition = position + 2;
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (newPosition > limit) {
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new BufferUnderflowException();
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        short result = getBaseAddress().getShort(offset + position, order);
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        position = newPosition;
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
211eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final short getShort(int index) {
213eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson        if (index < 0 || (long) index + 2 > limit) {
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IndexOutOfBoundsException();
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getBaseAddress().getShort(offset + index, order);
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
219eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final boolean isDirect() {
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return true;
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final boolean isAddressValid() {
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return safeAddress.isValid;
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void addressValidityCheck() {
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isAddressValid()) {
230eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson            // nio.08=Cannot use the direct byte buffer after it has been
231eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson            // explicitly freed.
232eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson            throw new IllegalStateException(Messages.getString("nio.08")); //$NON-NLS-1$
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void markAddressInvalid() {
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        safeAddress.isValid = false;
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the base address of the buffer (i.e. before offset).
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final PlatformAddress getBaseAddress() {
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        addressValidityCheck();
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return safeAddress.address;
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the platform address of the start of this buffer instance.
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <em>You must not attempt to free the returned address!!</em> It may not
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * be an address that was explicitly malloc'ed (i.e. if this buffer is the
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * result of a split); and it may be memory shared by multiple buffers.
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If you can guarantee that you want to free the underlying memory call the
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * #free() method on this instance -- generally applications will rely on
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the garbage collector to autofree this memory.
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </p>
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the effective address of the start of the buffer.
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalStateException
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this buffer address is known to have been freed
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             previously.
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final PlatformAddress getEffectiveAddress() {
265bd8ecd863aa83df50d7ce8f5950d8645ab6356afAndy McFadden        // BEGIN android-changed
266bd8ecd863aa83df50d7ce8f5950d8645ab6356afAndy McFadden        PlatformAddress addr = getBaseAddress().offsetBytes(offset);
267bd8ecd863aa83df50d7ce8f5950d8645ab6356afAndy McFadden        effectiveDirectAddress = addr.toInt();
268bd8ecd863aa83df50d7ce8f5950d8645ab6356afAndy McFadden        return addr;
269bd8ecd863aa83df50d7ce8f5950d8645ab6356afAndy McFadden        // END android-changed
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Explicitly free the memory used by this direct byte buffer. If the memory
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * has already been freed then this is a no-op. Once the memory has been
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * freed then operations requiring access to the memory will throw an
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <code>IllegalStateException</code>.
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Note this is is possible that the memory is freed by code that reaches
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * into the address and explicitly frees it 'beneith' us -- this is bad
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * form.
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </p>
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void free() {
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isAddressValid()) {
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            markAddressInvalid();
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            safeAddress.address.free();
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
289eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson
290eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    final protected byte[] protectedArray() {
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throw new UnsupportedOperationException();
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
295eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    final protected int protectedArrayOffset() {
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throw new UnsupportedOperationException();
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
300eaa2ff09069424b0f7a95c7cd831cef1b744fe67Jesse Wilson    @Override
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    final protected boolean protectedHasArray() {
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final int getByteCapacity() {
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return capacity;
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
309