001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.nio;
019:
020: import org.apache.harmony.luni.platform.Endianness;
021:
022: /**
023: * HeapByteBuffer, ReadWriteHeapByteBuffer and ReadOnlyHeapByteBuffer compose
024: * the implementation of array based byte buffers.
025: * <p>
026: * HeapByteBuffer implements all the shared readonly methods and is extended by
027: * the other two classes.
028: * </p>
029: * <p>
030: * All methods are marked final for runtime performance.
031: * </p>
032: *
033: */
034: abstract class HeapByteBuffer extends BaseByteBuffer {
035:
036: protected final byte[] backingArray;
037:
038: protected final int offset;
039:
040: HeapByteBuffer(byte[] backingArray) {
041: this (backingArray, backingArray.length, 0);
042: }
043:
044: HeapByteBuffer(int capacity) {
045: this (new byte[capacity], capacity, 0);
046: }
047:
048: HeapByteBuffer(byte[] backingArray, int capacity, int offset) {
049: super (capacity);
050: this .backingArray = backingArray;
051: this .offset = offset;
052:
053: if (offset + capacity > backingArray.length) {
054: throw new IndexOutOfBoundsException();
055: }
056: }
057:
058: /*
059: * Override ByteBuffer.get(byte[], int, int) to improve performance.
060: *
061: * (non-Javadoc)
062: *
063: * @see java.nio.ByteBuffer#get(byte[], int, int)
064: */
065: @Override
066: public final ByteBuffer get(byte[] dest, int off, int len) {
067: int length = dest.length;
068: if (off < 0 || len < 0 || (long) off + (long) len > length) {
069: throw new IndexOutOfBoundsException();
070: }
071: if (len > remaining()) {
072: throw new BufferUnderflowException();
073: }
074: System.arraycopy(backingArray, offset + position, dest, off,
075: len);
076: position += len;
077: return this ;
078: }
079:
080: @Override
081: public final byte get() {
082: if (position == limit) {
083: throw new BufferUnderflowException();
084: }
085: return backingArray[offset + position++];
086: }
087:
088: @Override
089: public final byte get(int index) {
090: if (index < 0 || index >= limit) {
091: throw new IndexOutOfBoundsException();
092: }
093: return backingArray[offset + index];
094: }
095:
096: @Override
097: public final double getDouble() {
098: return Double.longBitsToDouble(getLong());
099: }
100:
101: @Override
102: public final double getDouble(int index) {
103: return Double.longBitsToDouble(getLong(index));
104: }
105:
106: @Override
107: public final float getFloat() {
108: return Float.intBitsToFloat(getInt());
109: }
110:
111: @Override
112: public final float getFloat(int index) {
113: return Float.intBitsToFloat(getInt(index));
114: }
115:
116: @Override
117: public final int getInt() {
118: int newPosition = position + 4;
119: if (newPosition > limit) {
120: throw new BufferUnderflowException();
121: }
122: int result = loadInt(position);
123: position = newPosition;
124: return result;
125: }
126:
127: @Override
128: public final int getInt(int index) {
129: if (index < 0 || index + 4 > limit) {
130: throw new IndexOutOfBoundsException();
131: }
132: return loadInt(index);
133: }
134:
135: @Override
136: public final long getLong() {
137: int newPosition = position + 8;
138: if (newPosition > limit) {
139: throw new BufferUnderflowException();
140: }
141: long result = loadLong(position);
142: position = newPosition;
143: return result;
144: }
145:
146: @Override
147: public final long getLong(int index) {
148: if (index < 0 || index + 8 > limit) {
149: throw new IndexOutOfBoundsException();
150: }
151: return loadLong(index);
152: }
153:
154: @Override
155: public final short getShort() {
156: int newPosition = position + 2;
157: if (newPosition > limit) {
158: throw new BufferUnderflowException();
159: }
160: short result = loadShort(position);
161: position = newPosition;
162: return result;
163: }
164:
165: @Override
166: public final short getShort(int index) {
167: if (index < 0 || index + 2 > limit) {
168: throw new IndexOutOfBoundsException();
169: }
170: return loadShort(index);
171: }
172:
173: @Override
174: public final boolean isDirect() {
175: return false;
176: }
177:
178: protected final int loadInt(int index) {
179: int baseOffset = offset + index;
180: int bytes = 0;
181: if (order == Endianness.BIG_ENDIAN) {
182: for (int i = 0; i < 4; i++) {
183: bytes = bytes << 8;
184: bytes = bytes | (backingArray[baseOffset + i] & 0xFF);
185: }
186: } else {
187: for (int i = 3; i >= 0; i--) {
188: bytes = bytes << 8;
189: bytes = bytes | (backingArray[baseOffset + i] & 0xFF);
190: }
191: }
192: return bytes;
193: }
194:
195: protected final long loadLong(int index) {
196: int baseOffset = offset + index;
197: long bytes = 0;
198: if (order == Endianness.BIG_ENDIAN) {
199: for (int i = 0; i < 8; i++) {
200: bytes = bytes << 8;
201: bytes = bytes | (backingArray[baseOffset + i] & 0xFF);
202: }
203: } else {
204: for (int i = 7; i >= 0; i--) {
205: bytes = bytes << 8;
206: bytes = bytes | (backingArray[baseOffset + i] & 0xFF);
207: }
208: }
209: return bytes;
210: }
211:
212: protected final short loadShort(int index) {
213: int baseOffset = offset + index;
214: short bytes = 0;
215: if (order == Endianness.BIG_ENDIAN) {
216: bytes = (short) (backingArray[baseOffset] << 8);
217: bytes |= (backingArray[baseOffset + 1] & 0xFF);
218: } else {
219: bytes = (short) (backingArray[baseOffset + 1] << 8);
220: bytes |= (backingArray[baseOffset] & 0xFF);
221: }
222: return bytes;
223: }
224:
225: protected final void store(int index, int value) {
226: int baseOffset = offset + index;
227: if (order == Endianness.BIG_ENDIAN) {
228: for (int i = 3; i >= 0; i--) {
229: backingArray[baseOffset + i] = (byte) (value & 0xFF);
230: value = value >> 8;
231: }
232: } else {
233: for (int i = 0; i <= 3; i++) {
234: backingArray[baseOffset + i] = (byte) (value & 0xFF);
235: value = value >> 8;
236: }
237: }
238: }
239:
240: protected final void store(int index, long value) {
241: int baseOffset = offset + index;
242: if (order == Endianness.BIG_ENDIAN) {
243: for (int i = 7; i >= 0; i--) {
244: backingArray[baseOffset + i] = (byte) (value & 0xFF);
245: value = value >> 8;
246: }
247: } else {
248: for (int i = 0; i <= 7; i++) {
249: backingArray[baseOffset + i] = (byte) (value & 0xFF);
250: value = value >> 8;
251: }
252: }
253: }
254:
255: protected final void store(int index, short value) {
256: int baseOffset = offset + index;
257: if (order == Endianness.BIG_ENDIAN) {
258: backingArray[baseOffset] = (byte) ((value >> 8) & 0xFF);
259: backingArray[baseOffset + 1] = (byte) (value & 0xFF);
260: } else {
261: backingArray[baseOffset + 1] = (byte) ((value >> 8) & 0xFF);
262: backingArray[baseOffset] = (byte) (value & 0xFF);
263: }
264: }
265: }
|