• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 
28 package java.nio;
29 
30 
31 import libcore.io.Memory;
32 
33 /**
34  * A read/write HeapByteBuffer.
35  */
36 
37 final class HeapByteBuffer extends ByteBuffer {
38 
39     // For speed these fields are actually declared in X-Buffer;
40     // these declarations are here as documentation
41     /*
42 
43       protected final byte[] hb;
44       protected final int offset;
45 
46     */
47 
HeapByteBuffer(int cap, int lim)48     HeapByteBuffer(int cap, int lim) {            // packag-private
49         this(cap, lim, false);
50     }
51 
52 
HeapByteBuffer(int cap, int lim, boolean isReadOnly)53     private HeapByteBuffer(int cap, int lim, boolean isReadOnly) {
54         super(-1, 0, lim, cap, new byte[cap], 0);
55         this.isReadOnly = isReadOnly;
56     }
57 
HeapByteBuffer(byte[] buf, int off, int len)58     HeapByteBuffer(byte[] buf, int off, int len) { // package-private
59         this(buf, off, len, false);
60     }
61 
HeapByteBuffer(byte[] buf, int off, int len, boolean isReadOnly)62     private HeapByteBuffer(byte[] buf, int off, int len, boolean isReadOnly) {
63         super(-1, off, off + len, buf.length, buf, 0);
64         this.isReadOnly = isReadOnly;
65     }
66 
HeapByteBuffer(byte[] buf, int mark, int pos, int lim, int cap, int off, boolean isReadOnly)67     private HeapByteBuffer(byte[] buf, int mark, int pos, int lim, int cap, int off,
68             boolean isReadOnly) {
69         super(mark, pos, lim, cap, buf, off);
70         this.isReadOnly = isReadOnly;
71     }
72 
73     @Override
slice()74     public ByteBuffer slice() {
75         return new HeapByteBuffer(hb,
76                 -1,
77                 0,
78                 remaining(),
79                 remaining(),
80                 position() + offset,
81                 isReadOnly);
82     }
83 
slice(int pos, int lim)84     ByteBuffer slice(int pos, int lim) {
85         assert (pos >= 0);
86         assert (pos <= lim);
87         int rem = lim - pos;
88         return new HeapByteBuffer(hb,
89                                   -1,
90                                   0,
91                                   rem,
92                                   rem,
93                                   pos + offset,
94                                   isReadOnly);
95     }
96 
97     @Override
duplicate()98     public ByteBuffer duplicate() {
99         return new HeapByteBuffer(hb,
100                 markValue(),
101                 position(),
102                 limit(),
103                 capacity(),
104                 offset,
105                 isReadOnly);
106     }
107 
108     @Override
asReadOnlyBuffer()109     public ByteBuffer asReadOnlyBuffer() {
110         return new HeapByteBuffer(hb,
111                 this.markValue(),
112                 this.position(),
113                 this.limit(),
114                 this.capacity(),
115                 offset, true);
116     }
117 
ix(int i)118     protected int ix(int i) {
119         return i + offset;
120     }
121 
122     @Override
get()123     public byte get() {
124         return hb[ix(nextGetIndex())];
125     }
126 
127     @Override
get(int i)128     public byte get(int i) {
129         return hb[ix(checkIndex(i))];
130     }
131 
132     @Override
get(byte[] dst, int offset, int length)133     public ByteBuffer get(byte[] dst, int offset, int length) {
134         checkBounds(offset, length, dst.length);
135         if (length > remaining())
136             throw new BufferUnderflowException();
137         System.arraycopy(hb, ix(position()), dst, offset, length);
138         position(position() + length);
139         return this;
140     }
141 
142     @Override
isDirect()143     public boolean isDirect() {
144         return false;
145     }
146 
147     @Override
isReadOnly()148     public boolean isReadOnly() {
149         return isReadOnly;
150     }
151 
152     @Override
put(byte x)153     public ByteBuffer put(byte x) {
154         if (isReadOnly) {
155             throw new ReadOnlyBufferException();
156         }
157         hb[ix(nextPutIndex())] = x;
158         return this;
159     }
160 
161     @Override
put(int i, byte x)162     public ByteBuffer put(int i, byte x) {
163         if (isReadOnly) {
164             throw new ReadOnlyBufferException();
165         }
166         hb[ix(checkIndex(i))] = x;
167         return this;
168     }
169 
170     @Override
put(byte[] src, int offset, int length)171     public ByteBuffer put(byte[] src, int offset, int length) {
172         if (isReadOnly) {
173             throw new ReadOnlyBufferException();
174         }
175         checkBounds(offset, length, src.length);
176         if (length > remaining())
177             throw new BufferOverflowException();
178         System.arraycopy(src, offset, hb, ix(position()), length);
179         position(position() + length);
180         return this;
181     }
182 
183     @Override
compact()184     public ByteBuffer compact() {
185         if (isReadOnly) {
186             throw new ReadOnlyBufferException();
187         }
188         System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
189         position(remaining());
190         limit(capacity());
191         discardMark();
192         return this;
193     }
194 
195     @Override
_get(int i)196     byte _get(int i) {                          // package-private
197         return hb[i];
198     }
199 
200     @Override
_put(int i, byte b)201     void _put(int i, byte b) {                  // package-private
202         if (isReadOnly) {
203             throw new ReadOnlyBufferException();
204         }
205         hb[i] = b;
206     }
207 
208     @Override
getChar()209     public char getChar() {
210         return Bits.getChar(this, ix(nextGetIndex(2)), bigEndian);
211     }
212 
213     @Override
getChar(int i)214     public char getChar(int i) {
215         return Bits.getChar(this, ix(checkIndex(i, 2)), bigEndian);
216     }
217 
218     @Override
getCharUnchecked(int i)219     char getCharUnchecked(int i) {
220         return Bits.getChar(this, ix(i), bigEndian);
221     }
222 
223     @Override
getUnchecked(int pos, char[] dst, int dstOffset, int length)224     void getUnchecked(int pos, char[] dst, int dstOffset, int length) {
225         Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder);
226     }
227 
228     @Override
putChar(char x)229     public ByteBuffer putChar(char x) {
230         if (isReadOnly) {
231             throw new ReadOnlyBufferException();
232         }
233         Bits.putChar(this, ix(nextPutIndex(2)), x, bigEndian);
234         return this;
235     }
236 
237     @Override
putChar(int i, char x)238     public ByteBuffer putChar(int i, char x) {
239         if (isReadOnly) {
240             throw new ReadOnlyBufferException();
241         }
242         Bits.putChar(this, ix(checkIndex(i, 2)), x, bigEndian);
243         return this;
244     }
245 
246     @Override
putCharUnchecked(int i, char x)247     void putCharUnchecked(int i, char x) {
248         Bits.putChar(this, ix(i), x, bigEndian);
249     }
250 
251     @Override
putUnchecked(int pos, char[] src, int srcOffset, int length)252     void putUnchecked(int pos, char[] src, int srcOffset, int length) {
253         Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder);
254     }
255 
256     @Override
asCharBuffer()257     public CharBuffer asCharBuffer() {
258         int size = this.remaining() >> 1;
259         int off = position();
260         return new ByteBufferAsCharBuffer(this,
261                 -1,
262                 0,
263                 size,
264                 size,
265                 off,
266                 order());
267     }
268 
269     @Override
getShort()270     public short getShort() {
271         return Bits.getShort(this, ix(nextGetIndex(2)), bigEndian);
272     }
273 
274     @Override
getShort(int i)275     public short getShort(int i) {
276         return Bits.getShort(this, ix(checkIndex(i, 2)), bigEndian);
277     }
278 
279     @Override
getShortUnchecked(int i)280     short getShortUnchecked(int i) {
281         return Bits.getShort(this, ix(i), bigEndian);
282     }
283 
284     @Override
getUnchecked(int pos, short[] dst, int dstOffset, int length)285     void getUnchecked(int pos, short[] dst, int dstOffset, int length) {
286         Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder);
287     }
288 
289     @Override
putShort(short x)290     public ByteBuffer putShort(short x) {
291         if (isReadOnly) {
292             throw new ReadOnlyBufferException();
293         }
294         Bits.putShort(this, ix(nextPutIndex(2)), x, bigEndian);
295         return this;
296     }
297 
298     @Override
putShort(int i, short x)299     public ByteBuffer putShort(int i, short x) {
300         if (isReadOnly) {
301             throw new ReadOnlyBufferException();
302         }
303         Bits.putShort(this, ix(checkIndex(i, 2)), x, bigEndian);
304         return this;
305     }
306 
307     @Override
putShortUnchecked(int i, short x)308     void putShortUnchecked(int i, short x) {
309         Bits.putShort(this, ix(i), x, bigEndian);
310     }
311 
312     @Override
putUnchecked(int pos, short[] src, int srcOffset, int length)313     void putUnchecked(int pos, short[] src, int srcOffset, int length) {
314         Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder);
315     }
316 
317     @Override
asShortBuffer()318     public ShortBuffer asShortBuffer() {
319         int size = this.remaining() >> 1;
320         int off = position();
321         return new ByteBufferAsShortBuffer(this,
322                 -1,
323                 0,
324                 size,
325                 size,
326                 off,
327                 order());
328     }
329 
330     @Override
getInt()331     public int getInt() {
332         return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian);
333     }
334 
335     @Override
getInt(int i)336     public int getInt(int i) {
337         return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian);
338     }
339 
340     @Override
getIntUnchecked(int i)341     int getIntUnchecked(int i) {
342         return Bits.getInt(this, ix(i), bigEndian);
343     }
344 
345     @Override
getUnchecked(int pos, int[] dst, int dstOffset, int length)346     void getUnchecked(int pos, int[] dst, int dstOffset, int length) {
347         Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder);
348     }
349 
350     @Override
putInt(int x)351     public ByteBuffer putInt(int x) {
352         if (isReadOnly) {
353             throw new ReadOnlyBufferException();
354         }
355         Bits.putInt(this, ix(nextPutIndex(4)), x, bigEndian);
356         return this;
357     }
358 
359     @Override
putInt(int i, int x)360     public ByteBuffer putInt(int i, int x) {
361         if (isReadOnly) {
362             throw new ReadOnlyBufferException();
363         }
364         Bits.putInt(this, ix(checkIndex(i, 4)), x, bigEndian);
365         return this;
366     }
367 
368     @Override
putIntUnchecked(int i, int x)369     void putIntUnchecked(int i, int x) {
370         Bits.putInt(this, ix(i), x, bigEndian);
371     }
372 
373     @Override
putUnchecked(int pos, int[] src, int srcOffset, int length)374     void putUnchecked(int pos, int[] src, int srcOffset, int length) {
375         Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder);
376     }
377 
378     @Override
asIntBuffer()379     public IntBuffer asIntBuffer() {
380         int size = this.remaining() >> 2;
381         int off = position();
382 
383         return new ByteBufferAsIntBuffer(this,
384                 -1,
385                 0,
386                 size,
387                 size,
388                 off,
389                 order());
390     }
391 
392     @Override
getLong()393     public long getLong() {
394         return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian);
395     }
396 
397     @Override
getLong(int i)398     public long getLong(int i) {
399         return Bits.getLong(this, ix(checkIndex(i, 8)), bigEndian);
400     }
401 
402     @Override
getLongUnchecked(int i)403     long getLongUnchecked(int i) {
404         return Bits.getLong(this, ix(i), bigEndian);
405     }
406 
407     @Override
getUnchecked(int pos, long[] dst, int dstOffset, int length)408     void getUnchecked(int pos, long[] dst, int dstOffset, int length) {
409         Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder);
410     }
411 
412     @Override
putLong(long x)413     public ByteBuffer putLong(long x) {
414         if (isReadOnly) {
415             throw new ReadOnlyBufferException();
416         }
417         Bits.putLong(this, ix(nextPutIndex(8)), x, bigEndian);
418         return this;
419     }
420 
421     @Override
putLong(int i, long x)422     public ByteBuffer putLong(int i, long x) {
423         if (isReadOnly) {
424             throw new ReadOnlyBufferException();
425         }
426         Bits.putLong(this, ix(checkIndex(i, 8)), x, bigEndian);
427         return this;
428     }
429 
430     @Override
putLongUnchecked(int i, long x)431     void putLongUnchecked(int i, long x) {
432         Bits.putLong(this, ix(i), x, bigEndian);
433     }
434 
435     @Override
putUnchecked(int pos, long[] src, int srcOffset, int length)436     void putUnchecked(int pos, long[] src, int srcOffset, int length) {
437         Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder);
438     }
439 
440     @Override
asLongBuffer()441     public LongBuffer asLongBuffer() {
442         int size = this.remaining() >> 3;
443         int off = position();
444         return new ByteBufferAsLongBuffer(this,
445                 -1,
446                 0,
447                 size,
448                 size,
449                 off,
450                 order());
451     }
452 
453     @Override
getFloat()454     public float getFloat() {
455         return Bits.getFloat(this, ix(nextGetIndex(4)), bigEndian);
456     }
457 
458     @Override
getFloat(int i)459     public float getFloat(int i) {
460         return Bits.getFloat(this, ix(checkIndex(i, 4)), bigEndian);
461     }
462 
463     @Override
getFloatUnchecked(int i)464     float getFloatUnchecked(int i) {
465         return Bits.getFloat(this, ix(i), bigEndian);
466     }
467 
468     @Override
getUnchecked(int pos, float[] dst, int dstOffset, int length)469     void getUnchecked(int pos, float[] dst, int dstOffset, int length) {
470         Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder);
471     }
472 
473     @Override
putFloat(float x)474     public ByteBuffer putFloat(float x) {
475         if (isReadOnly) {
476             throw new ReadOnlyBufferException();
477         }
478         Bits.putFloat(this, ix(nextPutIndex(4)), x, bigEndian);
479         return this;
480     }
481 
482     @Override
putFloat(int i, float x)483     public ByteBuffer putFloat(int i, float x) {
484         if (isReadOnly) {
485             throw new ReadOnlyBufferException();
486         }
487         Bits.putFloat(this, ix(checkIndex(i, 4)), x, bigEndian);
488         return this;
489     }
490 
491     @Override
putFloatUnchecked(int i, float x)492     void putFloatUnchecked(int i, float x) {
493         Bits.putFloat(this, ix(i), x, bigEndian);
494     }
495 
496     @Override
putUnchecked(int pos, float[] src, int srcOffset, int length)497     void putUnchecked(int pos, float[] src, int srcOffset, int length) {
498         Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder);
499     }
500 
501     @Override
asFloatBuffer()502     public FloatBuffer asFloatBuffer() {
503         int size = this.remaining() >> 2;
504         int off = position();
505         return new ByteBufferAsFloatBuffer(this,
506                 -1,
507                 0,
508                 size,
509                 size,
510                 off,
511                 order());
512     }
513 
514     @Override
getDouble()515     public double getDouble() {
516         return Bits.getDouble(this, ix(nextGetIndex(8)), bigEndian);
517     }
518 
519     @Override
getDouble(int i)520     public double getDouble(int i) {
521         return Bits.getDouble(this, ix(checkIndex(i, 8)), bigEndian);
522     }
523 
524     @Override
getDoubleUnchecked(int i)525     double getDoubleUnchecked(int i) {
526         return Bits.getDouble(this, ix(i), bigEndian);
527     }
528 
529     @Override
getUnchecked(int pos, double[] dst, int dstOffset, int length)530     void getUnchecked(int pos, double[] dst, int dstOffset, int length) {
531         Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder);
532     }
533 
534     @Override
putDouble(double x)535     public ByteBuffer putDouble(double x) {
536         if (isReadOnly) {
537             throw new ReadOnlyBufferException();
538         }
539         Bits.putDouble(this, ix(nextPutIndex(8)), x, bigEndian);
540         return this;
541     }
542 
543     @Override
putDouble(int i, double x)544     public ByteBuffer putDouble(int i, double x) {
545         if (isReadOnly) {
546             throw new ReadOnlyBufferException();
547         }
548         Bits.putDouble(this, ix(checkIndex(i, 8)), x, bigEndian);
549         return this;
550     }
551 
552     @Override
putDoubleUnchecked(int i, double x)553     void putDoubleUnchecked(int i, double x) {
554         Bits.putDouble(this, ix(i), x, bigEndian);
555     }
556 
557     @Override
putUnchecked(int pos, double[] src, int srcOffset, int length)558     void putUnchecked(int pos, double[] src, int srcOffset, int length) {
559         Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder);
560     }
561 
562     @Override
asDoubleBuffer()563     public DoubleBuffer asDoubleBuffer() {
564         int size = this.remaining() >> 3;
565         int off = position();
566         return new ByteBufferAsDoubleBuffer(this,
567                 -1,
568                 0,
569                 size,
570                 size,
571                 off,
572                 order());
573     }
574 }
575