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