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 ByteBufferAsFloatBuffer 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 ByteBufferAsFloatBuffer(slice);
     41     }
     42 
     43     ByteBufferAsFloatBuffer(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         ByteBufferAsFloatBuffer buf = new ByteBufferAsFloatBuffer(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         ByteBufferAsFloatBuffer buf = new ByteBufferAsFloatBuffer(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             ((ByteArrayBuffer) 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 float[] protectedArray() {
    128         throw new UnsupportedOperationException();
    129     }
    130 
    131     @Override int protectedArrayOffset() {
    132         throw new UnsupportedOperationException();
    133     }
    134 
    135     @Override boolean protectedHasArray() {
    136         return false;
    137     }
    138 
    139     @Override
    140     public FloatBuffer put(float c) {
    141         if (position == limit) {
    142             throw new BufferOverflowException();
    143         }
    144         byteBuffer.putFloat(position++ * SizeOf.FLOAT, c);
    145         return this;
    146     }
    147 
    148     @Override
    149     public FloatBuffer put(int index, float c) {
    150         checkIndex(index);
    151         byteBuffer.putFloat(index * SizeOf.FLOAT, c);
    152         return this;
    153     }
    154 
    155     @Override
    156     public FloatBuffer put(float[] src, int srcOffset, int floatCount) {
    157         byteBuffer.limit(limit * SizeOf.FLOAT);
    158         byteBuffer.position(position * SizeOf.FLOAT);
    159         if (byteBuffer instanceof DirectByteBuffer) {
    160             ((DirectByteBuffer) byteBuffer).put(src, srcOffset, floatCount);
    161         } else {
    162             ((ByteArrayBuffer) byteBuffer).put(src, srcOffset, floatCount);
    163         }
    164         this.position += floatCount;
    165         return this;
    166     }
    167 
    168     @Override
    169     public FloatBuffer slice() {
    170         byteBuffer.limit(limit * SizeOf.FLOAT);
    171         byteBuffer.position(position * SizeOf.FLOAT);
    172         ByteBuffer bb = byteBuffer.slice().order(byteBuffer.order());
    173         FloatBuffer result = new ByteBufferAsFloatBuffer(bb);
    174         byteBuffer.clear();
    175         return result;
    176     }
    177 
    178 }
    179