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