Home | History | Annotate | Download | only in nio
      1 /* Licensed to the Apache Software Foundation (ASF) under one or more
      2  * contributor license agreements.  See the NOTICE file distributed with
      3  * this work for additional information regarding copyright ownership.
      4  * The ASF licenses this file to You under the Apache License, Version 2.0
      5  * (the "License"); you may not use this file except in compliance with
      6  * the License.  You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package java.nio;
     18 
     19 import libcore.io.SizeOf;
     20 
     21 /**
     22  * This class wraps a byte buffer to be a int buffer.
     23  * <p>
     24  * Implementation notice:
     25  * <ul>
     26  * <li>After a byte buffer instance is wrapped, it becomes privately owned by
     27  * the adapter. It must NOT be accessed outside the adapter any more.</li>
     28  * <li>The byte buffer's position and limit are NOT linked with the adapter.
     29  * The adapter extends Buffer, thus has its own position and limit.</li>
     30  * </ul>
     31  * </p>
     32  *
     33  */
     34 final class ByteBufferAsIntBuffer extends IntBuffer {
     35 
     36     private final ByteBuffer byteBuffer;
     37 
     38     static IntBuffer asIntBuffer(ByteBuffer byteBuffer) {
     39         ByteBuffer slice = byteBuffer.slice();
     40         slice.order(byteBuffer.order());
     41         return new ByteBufferAsIntBuffer(slice);
     42     }
     43 
     44     private ByteBufferAsIntBuffer(ByteBuffer byteBuffer) {
     45         super(byteBuffer.capacity() / SizeOf.INT);
     46         this.byteBuffer = byteBuffer;
     47         this.byteBuffer.clear();
     48         this.effectiveDirectAddress = byteBuffer.effectiveDirectAddress;
     49     }
     50 
     51     @Override
     52     public IntBuffer asReadOnlyBuffer() {
     53         ByteBufferAsIntBuffer buf = new ByteBufferAsIntBuffer(byteBuffer.asReadOnlyBuffer());
     54         buf.limit = limit;
     55         buf.position = position;
     56         buf.mark = mark;
     57         buf.byteBuffer.order = byteBuffer.order;
     58         return buf;
     59     }
     60 
     61     @Override
     62     public IntBuffer compact() {
     63         if (byteBuffer.isReadOnly()) {
     64             throw new ReadOnlyBufferException();
     65         }
     66         byteBuffer.limit(limit * SizeOf.INT);
     67         byteBuffer.position(position * SizeOf.INT);
     68         byteBuffer.compact();
     69         byteBuffer.clear();
     70         position = limit - position;
     71         limit = capacity;
     72         mark = UNSET_MARK;
     73         return this;
     74     }
     75 
     76     @Override
     77     public IntBuffer duplicate() {
     78         ByteBuffer bb = byteBuffer.duplicate().order(byteBuffer.order());
     79         ByteBufferAsIntBuffer buf = new ByteBufferAsIntBuffer(bb);
     80         buf.limit = limit;
     81         buf.position = position;
     82         buf.mark = mark;
     83         return buf;
     84     }
     85 
     86     @Override
     87     public int get() {
     88         if (position == limit) {
     89             throw new BufferUnderflowException();
     90         }
     91         return byteBuffer.getInt(position++ * SizeOf.INT);
     92     }
     93 
     94     @Override
     95     public int get(int index) {
     96         checkIndex(index);
     97         return byteBuffer.getInt(index * SizeOf.INT);
     98     }
     99 
    100     @Override
    101     public IntBuffer get(int[] dst, int dstOffset, int intCount) {
    102         byteBuffer.limit(limit * SizeOf.INT);
    103         byteBuffer.position(position * SizeOf.INT);
    104         if (byteBuffer instanceof DirectByteBuffer) {
    105             ((DirectByteBuffer) byteBuffer).get(dst, dstOffset, intCount);
    106         } else {
    107             ((ByteArrayBuffer) byteBuffer).get(dst, dstOffset, intCount);
    108         }
    109         this.position += intCount;
    110         return this;
    111     }
    112 
    113     @Override
    114     public boolean isDirect() {
    115         return byteBuffer.isDirect();
    116     }
    117 
    118     @Override
    119     public boolean isReadOnly() {
    120         return byteBuffer.isReadOnly();
    121     }
    122 
    123     @Override
    124     public ByteOrder order() {
    125         return byteBuffer.order();
    126     }
    127 
    128     @Override int[] protectedArray() {
    129         throw new UnsupportedOperationException();
    130     }
    131 
    132     @Override int protectedArrayOffset() {
    133         throw new UnsupportedOperationException();
    134     }
    135 
    136     @Override boolean protectedHasArray() {
    137         return false;
    138     }
    139 
    140     @Override
    141     public IntBuffer put(int c) {
    142         if (position == limit) {
    143             throw new BufferOverflowException();
    144         }
    145         byteBuffer.putInt(position++ * SizeOf.INT, c);
    146         return this;
    147     }
    148 
    149     @Override
    150     public IntBuffer put(int index, int c) {
    151         checkIndex(index);
    152         byteBuffer.putInt(index * SizeOf.INT, c);
    153         return this;
    154     }
    155 
    156     @Override
    157     public IntBuffer put(int[] src, int srcOffset, int intCount) {
    158         byteBuffer.limit(limit * SizeOf.INT);
    159         byteBuffer.position(position * SizeOf.INT);
    160         if (byteBuffer instanceof DirectByteBuffer) {
    161             ((DirectByteBuffer) byteBuffer).put(src, srcOffset, intCount);
    162         } else {
    163             ((ByteArrayBuffer) byteBuffer).put(src, srcOffset, intCount);
    164         }
    165         this.position += intCount;
    166         return this;
    167     }
    168 
    169     @Override
    170     public IntBuffer slice() {
    171         byteBuffer.limit(limit * SizeOf.INT);
    172         byteBuffer.position(position * SizeOf.INT);
    173         ByteBuffer bb = byteBuffer.slice().order(byteBuffer.order());
    174         IntBuffer result = new ByteBufferAsIntBuffer(bb);
    175         byteBuffer.clear();
    176         return result;
    177     }
    178 
    179 }
    180