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 float 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 final class FloatToByteBufferAdapter extends FloatBuffer {
     34 
     35     private final ByteBuffer byteBuffer;
     36 
     37     static FloatBuffer asFloatBuffer(ByteBuffer byteBuffer) {
     38         ByteBuffer slice = byteBuffer.slice();
     39         slice.order(byteBuffer.order());
     40         return new FloatToByteBufferAdapter(slice);
     41     }
     42 
     43     FloatToByteBufferAdapter(ByteBuffer byteBuffer) {
     44         super(byteBuffer.capacity() / SizeOf.FLOAT);
     45         this.byteBuffer = byteBuffer;
     46         this.byteBuffer.clear();
     47         this.effectiveDirectAddress = byteBuffer.effectiveDirectAddress;
     48     }
     49 
     50     @Override
     51     public FloatBuffer asReadOnlyBuffer() {
     52         FloatToByteBufferAdapter buf = new FloatToByteBufferAdapter(byteBuffer.asReadOnlyBuffer());
     53         buf.limit = limit;
     54         buf.position = position;
     55         buf.mark = mark;
     56         buf.byteBuffer.order = byteBuffer.order;
     57         return buf;
     58     }
     59 
     60     @Override
     61     public FloatBuffer compact() {
     62         if (byteBuffer.isReadOnly()) {
     63             throw new ReadOnlyBufferException();
     64         }
     65         byteBuffer.limit(limit * SizeOf.FLOAT);
     66         byteBuffer.position(position * SizeOf.FLOAT);
     67         byteBuffer.compact();
     68         byteBuffer.clear();
     69         position = limit - position;
     70         limit = capacity;
     71         mark = UNSET_MARK;
     72         return this;
     73     }
     74 
     75     @Override
     76     public FloatBuffer duplicate() {
     77         ByteBuffer bb = byteBuffer.duplicate().order(byteBuffer.order());
     78         FloatToByteBufferAdapter buf = new FloatToByteBufferAdapter(bb);
     79         buf.limit = limit;
     80         buf.position = position;
     81         buf.mark = mark;
     82         return buf;
     83     }
     84 
     85     @Override
     86     public float get() {
     87         if (position == limit) {
     88             throw new BufferUnderflowException();
     89         }
     90         return byteBuffer.getFloat(position++ * SizeOf.FLOAT);
     91     }
     92 
     93     @Override
     94     public float get(int index) {
     95         checkIndex(index);
     96         return byteBuffer.getFloat(index * SizeOf.FLOAT);
     97     }
     98 
     99     @Override
    100     public FloatBuffer get(float[] dst, int dstOffset, int floatCount) {
    101         byteBuffer.limit(limit * SizeOf.FLOAT);
    102         byteBuffer.position(position * SizeOf.FLOAT);
    103         if (byteBuffer instanceof DirectByteBuffer) {
    104             ((DirectByteBuffer) byteBuffer).get(dst, dstOffset, floatCount);
    105         } else {
    106             ((HeapByteBuffer) byteBuffer).get(dst, dstOffset, floatCount);
    107         }
    108         this.position += floatCount;
    109         return this;
    110     }
    111 
    112     @Override
    113     public boolean isDirect() {
    114         return byteBuffer.isDirect();
    115     }
    116 
    117     @Override
    118     public boolean isReadOnly() {
    119         return byteBuffer.isReadOnly();
    120     }
    121 
    122     @Override
    123     public ByteOrder order() {
    124         return byteBuffer.order();
    125     }
    126 
    127     @Override
    128     protected float[] protectedArray() {
    129         throw new UnsupportedOperationException();
    130     }
    131 
    132     @Override
    133     protected int protectedArrayOffset() {
    134         throw new UnsupportedOperationException();
    135     }
    136 
    137     @Override
    138     protected boolean protectedHasArray() {
    139         return false;
    140     }
    141 
    142     @Override
    143     public FloatBuffer put(float c) {
    144         if (position == limit) {
    145             throw new BufferOverflowException();
    146         }
    147         byteBuffer.putFloat(position++ * SizeOf.FLOAT, c);
    148         return this;
    149     }
    150 
    151     @Override
    152     public FloatBuffer put(int index, float c) {
    153         checkIndex(index);
    154         byteBuffer.putFloat(index * SizeOf.FLOAT, c);
    155         return this;
    156     }
    157 
    158     @Override
    159     public FloatBuffer put(float[] src, int srcOffset, int floatCount) {
    160         byteBuffer.limit(limit * SizeOf.FLOAT);
    161         byteBuffer.position(position * SizeOf.FLOAT);
    162         if (byteBuffer instanceof ReadWriteDirectByteBuffer) {
    163             ((ReadWriteDirectByteBuffer) byteBuffer).put(src, srcOffset, floatCount);
    164         } else {
    165             ((ReadWriteHeapByteBuffer) byteBuffer).put(src, srcOffset, floatCount);
    166         }
    167         this.position += floatCount;
    168         return this;
    169     }
    170 
    171     @Override
    172     public FloatBuffer slice() {
    173         byteBuffer.limit(limit * SizeOf.FLOAT);
    174         byteBuffer.position(position * SizeOf.FLOAT);
    175         ByteBuffer bb = byteBuffer.slice().order(byteBuffer.order());
    176         FloatBuffer result = new FloatToByteBufferAdapter(bb);
    177         byteBuffer.clear();
    178         return result;
    179     }
    180 
    181 }
    182