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 28package java.nio; 29 30import java.util.Objects; 31import jdk.internal.access.foreign.MemorySegmentProxy; 32import jdk.internal.misc.Unsafe; 33 34class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private 35 extends {#if[ro]?ByteBufferAs}$Type$Buffer{#if[ro]?$BO$} 36{ 37 38#if[rw] 39 40 protected final ByteBuffer bb; 41 42#end[rw] 43 44 ByteBufferAs$Type$Buffer$RW$$BO$(ByteBuffer bb, MemorySegmentProxy segment) { // package-private 45#if[rw] 46 super(-1, 0, 47 bb.remaining() >> $LG_BYTES_PER_VALUE$, 48 bb.remaining() >> $LG_BYTES_PER_VALUE$, segment); 49 this.bb = bb; 50 // enforce limit == capacity 51 int cap = this.capacity(); 52 this.limit(cap); 53 int pos = this.position(); 54 assert (pos <= cap); 55 address = bb.address; 56#else[rw] 57 super(bb, segment); 58#end[rw] 59 } 60 61 ByteBufferAs$Type$Buffer$RW$$BO$(ByteBuffer bb, 62 int mark, int pos, int lim, int cap, 63 long addr, MemorySegmentProxy segment) 64 { 65#if[rw] 66 super(mark, pos, lim, cap, segment); 67 this.bb = bb; 68 address = addr; 69 assert address >= bb.address; 70#else[rw] 71 super(bb, mark, pos, lim, cap, addr, segment); 72#end[rw] 73 } 74 75 @Override 76 Object base() { 77 return bb.hb; 78 } 79 80 public $Type$Buffer slice() { 81 int pos = this.position(); 82 int lim = this.limit(); 83 int rem = (pos <= lim ? lim - pos : 0); 84 long addr = byteOffset(pos); 85 return new ByteBufferAs$Type$Buffer$RW$$BO$(bb, -1, 0, rem, rem, addr, segment); 86 } 87 88 @Override 89 public $Type$Buffer slice(int index, int length) { 90 Objects.checkFromIndexSize(index, length, limit()); 91 return new ByteBufferAs$Type$Buffer$RW$$BO$(bb, 92 -1, 93 0, 94 length, 95 length, 96 byteOffset(index), segment); 97 } 98 99 public $Type$Buffer duplicate() { 100 return new ByteBufferAs$Type$Buffer$RW$$BO$(bb, 101 this.markValue(), 102 this.position(), 103 this.limit(), 104 this.capacity(), 105 address, segment); 106 } 107 108 public $Type$Buffer asReadOnlyBuffer() { 109#if[rw] 110 return new ByteBufferAs$Type$BufferR$BO$(bb, 111 this.markValue(), 112 this.position(), 113 this.limit(), 114 this.capacity(), 115 address, segment); 116#else[rw] 117 return duplicate(); 118#end[rw] 119 } 120 121#if[rw] 122 123 private int ix(int i) { 124 int off = (int) (address - bb.address); 125 return (i << $LG_BYTES_PER_VALUE$) + off; 126 } 127 128 protected long byteOffset(long i) { 129 return (i << $LG_BYTES_PER_VALUE$) + address; 130 } 131 132 public $type$ get() { 133 $memtype$ x = SCOPED_MEMORY_ACCESS.get$Memtype$Unaligned(scope(), bb.hb, byteOffset(nextGetIndex()), 134 {#if[boB]?true:false}); 135 return $fromBits$(x); 136 } 137 138 public $type$ get(int i) { 139 $memtype$ x = SCOPED_MEMORY_ACCESS.get$Memtype$Unaligned(scope(), bb.hb, byteOffset(checkIndex(i)), 140 {#if[boB]?true:false}); 141 return $fromBits$(x); 142 } 143 144#if[streamableType] 145 $type$ getUnchecked(int i) { 146 $memtype$ x = SCOPED_MEMORY_ACCESS.get$Memtype$Unaligned(null, bb.hb, byteOffset(i), 147 {#if[boB]?true:false}); 148 return $fromBits$(x); 149 } 150#end[streamableType] 151 152#end[rw] 153 154 public $Type$Buffer put($type$ x) { 155#if[rw] 156 $memtype$ y = $toBits$(x); 157 SCOPED_MEMORY_ACCESS.put$Memtype$Unaligned(scope(), bb.hb, byteOffset(nextPutIndex()), y, 158 {#if[boB]?true:false}); 159 return this; 160#else[rw] 161 throw new ReadOnlyBufferException(); 162#end[rw] 163 } 164 165 public $Type$Buffer put(int i, $type$ x) { 166#if[rw] 167 $memtype$ y = $toBits$(x); 168 SCOPED_MEMORY_ACCESS.put$Memtype$Unaligned(scope(), bb.hb, byteOffset(checkIndex(i)), y, 169 {#if[boB]?true:false}); 170 return this; 171#else[rw] 172 throw new ReadOnlyBufferException(); 173#end[rw] 174 } 175 176 public $Type$Buffer compact() { 177#if[rw] 178 int pos = position(); 179 int lim = limit(); 180 assert (pos <= lim); 181 int rem = (pos <= lim ? lim - pos : 0); 182 183 ByteBuffer db = bb.duplicate(); 184 db.limit(ix(lim)); 185 db.position(ix(0)); 186 ByteBuffer sb = db.slice(); 187 sb.position(pos << $LG_BYTES_PER_VALUE$); 188 sb.compact(); 189 position(rem); 190 limit(capacity()); 191 discardMark(); 192 return this; 193#else[rw] 194 throw new ReadOnlyBufferException(); 195#end[rw] 196 } 197 198 public boolean isDirect() { 199 return bb.isDirect(); 200 } 201 202 public boolean isReadOnly() { 203 return {#if[rw]?false:true}; 204 } 205 206#if[char] 207 208 public String toString(int start, int end) { 209 Objects.checkFromToIndex(start, end, limit()); 210 try { 211 int len = end - start; 212 char[] ca = new char[len]; 213 CharBuffer cb = CharBuffer.wrap(ca); 214 CharBuffer db = this.duplicate(); 215 db.position(start); 216 db.limit(end); 217 cb.put(db); 218 return new String(ca); 219 } catch (StringIndexOutOfBoundsException x) { 220 throw new IndexOutOfBoundsException(); 221 } 222 } 223 224 225 // --- Methods to support CharSequence --- 226 227 public CharBuffer subSequence(int start, int end) { 228 int pos = position(); 229 int lim = limit(); 230 assert (pos <= lim); 231 pos = (pos <= lim ? pos : lim); 232 int len = lim - pos; 233 234 Objects.checkFromToIndex(start, end, len); 235 return new ByteBufferAsCharBuffer$RW$$BO$(bb, 236 -1, 237 pos + start, 238 pos + end, 239 capacity(), 240 address, segment); 241 } 242 243#end[char] 244 245 246 public ByteOrder order() { 247#if[boB] 248 return ByteOrder.BIG_ENDIAN; 249#end[boB] 250#if[boL] 251 return ByteOrder.LITTLE_ENDIAN; 252#end[boL] 253 } 254 255#if[char] 256 ByteOrder charRegionOrder() { 257 return order(); 258 } 259#end[char] 260} 261