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 17package java.nio; 18 19import 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 */ 33final 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