Home | History | Annotate | Download | only in nio
      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 
     22 abstract class DirectByteBuffer extends BaseByteBuffer {
     23     // This is the offset into {@code Buffer.block} at which this buffer logically starts.
     24     // TODO: rewrite this so we set 'block' to an OffsetMemoryBlock?
     25     protected final int offset;
     26 
     27     protected DirectByteBuffer(MemoryBlock block, int capacity, int offset) {
     28         super(capacity, block);
     29 
     30         long baseSize = block.getSize();
     31         if (baseSize >= 0 && (capacity + offset) > baseSize) {
     32             throw new IllegalArgumentException("capacity + offset > baseSize");
     33         }
     34 
     35         this.offset = offset;
     36         this.effectiveDirectAddress = block.toInt() + offset;
     37     }
     38 
     39     @Override
     40     public final ByteBuffer get(byte[] dst, int dstOffset, int byteCount) {
     41         checkGetBounds(1, dst.length, dstOffset, byteCount);
     42         this.block.peekByteArray(offset + position, dst, dstOffset, byteCount);
     43         position += byteCount;
     44         return this;
     45     }
     46 
     47     final void get(char[] dst, int dstOffset, int charCount) {
     48         int byteCount = checkGetBounds(SizeOf.CHAR, dst.length, dstOffset, charCount);
     49         this.block.peekCharArray(offset + position, dst, dstOffset, charCount, order.needsSwap);
     50         position += byteCount;
     51     }
     52 
     53     final void get(double[] dst, int dstOffset, int doubleCount) {
     54         int byteCount = checkGetBounds(SizeOf.DOUBLE, dst.length, dstOffset, doubleCount);
     55         this.block.peekDoubleArray(offset + position, dst, dstOffset, doubleCount, order.needsSwap);
     56         position += byteCount;
     57     }
     58 
     59     final void get(float[] dst, int dstOffset, int floatCount) {
     60         int byteCount = checkGetBounds(SizeOf.FLOAT, dst.length, dstOffset, floatCount);
     61         this.block.peekFloatArray(offset + position, dst, dstOffset, floatCount, order.needsSwap);
     62         position += byteCount;
     63     }
     64 
     65     final void get(int[] dst, int dstOffset, int intCount) {
     66         int byteCount = checkGetBounds(SizeOf.INT, dst.length, dstOffset, intCount);
     67         this.block.peekIntArray(offset + position, dst, dstOffset, intCount, order.needsSwap);
     68         position += byteCount;
     69     }
     70 
     71     final void get(long[] dst, int dstOffset, int longCount) {
     72         int byteCount = checkGetBounds(SizeOf.LONG, dst.length, dstOffset, longCount);
     73         this.block.peekLongArray(offset + position, dst, dstOffset, longCount, order.needsSwap);
     74         position += byteCount;
     75     }
     76 
     77     final void get(short[] dst, int dstOffset, int shortCount) {
     78         int byteCount = checkGetBounds(SizeOf.SHORT, dst.length, dstOffset, shortCount);
     79         this.block.peekShortArray(offset + position, dst, dstOffset, shortCount, order.needsSwap);
     80         position += byteCount;
     81     }
     82 
     83     @Override
     84     public final byte get() {
     85         if (position == limit) {
     86             throw new BufferUnderflowException();
     87         }
     88         return this.block.peekByte(offset + position++);
     89     }
     90 
     91     @Override
     92     public final byte get(int index) {
     93         checkIndex(index);
     94         return this.block.peekByte(offset + index);
     95     }
     96 
     97     @Override
     98     public final char getChar() {
     99         int newPosition = position + SizeOf.CHAR;
    100         if (newPosition > limit) {
    101             throw new BufferUnderflowException();
    102         }
    103         char result = (char) this.block.peekShort(offset + position, order);
    104         position = newPosition;
    105         return result;
    106     }
    107 
    108     @Override
    109     public final char getChar(int index) {
    110         checkIndex(index, SizeOf.CHAR);
    111         return (char) this.block.peekShort(offset + index, order);
    112     }
    113 
    114     @Override
    115     public final double getDouble() {
    116         int newPosition = position + SizeOf.DOUBLE;
    117         if (newPosition > limit) {
    118             throw new BufferUnderflowException();
    119         }
    120         double result = Double.longBitsToDouble(this.block.peekLong(offset + position, order));
    121         position = newPosition;
    122         return result;
    123     }
    124 
    125     @Override
    126     public final double getDouble(int index) {
    127         checkIndex(index, SizeOf.DOUBLE);
    128         return Double.longBitsToDouble(this.block.peekLong(offset + index, order));
    129     }
    130 
    131     @Override
    132     public final float getFloat() {
    133         int newPosition = position + SizeOf.FLOAT;
    134         if (newPosition > limit) {
    135             throw new BufferUnderflowException();
    136         }
    137         float result = Float.intBitsToFloat(this.block.peekInt(offset + position, order));
    138         position = newPosition;
    139         return result;
    140     }
    141 
    142     @Override
    143     public final float getFloat(int index) {
    144         checkIndex(index, SizeOf.FLOAT);
    145         return Float.intBitsToFloat(this.block.peekInt(offset + index, order));
    146     }
    147 
    148     @Override
    149     public final int getInt() {
    150         int newPosition = position + SizeOf.INT;
    151         if (newPosition > limit) {
    152             throw new BufferUnderflowException();
    153         }
    154         int result = this.block.peekInt(offset + position, order);
    155         position = newPosition;
    156         return result;
    157     }
    158 
    159     @Override
    160     public final int getInt(int index) {
    161         checkIndex(index, SizeOf.INT);
    162         return this.block.peekInt(offset + index, order);
    163     }
    164 
    165     @Override
    166     public final long getLong() {
    167         int newPosition = position + SizeOf.LONG;
    168         if (newPosition > limit) {
    169             throw new BufferUnderflowException();
    170         }
    171         long result = this.block.peekLong(offset + position, order);
    172         position = newPosition;
    173         return result;
    174     }
    175 
    176     @Override
    177     public final long getLong(int index) {
    178         checkIndex(index, SizeOf.LONG);
    179         return this.block.peekLong(offset + index, order);
    180     }
    181 
    182     @Override
    183     public final short getShort() {
    184         int newPosition = position + SizeOf.SHORT;
    185         if (newPosition > limit) {
    186             throw new BufferUnderflowException();
    187         }
    188         short result = this.block.peekShort(offset + position, order);
    189         position = newPosition;
    190         return result;
    191     }
    192 
    193     @Override
    194     public final short getShort(int index) {
    195         checkIndex(index, SizeOf.SHORT);
    196         return this.block.peekShort(offset + index, order);
    197     }
    198 
    199     @Override
    200     public final boolean isDirect() {
    201         return true;
    202     }
    203 
    204     public final void free() {
    205         block.free();
    206     }
    207 
    208     @Override protected byte[] protectedArray() {
    209         byte[] array = this.block.array();
    210         if (array == null) {
    211             throw new UnsupportedOperationException();
    212         }
    213         return array;
    214     }
    215 
    216     @Override protected int protectedArrayOffset() {
    217         protectedArray(); // Check we have an array.
    218         return offset;
    219     }
    220 
    221     @Override protected boolean protectedHasArray() {
    222         return protectedArray() != null;
    223     }
    224 }
    225