Home | History | Annotate | Download | only in nio
      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 
     48     HeapByteBuffer(int cap, int lim) {            // packag-private
     49         this(cap, lim, false);
     50     }
     51 
     52 
     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 
     58     HeapByteBuffer(byte[] buf, int off, int len) { // package-private
     59         this(buf, off, len, false);
     60     }
     61 
     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 
     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
     74     public ByteBuffer slice() {
     75         return new HeapByteBuffer(hb,
     76                 -1,
     77                 0,
     78                 remaining(),
     79                 remaining(),
     80                 position() + offset,
     81                 isReadOnly);
     82     }
     83 
     84     @Override
     85     public ByteBuffer duplicate() {
     86         return new HeapByteBuffer(hb,
     87                 markValue(),
     88                 position(),
     89                 limit(),
     90                 capacity(),
     91                 offset,
     92                 isReadOnly);
     93     }
     94 
     95     @Override
     96     public ByteBuffer asReadOnlyBuffer() {
     97         return new HeapByteBuffer(hb,
     98                 this.markValue(),
     99                 this.position(),
    100                 this.limit(),
    101                 this.capacity(),
    102                 offset, true);
    103     }
    104 
    105     protected int ix(int i) {
    106         return i + offset;
    107     }
    108 
    109     @Override
    110     public byte get() {
    111         return hb[ix(nextGetIndex())];
    112     }
    113 
    114     @Override
    115     public byte get(int i) {
    116         return hb[ix(checkIndex(i))];
    117     }
    118 
    119     @Override
    120     public ByteBuffer get(byte[] dst, int offset, int length) {
    121         checkBounds(offset, length, dst.length);
    122         if (length > remaining())
    123             throw new BufferUnderflowException();
    124         System.arraycopy(hb, ix(position()), dst, offset, length);
    125         position(position() + length);
    126         return this;
    127     }
    128 
    129     @Override
    130     public boolean isDirect() {
    131         return false;
    132     }
    133 
    134     @Override
    135     public boolean isReadOnly() {
    136         return isReadOnly;
    137     }
    138 
    139     @Override
    140     public ByteBuffer put(byte x) {
    141         if (isReadOnly) {
    142             throw new ReadOnlyBufferException();
    143         }
    144         hb[ix(nextPutIndex())] = x;
    145         return this;
    146     }
    147 
    148     @Override
    149     public ByteBuffer put(int i, byte x) {
    150         if (isReadOnly) {
    151             throw new ReadOnlyBufferException();
    152         }
    153         hb[ix(checkIndex(i))] = x;
    154         return this;
    155     }
    156 
    157     @Override
    158     public ByteBuffer put(byte[] src, int offset, int length) {
    159         if (isReadOnly) {
    160             throw new ReadOnlyBufferException();
    161         }
    162         checkBounds(offset, length, src.length);
    163         if (length > remaining())
    164             throw new BufferOverflowException();
    165         System.arraycopy(src, offset, hb, ix(position()), length);
    166         position(position() + length);
    167         return this;
    168     }
    169 
    170     @Override
    171     public ByteBuffer compact() {
    172         if (isReadOnly) {
    173             throw new ReadOnlyBufferException();
    174         }
    175         System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
    176         position(remaining());
    177         limit(capacity());
    178         discardMark();
    179         return this;
    180     }
    181 
    182     @Override
    183     byte _get(int i) {                          // package-private
    184         return hb[i];
    185     }
    186 
    187     @Override
    188     void _put(int i, byte b) {                  // package-private
    189         if (isReadOnly) {
    190             throw new ReadOnlyBufferException();
    191         }
    192         hb[i] = b;
    193     }
    194 
    195     @Override
    196     public char getChar() {
    197         return Bits.getChar(this, ix(nextGetIndex(2)), bigEndian);
    198     }
    199 
    200     @Override
    201     public char getChar(int i) {
    202         return Bits.getChar(this, ix(checkIndex(i, 2)), bigEndian);
    203     }
    204 
    205     @Override
    206     char getCharUnchecked(int i) {
    207         return Bits.getChar(this, ix(i), bigEndian);
    208     }
    209 
    210     @Override
    211     void getUnchecked(int pos, char[] dst, int dstOffset, int length) {
    212         Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder);
    213     }
    214 
    215     @Override
    216     public ByteBuffer putChar(char x) {
    217         if (isReadOnly) {
    218             throw new ReadOnlyBufferException();
    219         }
    220         Bits.putChar(this, ix(nextPutIndex(2)), x, bigEndian);
    221         return this;
    222     }
    223 
    224     @Override
    225     public ByteBuffer putChar(int i, char x) {
    226         if (isReadOnly) {
    227             throw new ReadOnlyBufferException();
    228         }
    229         Bits.putChar(this, ix(checkIndex(i, 2)), x, bigEndian);
    230         return this;
    231     }
    232 
    233     @Override
    234     void putCharUnchecked(int i, char x) {
    235         Bits.putChar(this, ix(i), x, bigEndian);
    236     }
    237 
    238     @Override
    239     void putUnchecked(int pos, char[] src, int srcOffset, int length) {
    240         Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder);
    241     }
    242 
    243     @Override
    244     public CharBuffer asCharBuffer() {
    245         int size = this.remaining() >> 1;
    246         int off = position();
    247         return new ByteBufferAsCharBuffer(this,
    248                 -1,
    249                 0,
    250                 size,
    251                 size,
    252                 off,
    253                 order());
    254     }
    255 
    256     @Override
    257     public short getShort() {
    258         return Bits.getShort(this, ix(nextGetIndex(2)), bigEndian);
    259     }
    260 
    261     @Override
    262     public short getShort(int i) {
    263         return Bits.getShort(this, ix(checkIndex(i, 2)), bigEndian);
    264     }
    265 
    266     @Override
    267     short getShortUnchecked(int i) {
    268         return Bits.getShort(this, ix(i), bigEndian);
    269     }
    270 
    271     @Override
    272     void getUnchecked(int pos, short[] dst, int dstOffset, int length) {
    273         Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder);
    274     }
    275 
    276     @Override
    277     public ByteBuffer putShort(short x) {
    278         if (isReadOnly) {
    279             throw new ReadOnlyBufferException();
    280         }
    281         Bits.putShort(this, ix(nextPutIndex(2)), x, bigEndian);
    282         return this;
    283     }
    284 
    285     @Override
    286     public ByteBuffer putShort(int i, short x) {
    287         if (isReadOnly) {
    288             throw new ReadOnlyBufferException();
    289         }
    290         Bits.putShort(this, ix(checkIndex(i, 2)), x, bigEndian);
    291         return this;
    292     }
    293 
    294     @Override
    295     void putShortUnchecked(int i, short x) {
    296         Bits.putShort(this, ix(i), x, bigEndian);
    297     }
    298 
    299     @Override
    300     void putUnchecked(int pos, short[] src, int srcOffset, int length) {
    301         Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder);
    302     }
    303 
    304     @Override
    305     public ShortBuffer asShortBuffer() {
    306         int size = this.remaining() >> 1;
    307         int off = position();
    308         return new ByteBufferAsShortBuffer(this,
    309                 -1,
    310                 0,
    311                 size,
    312                 size,
    313                 off,
    314                 order());
    315     }
    316 
    317     @Override
    318     public int getInt() {
    319         return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian);
    320     }
    321 
    322     @Override
    323     public int getInt(int i) {
    324         return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian);
    325     }
    326 
    327     @Override
    328     int getIntUnchecked(int i) {
    329         return Bits.getInt(this, ix(i), bigEndian);
    330     }
    331 
    332     @Override
    333     void getUnchecked(int pos, int[] dst, int dstOffset, int length) {
    334         Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder);
    335     }
    336 
    337     @Override
    338     public ByteBuffer putInt(int x) {
    339         if (isReadOnly) {
    340             throw new ReadOnlyBufferException();
    341         }
    342         Bits.putInt(this, ix(nextPutIndex(4)), x, bigEndian);
    343         return this;
    344     }
    345 
    346     @Override
    347     public ByteBuffer putInt(int i, int x) {
    348         if (isReadOnly) {
    349             throw new ReadOnlyBufferException();
    350         }
    351         Bits.putInt(this, ix(checkIndex(i, 4)), x, bigEndian);
    352         return this;
    353     }
    354 
    355     @Override
    356     void putIntUnchecked(int i, int x) {
    357         Bits.putInt(this, ix(i), x, bigEndian);
    358     }
    359 
    360     @Override
    361     void putUnchecked(int pos, int[] src, int srcOffset, int length) {
    362         Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder);
    363     }
    364 
    365     @Override
    366     public IntBuffer asIntBuffer() {
    367         int size = this.remaining() >> 2;
    368         int off = position();
    369 
    370         return new ByteBufferAsIntBuffer(this,
    371                 -1,
    372                 0,
    373                 size,
    374                 size,
    375                 off,
    376                 order());
    377     }
    378 
    379     @Override
    380     public long getLong() {
    381         return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian);
    382     }
    383 
    384     @Override
    385     public long getLong(int i) {
    386         return Bits.getLong(this, ix(checkIndex(i, 8)), bigEndian);
    387     }
    388 
    389     @Override
    390     long getLongUnchecked(int i) {
    391         return Bits.getLong(this, ix(i), bigEndian);
    392     }
    393 
    394     @Override
    395     void getUnchecked(int pos, long[] dst, int dstOffset, int length) {
    396         Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder);
    397     }
    398 
    399     @Override
    400     public ByteBuffer putLong(long x) {
    401         if (isReadOnly) {
    402             throw new ReadOnlyBufferException();
    403         }
    404         Bits.putLong(this, ix(nextPutIndex(8)), x, bigEndian);
    405         return this;
    406     }
    407 
    408     @Override
    409     public ByteBuffer putLong(int i, long x) {
    410         if (isReadOnly) {
    411             throw new ReadOnlyBufferException();
    412         }
    413         Bits.putLong(this, ix(checkIndex(i, 8)), x, bigEndian);
    414         return this;
    415     }
    416 
    417     @Override
    418     void putLongUnchecked(int i, long x) {
    419         Bits.putLong(this, ix(i), x, bigEndian);
    420     }
    421 
    422     @Override
    423     void putUnchecked(int pos, long[] src, int srcOffset, int length) {
    424         Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder);
    425     }
    426 
    427     @Override
    428     public LongBuffer asLongBuffer() {
    429         int size = this.remaining() >> 3;
    430         int off = position();
    431         return new ByteBufferAsLongBuffer(this,
    432                 -1,
    433                 0,
    434                 size,
    435                 size,
    436                 off,
    437                 order());
    438     }
    439 
    440     @Override
    441     public float getFloat() {
    442         return Bits.getFloat(this, ix(nextGetIndex(4)), bigEndian);
    443     }
    444 
    445     @Override
    446     public float getFloat(int i) {
    447         return Bits.getFloat(this, ix(checkIndex(i, 4)), bigEndian);
    448     }
    449 
    450     @Override
    451     float getFloatUnchecked(int i) {
    452         return Bits.getFloat(this, ix(i), bigEndian);
    453     }
    454 
    455     @Override
    456     void getUnchecked(int pos, float[] dst, int dstOffset, int length) {
    457         Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder);
    458     }
    459 
    460     @Override
    461     public ByteBuffer putFloat(float x) {
    462         if (isReadOnly) {
    463             throw new ReadOnlyBufferException();
    464         }
    465         Bits.putFloat(this, ix(nextPutIndex(4)), x, bigEndian);
    466         return this;
    467     }
    468 
    469     @Override
    470     public ByteBuffer putFloat(int i, float x) {
    471         if (isReadOnly) {
    472             throw new ReadOnlyBufferException();
    473         }
    474         Bits.putFloat(this, ix(checkIndex(i, 4)), x, bigEndian);
    475         return this;
    476     }
    477 
    478     @Override
    479     void putFloatUnchecked(int i, float x) {
    480         Bits.putFloat(this, ix(i), x, bigEndian);
    481     }
    482 
    483     @Override
    484     void putUnchecked(int pos, float[] src, int srcOffset, int length) {
    485         Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder);
    486     }
    487 
    488     @Override
    489     public FloatBuffer asFloatBuffer() {
    490         int size = this.remaining() >> 2;
    491         int off = position();
    492         return new ByteBufferAsFloatBuffer(this,
    493                 -1,
    494                 0,
    495                 size,
    496                 size,
    497                 off,
    498                 order());
    499     }
    500 
    501     @Override
    502     public double getDouble() {
    503         return Bits.getDouble(this, ix(nextGetIndex(8)), bigEndian);
    504     }
    505 
    506     @Override
    507     public double getDouble(int i) {
    508         return Bits.getDouble(this, ix(checkIndex(i, 8)), bigEndian);
    509     }
    510 
    511     @Override
    512     double getDoubleUnchecked(int i) {
    513         return Bits.getDouble(this, ix(i), bigEndian);
    514     }
    515 
    516     @Override
    517     void getUnchecked(int pos, double[] dst, int dstOffset, int length) {
    518         Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder);
    519     }
    520 
    521     @Override
    522     public ByteBuffer putDouble(double x) {
    523         if (isReadOnly) {
    524             throw new ReadOnlyBufferException();
    525         }
    526         Bits.putDouble(this, ix(nextPutIndex(8)), x, bigEndian);
    527         return this;
    528     }
    529 
    530     @Override
    531     public ByteBuffer putDouble(int i, double x) {
    532         if (isReadOnly) {
    533             throw new ReadOnlyBufferException();
    534         }
    535         Bits.putDouble(this, ix(checkIndex(i, 8)), x, bigEndian);
    536         return this;
    537     }
    538 
    539     @Override
    540     void putDoubleUnchecked(int i, double x) {
    541         Bits.putDouble(this, ix(i), x, bigEndian);
    542     }
    543 
    544     @Override
    545     void putUnchecked(int pos, double[] src, int srcOffset, int length) {
    546         Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder);
    547     }
    548 
    549     @Override
    550     public DoubleBuffer asDoubleBuffer() {
    551         int size = this.remaining() >> 3;
    552         int off = position();
    553         return new ByteBufferAsDoubleBuffer(this,
    554                 -1,
    555                 0,
    556                 size,
    557                 size,
    558                 off,
    559                 order());
    560     }
    561 }
    562