1/* 2 * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26#warn This file is preprocessed before being compiled 27// Android-note: This file is generated by ojluni/src/tools/gensrc_android.sh. 28 29package java.nio; 30 31import java.util.Objects; 32 33import libcore.io.Memory; 34 35class ByteBufferAs$Type$Buffer // package-private 36 extends {#if[ro]?ByteBufferAs}$Type$Buffer{#if[ro]?$BO$} 37{ 38 39#if[rw] 40 41 protected final ByteBuffer bb; 42 43#end[rw] 44 // Android-added: Added offset as address can be zero on Android. 45 /** 46 * The offset from the Bytebuffer at the position 0 (in addition to bb.offset) in the 47 * number of bytes. 48 */ 49 protected final int byteOffset; 50 // Android-added: Merge with little- and big-endian classes. 51 private final ByteOrder order; 52 53 // Android-changed: Added ByteOrder and removed MemorySegmentProxy to be supported yet. 54 ByteBufferAs$Type$Buffer(ByteBuffer bb, 55 int mark, int pos, int lim, int cap, 56 int off, ByteOrder order) 57 { 58#if[rw] 59 // Android-removed: Android duplicates the buffer, and merges with the read-only buffer. 60 // super(mark, pos, lim, cap, segment); 61 // this.bb = bb; 62 // address = addr; 63 // assert address >= bb.address; 64 super(mark, pos, lim, cap); 65 this.bb = bb.duplicate(); 66 this.isReadOnly = bb.isReadOnly; 67 // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and 68 // HeapByteBuffer. We only have to initialize the field when bb is an instance of 69 // DirectByteBuffer. 70 // The address field is used by NIOAccess#getBasePointer and GetDirectBufferAddress method 71 // in art which return the address of the first usable byte of the underlying memory, i.e, 72 // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's 73 // position when the method is called from either HeapByteBuffer or DirectByteBuffer. 74 if (bb instanceof DirectByteBuffer) { 75 this.address = bb.address + off; 76 } 77 this.bb.order(order); 78 this.order = order; 79 byteOffset = off; 80#else[rw] 81 super(bb, mark, pos, lim, cap, addr, segment); 82#end[rw] 83 } 84 85 @Override 86 Object base() { 87 // Android-changed: DirectByteBuffer allocated directly assigns both hb and address field. 88 // return bb.hb; 89 return bb.base(); 90 } 91 92 @Override 93 public $Type$Buffer slice() { 94 int pos = this.position(); 95 int lim = this.limit(); 96 int rem = (pos <= lim ? lim - pos : 0); 97 // Android-changed: Added ByteOrder and removed MemorySegmentProxy to be supported yet. 98 // long addr = byteOffset(pos); 99 // return new ByteBufferAs$Type$Buffer(bb, -1, 0, rem, rem, addr, order); 100 return new ByteBufferAs$Type$Buffer(bb, -1, 0, rem, rem, ix(pos), order); 101 } 102 103 @Override 104 public $Type$Buffer slice(int index, int length) { 105 Objects.checkFromIndexSize(index, length, limit()); 106 return new ByteBufferAs$Type$Buffer(bb, 107 -1, 108 0, 109 length, 110 length, 111 // Android-changed: Added ByteOrder and removed MemorySegmentProxy to be supported yet. 112 ix(index), order); 113 } 114 115 @Override 116 public $Type$Buffer duplicate() { 117 return new ByteBufferAs$Type$Buffer(bb, 118 this.markValue(), 119 this.position(), 120 this.limit(), 121 this.capacity(), 122 // Android-changed: Added ByteOrder and removed MemorySegmentProxy to be supported yet. 123 byteOffset, order); 124 } 125 126 @Override 127 public $Type$Buffer asReadOnlyBuffer() { 128#if[rw] 129 return new ByteBufferAs$Type$Buffer(bb.asReadOnlyBuffer(), 130 this.markValue(), 131 this.position(), 132 this.limit(), 133 this.capacity(), 134 // Android-changed: Added ByteOrder and removed MemorySegmentProxy to be supported yet. 135 byteOffset, order); 136#else[rw] 137 return duplicate(); 138#end[rw] 139 } 140 141#if[rw] 142 143 private int ix(int i) { 144 // Android-changed: address can be zero on Android. 145 // int off = (int) (address - bb.address); 146 // return (i << $LG_BYTES_PER_VALUE$) + off; 147 return (i << $LG_BYTES_PER_VALUE$) + byteOffset; 148 } 149 150 // Android-removed: Removed unused byteOffset(long). 151 /* 152 protected long byteOffset(long i) { 153 return (i << $LG_BYTES_PER_VALUE$) + address; 154 } 155 */ 156 157 @Override 158 public $type$ get() { 159 // Android-changed: Removed MemorySegmentProxy to be supported yet. 160 // $memtype$ x = SCOPED_MEMORY_ACCESS.get$Memtype$Unaligned(scope(), bb.hb, byteOffset(nextGetIndex()), 161 // {#if[boB]?true:false}); 162 // return $fromBits$(x); 163 return get(nextGetIndex()); 164 } 165 166 @Override 167 public $type$ get(int i) { 168 // Android-changed: Removed MemorySegmentProxy to be supported yet. 169 // $memtype$ x = SCOPED_MEMORY_ACCESS.get$Memtype$Unaligned(scope(), bb.hb, byteOffset(checkIndex(i)), 170 // {#if[boB]?true:false}); 171 // return $fromBits$(x); 172 return bb.get$Type$Unchecked(ix(checkIndex(i))); 173 } 174 175 // BEGIN Android-added: Improve the efficiency of get(). 176 @Override 177 public $Type$Buffer get($type$[] dst, int off, int length) { 178 Objects.checkFromIndexSize(off, length, dst.length); 179 if (length > remaining()) 180 throw new BufferUnderflowException(); 181 bb.getUnchecked(ix(position), dst, off, length); 182 position += length; 183 return this; 184 } 185 186 @Override 187 public $Type$Buffer get(int index, $type$[] dst, int off, int length) { 188 Objects.checkFromIndexSize(index, length, limit()); 189 Objects.checkFromIndexSize(off, length, dst.length); 190 bb.getUnchecked(ix(index), dst, off, length); 191 return this; 192 } 193 // END Android-added: Improve the efficiency of get(). 194 195#if[streamableType] 196 @Override 197 $type$ getUnchecked(int i) { 198 // Android-changed: Removed MemorySegmentProxy to be supported yet. 199 // $memtype$ x = SCOPED_MEMORY_ACCESS.get$Memtype$Unaligned(null, bb.hb, byteOffset(i), 200 // {#if[boB]?true:false}); 201 // return $fromBits$(x); 202 return bb.get$Type$Unchecked(ix(i)); 203 } 204#end[streamableType] 205 206#end[rw] 207 208 @Override 209 public $Type$Buffer put($type$ x) { 210#if[rw] 211 // Android-added: Merge the Read-only buffer class with this Read-Write buffer class. 212 throwIfReadOnly(); 213 // Android-changed: Removed MemorySegmentProxy to be supported yet. 214 // $memtype$ y = $toBits$(x); 215 // SCOPED_MEMORY_ACCESS.put$Memtype$Unaligned(scope(), bb.hb, byteOffset(nextPutIndex()), y, 216 // {#if[boB]?true:false}); 217 put(nextPutIndex(), x); 218 return this; 219#else[rw] 220 throw new ReadOnlyBufferException(); 221#end[rw] 222 } 223 224 @Override 225 public $Type$Buffer put(int i, $type$ x) { 226#if[rw] 227 // Android-added: Merge the Read-only buffer class with this Read-Write buffer class. 228 throwIfReadOnly(); 229 // Android-changed: Removed MemorySegmentProxy to be supported yet. 230 // $memtype$ y = $toBits$(x); 231 // SCOPED_MEMORY_ACCESS.put$Memtype$Unaligned(scope(), bb.hb, byteOffset(checkIndex(i)), y, 232 // {#if[boB]?true:false}); 233 bb.put$Type$Unchecked(ix(checkIndex(i)), x); 234 return this; 235#else[rw] 236 throw new ReadOnlyBufferException(); 237#end[rw] 238 } 239 240 // BEGIN Android-added: Improve the efficiency of put(type$[]). 241 @Override 242 public $Type$Buffer put($type$[] src, int off, int length) { 243 throwIfReadOnly(); 244 Objects.checkFromIndexSize(off, length, src.length); 245 if (length > remaining()) 246 throw new BufferOverflowException(); 247 bb.putUnchecked(ix(position), src, off, length); 248 position += length; 249 return this; 250 } 251 252 @Override 253 public $Type$Buffer put(int index, $type$[] src, int off, int length) { 254 throwIfReadOnly(); 255 Objects.checkFromIndexSize(index, length, limit()); 256 Objects.checkFromIndexSize(off, length, src.length); 257 putUnchecked(index, src, off, length); 258 return this; 259 } 260 261 private void putUnchecked(int index, $type$[] src, int off, int length) { 262 bb.putUnchecked(ix(index), src, off, length); 263 } 264 265 @Override 266 void putBuffer(int pos, $Type$Buffer src, int srcPos, int n) { 267 if (src.hb != null) { 268 // this and src don't share the same backed char[]. 269 putUnchecked(pos, src.hb, srcPos + src.offset, n); 270 return; 271 } 272 if (order() == src.order() && 273 src instanceof ByteBufferAs$Type$Buffer asSrc) { // always true if src.hb == null 274 this.bb.putBuffer(ix(pos), asSrc.bb, asSrc.ix(srcPos), n << $LG_BYTES_PER_VALUE$); 275 return; 276 } 277 278 // Fallback to the slow path until memmove with bswap is implemented 279 super.putBuffer(pos, src, srcPos, n); 280 } 281 // END Android-added: Improve the efficiency of put(type$[]). 282 283 @Override 284 public $Type$Buffer compact() { 285#if[rw] 286 // Android-added: Merge the Read-only buffer class with this Read-Write buffer class. 287 throwIfReadOnly(); 288 int pos = position(); 289 int lim = limit(); 290 int rem = (pos <= lim ? lim - pos : 0); 291 // Android-changed: Improve the efficiency. 292 /* 293 ByteBuffer db = bb.duplicate(); 294 db.limit(ix(lim)); 295 db.position(ix(0)); 296 ByteBuffer sb = db.slice(); 297 sb.position(pos << $LG_BYTES_PER_VALUE$); 298 sb.compact(); 299 */ 300 if (!(bb instanceof DirectByteBuffer)) { 301 System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << $LG_BYTES_PER_VALUE$); 302 } else { 303 // Use pos << $LG_BYTES_PER_VALUE$ instead of ix(pos) to avoid double counting of the offset 304 // because this.address == bb.address + offset; 305 Memory.memmove(this, 0, this, pos << $LG_BYTES_PER_VALUE$, rem << $LG_BYTES_PER_VALUE$); 306 } 307 position(rem); 308 limit(capacity()); 309 discardMark(); 310 return this; 311#else[rw] 312 throw new ReadOnlyBufferException(); 313#end[rw] 314 } 315 316 @Override 317 public boolean isDirect() { 318 return bb.isDirect(); 319 } 320 321 @Override 322 public boolean isReadOnly() { 323 return isReadOnly; 324 } 325 326#if[char] 327 328 @Override 329 public String toString(int start, int end) { 330 Objects.checkFromToIndex(start, end, limit()); 331 try { 332 int len = end - start; 333 char[] ca = new char[len]; 334 CharBuffer cb = CharBuffer.wrap(ca); 335 CharBuffer db = this.duplicate(); 336 db.position(start); 337 db.limit(end); 338 cb.put(db); 339 return new String(ca); 340 } catch (StringIndexOutOfBoundsException x) { 341 throw new IndexOutOfBoundsException(); 342 } 343 } 344 345 346 // --- Methods to support CharSequence --- 347 348 @Override 349 public CharBuffer subSequence(int start, int end) { 350 int pos = position(); 351 int lim = limit(); 352 pos = (pos <= lim ? pos : lim); 353 int len = lim - pos; 354 355 Objects.checkFromToIndex(start, end, len); 356 return new ByteBufferAsCharBuffer(bb, 357 -1, 358 pos + start, 359 pos + end, 360 capacity(), 361 // Android-changed: Added ByteOrder and removed MemorySegmentProxy to be supported yet. 362 byteOffset, order); 363 } 364 365#end[char] 366 367 368 @Override 369 public ByteOrder order() { 370 return order; 371 } 372 373#if[char] 374 @Override 375 ByteOrder charRegionOrder() { 376 return order(); 377 } 378#end[char] 379 380 // Android-added: Merge the Read-only buffer class with this Read-Write buffer class. 381 private void throwIfReadOnly() { 382 if (isReadOnly) { 383 throw new ReadOnlyBufferException(); 384 } 385 } 386} 387