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