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 19/** 20 * HeapByteBuffer, ReadWriteHeapByteBuffer and ReadOnlyHeapByteBuffer compose 21 * the implementation of array based byte buffers. 22 * <p> 23 * ReadWriteHeapByteBuffer extends HeapByteBuffer with all the write methods. 24 * </p> 25 * <p> 26 * This class is marked final for runtime performance. 27 * </p> 28 * 29 */ 30final class ReadWriteHeapByteBuffer extends HeapByteBuffer { 31 32 static ReadWriteHeapByteBuffer copy(HeapByteBuffer other, int markOfOther) { 33 ReadWriteHeapByteBuffer buf = new ReadWriteHeapByteBuffer( 34 other.backingArray, other.capacity(), other.offset); 35 buf.limit = other.limit(); 36 buf.position = other.position(); 37 buf.mark = markOfOther; 38 buf.order(other.order()); 39 return buf; 40 } 41 42 ReadWriteHeapByteBuffer(byte[] backingArray) { 43 super(backingArray); 44 } 45 46 ReadWriteHeapByteBuffer(int capacity) { 47 super(capacity); 48 } 49 50 ReadWriteHeapByteBuffer(byte[] backingArray, int capacity, int arrayOffset) { 51 super(backingArray, capacity, arrayOffset); 52 } 53 54 @Override 55 public ByteBuffer asReadOnlyBuffer() { 56 return ReadOnlyHeapByteBuffer.copy(this, mark); 57 } 58 59 @Override 60 public ByteBuffer compact() { 61 System.arraycopy(backingArray, position + offset, backingArray, offset, 62 remaining()); 63 position = limit - position; 64 limit = capacity; 65 mark = UNSET_MARK; 66 return this; 67 } 68 69 @Override 70 public ByteBuffer duplicate() { 71 return copy(this, mark); 72 } 73 74 @Override 75 public boolean isReadOnly() { 76 return false; 77 } 78 79 @Override 80 protected byte[] protectedArray() { 81 return backingArray; 82 } 83 84 @Override 85 protected int protectedArrayOffset() { 86 return offset; 87 } 88 89 @Override 90 protected boolean protectedHasArray() { 91 return true; 92 } 93 94 @Override 95 public ByteBuffer put(byte b) { 96 if (position == limit) { 97 throw new BufferOverflowException(); 98 } 99 backingArray[offset + position++] = b; 100 return this; 101 } 102 103 @Override 104 public ByteBuffer put(int index, byte b) { 105 if (index < 0 || index >= limit) { 106 throw new IndexOutOfBoundsException(); 107 } 108 backingArray[offset + index] = b; 109 return this; 110 } 111 112 /* 113 * Override ByteBuffer.put(byte[], int, int) to improve performance. 114 * 115 * (non-Javadoc) 116 * 117 * @see java.nio.ByteBuffer#put(byte[], int, int) 118 */ 119 @Override 120 public ByteBuffer put(byte[] src, int off, int len) { 121 if (off < 0 || len < 0 || (long) off + (long) len > src.length) { 122 throw new IndexOutOfBoundsException(); 123 } 124 if (len > remaining()) { 125 throw new BufferOverflowException(); 126 } 127 if (isReadOnly()) { 128 throw new ReadOnlyBufferException(); 129 } 130 System.arraycopy(src, off, backingArray, offset + position, len); 131 position += len; 132 return this; 133 } 134 135 @Override 136 public ByteBuffer putDouble(double value) { 137 return putLong(Double.doubleToRawLongBits(value)); 138 } 139 140 @Override 141 public ByteBuffer putDouble(int index, double value) { 142 return putLong(index, Double.doubleToRawLongBits(value)); 143 } 144 145 @Override 146 public ByteBuffer putFloat(float value) { 147 return putInt(Float.floatToIntBits(value)); 148 } 149 150 @Override 151 public ByteBuffer putFloat(int index, float value) { 152 return putInt(index, Float.floatToIntBits(value)); 153 } 154 155 @Override 156 public ByteBuffer putInt(int value) { 157 int newPosition = position + 4; 158 if (newPosition > limit) { 159 throw new BufferOverflowException(); 160 } 161 store(position, value); 162 position = newPosition; 163 return this; 164 } 165 166 @Override 167 public ByteBuffer putInt(int index, int value) { 168 if (index < 0 || (long) index + 4 > limit) { 169 throw new IndexOutOfBoundsException(); 170 } 171 store(index, value); 172 return this; 173 } 174 175 @Override 176 public ByteBuffer putLong(int index, long value) { 177 if (index < 0 || (long) index + 8 > limit) { 178 throw new IndexOutOfBoundsException(); 179 } 180 store(index, value); 181 return this; 182 } 183 184 @Override 185 public ByteBuffer putLong(long value) { 186 int newPosition = position + 8; 187 if (newPosition > limit) { 188 throw new BufferOverflowException(); 189 } 190 store(position, value); 191 position = newPosition; 192 return this; 193 } 194 195 @Override 196 public ByteBuffer putShort(int index, short value) { 197 if (index < 0 || (long) index + 2 > limit) { 198 throw new IndexOutOfBoundsException(); 199 } 200 store(index, value); 201 return this; 202 } 203 204 @Override 205 public ByteBuffer putShort(short value) { 206 int newPosition = position + 2; 207 if (newPosition > limit) { 208 throw new BufferOverflowException(); 209 } 210 store(position, value); 211 position = newPosition; 212 return this; 213 } 214 215 @Override 216 public ByteBuffer slice() { 217 ReadWriteHeapByteBuffer slice = new ReadWriteHeapByteBuffer( 218 backingArray, remaining(), offset + position); 219 slice.order = order; 220 return slice; 221 } 222} 223