• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 package java.nio;
19 
20 import libcore.io.SizeOf;
21 import libcore.io.Memory;
22 
23 /**
24  * HeapByteBuffer, ReadWriteHeapByteBuffer and ReadOnlyHeapByteBuffer compose
25  * the implementation of array based byte buffers.
26  * <p>
27  * HeapByteBuffer implements all the shared readonly methods and is extended by
28  * the other two classes.
29  * </p>
30  * <p>
31  * All methods are marked final for runtime performance.
32  * </p>
33  *
34  */
35 abstract class HeapByteBuffer extends BaseByteBuffer {
36 
37     /**
38      * These fields are non-private for NioUtils.unsafeArray.
39      */
40     final byte[] backingArray;
41     final int offset;
42 
HeapByteBuffer(byte[] backingArray)43     HeapByteBuffer(byte[] backingArray) {
44         this(backingArray, backingArray.length, 0);
45     }
46 
HeapByteBuffer(int capacity)47     HeapByteBuffer(int capacity) {
48         this(new byte[capacity], capacity, 0);
49     }
50 
HeapByteBuffer(byte[] backingArray, int capacity, int offset)51     HeapByteBuffer(byte[] backingArray, int capacity, int offset) {
52         super(capacity, null);
53         this.backingArray = backingArray;
54         this.offset = offset;
55         if (offset + capacity > backingArray.length) {
56             throw new IndexOutOfBoundsException("backingArray.length=" + backingArray.length +
57                     ", capacity=" + capacity + ", offset=" + offset);
58         }
59     }
60 
61     @Override
get(byte[] dst, int dstOffset, int byteCount)62     public final ByteBuffer get(byte[] dst, int dstOffset, int byteCount) {
63         checkGetBounds(1, dst.length, dstOffset, byteCount);
64         System.arraycopy(backingArray, offset + position, dst, dstOffset, byteCount);
65         position += byteCount;
66         return this;
67     }
68 
get(char[] dst, int dstOffset, int charCount)69     final void get(char[] dst, int dstOffset, int charCount) {
70         int byteCount = checkGetBounds(SizeOf.CHAR, dst.length, dstOffset, charCount);
71         Memory.unsafeBulkGet(dst, dstOffset, byteCount, backingArray, offset + position, SizeOf.CHAR, order.needsSwap);
72         position += byteCount;
73     }
74 
get(double[] dst, int dstOffset, int doubleCount)75     final void get(double[] dst, int dstOffset, int doubleCount) {
76         int byteCount = checkGetBounds(SizeOf.DOUBLE, dst.length, dstOffset, doubleCount);
77         Memory.unsafeBulkGet(dst, dstOffset, byteCount, backingArray, offset + position, SizeOf.DOUBLE, order.needsSwap);
78         position += byteCount;
79     }
80 
get(float[] dst, int dstOffset, int floatCount)81     final void get(float[] dst, int dstOffset, int floatCount) {
82         int byteCount = checkGetBounds(SizeOf.FLOAT, dst.length, dstOffset, floatCount);
83         Memory.unsafeBulkGet(dst, dstOffset, byteCount, backingArray, offset + position, SizeOf.FLOAT, order.needsSwap);
84         position += byteCount;
85     }
86 
get(int[] dst, int dstOffset, int intCount)87     final void get(int[] dst, int dstOffset, int intCount) {
88         int byteCount = checkGetBounds(SizeOf.INT, dst.length, dstOffset, intCount);
89         Memory.unsafeBulkGet(dst, dstOffset, byteCount, backingArray, offset + position, SizeOf.INT, order.needsSwap);
90         position += byteCount;
91     }
92 
get(long[] dst, int dstOffset, int longCount)93     final void get(long[] dst, int dstOffset, int longCount) {
94         int byteCount = checkGetBounds(SizeOf.LONG, dst.length, dstOffset, longCount);
95         Memory.unsafeBulkGet(dst, dstOffset, byteCount, backingArray, offset + position, SizeOf.LONG, order.needsSwap);
96         position += byteCount;
97     }
98 
get(short[] dst, int dstOffset, int shortCount)99     final void get(short[] dst, int dstOffset, int shortCount) {
100         int byteCount = checkGetBounds(SizeOf.SHORT, dst.length, dstOffset, shortCount);
101         Memory.unsafeBulkGet(dst, dstOffset, byteCount, backingArray, offset + position, SizeOf.SHORT, order.needsSwap);
102         position += byteCount;
103     }
104 
105     @Override
get()106     public final byte get() {
107         if (position == limit) {
108             throw new BufferUnderflowException();
109         }
110         return backingArray[offset + position++];
111     }
112 
113     @Override
get(int index)114     public final byte get(int index) {
115         checkIndex(index);
116         return backingArray[offset + index];
117     }
118 
119     @Override
getChar()120     public final char getChar() {
121         int newPosition = position + SizeOf.CHAR;
122         if (newPosition > limit) {
123             throw new BufferUnderflowException();
124         }
125         char result = (char) Memory.peekShort(backingArray, offset + position, order);
126         position = newPosition;
127         return result;
128     }
129 
130     @Override
getChar(int index)131     public final char getChar(int index) {
132         checkIndex(index, SizeOf.CHAR);
133         return (char) Memory.peekShort(backingArray, offset + index, order);
134     }
135 
136     @Override
getDouble()137     public final double getDouble() {
138         return Double.longBitsToDouble(getLong());
139     }
140 
141     @Override
getDouble(int index)142     public final double getDouble(int index) {
143         return Double.longBitsToDouble(getLong(index));
144     }
145 
146     @Override
getFloat()147     public final float getFloat() {
148         return Float.intBitsToFloat(getInt());
149     }
150 
151     @Override
getFloat(int index)152     public final float getFloat(int index) {
153         return Float.intBitsToFloat(getInt(index));
154     }
155 
156     @Override
getInt()157     public final int getInt() {
158         int newPosition = position + SizeOf.INT;
159         if (newPosition > limit) {
160             throw new BufferUnderflowException();
161         }
162         int result = Memory.peekInt(backingArray, offset + position, order);
163         position = newPosition;
164         return result;
165     }
166 
167     @Override
getInt(int index)168     public final int getInt(int index) {
169         checkIndex(index, SizeOf.INT);
170         return Memory.peekInt(backingArray, offset + index, order);
171     }
172 
173     @Override
getLong()174     public final long getLong() {
175         int newPosition = position + SizeOf.LONG;
176         if (newPosition > limit) {
177             throw new BufferUnderflowException();
178         }
179         long result = Memory.peekLong(backingArray, offset + position, order);
180         position = newPosition;
181         return result;
182     }
183 
184     @Override
getLong(int index)185     public final long getLong(int index) {
186         checkIndex(index, SizeOf.LONG);
187         return Memory.peekLong(backingArray, offset + index, order);
188     }
189 
190     @Override
getShort()191     public final short getShort() {
192         int newPosition = position + SizeOf.SHORT;
193         if (newPosition > limit) {
194             throw new BufferUnderflowException();
195         }
196         short result = Memory.peekShort(backingArray, offset + position, order);
197         position = newPosition;
198         return result;
199     }
200 
201     @Override
getShort(int index)202     public final short getShort(int index) {
203         checkIndex(index, SizeOf.SHORT);
204         return Memory.peekShort(backingArray, offset + index, order);
205     }
206 
207     @Override
isDirect()208     public final boolean isDirect() {
209         return false;
210     }
211 }
212