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.misc.Unsafe; 32 33 class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private 34 extends {#if[ro]?ByteBufferAs}$Type$Buffer{#if[ro]?$BO$} 35 { 36 37 #if[rw] 38 39 protected final ByteBuffer bb; 40 41 #end[rw] 42 43 ByteBufferAs$Type$Buffer$RW$$BO$(ByteBuffer bb) { // package-private 44 #if[rw] 45 super(-1, 0, 46 bb.remaining() >> $LG_BYTES_PER_VALUE$, 47 bb.remaining() >> $LG_BYTES_PER_VALUE$); 48 this.bb = bb; 49 // enforce limit == capacity 50 int cap = this.capacity(); 51 this.limit(cap); 52 int pos = this.position(); 53 assert (pos <= cap); 54 address = bb.address; 55 #else[rw] 56 super(bb); 57 #end[rw] 58 } 59 60 ByteBufferAs$Type$Buffer$RW$$BO$(ByteBuffer bb, 61 int mark, int pos, int lim, int cap, 62 long addr) 63 { 64 #if[rw] 65 super(mark, pos, lim, cap); 66 this.bb = bb; 67 address = addr; 68 assert address >= bb.address; 69 #else[rw] 70 super(bb, mark, pos, lim, cap, addr); 71 #end[rw] 72 } 73 74 @Override 75 Object base() { 76 return bb.hb; 77 } 78 79 public $Type$Buffer slice() { 80 int pos = this.position(); 81 int lim = this.limit(); 82 assert (pos <= lim); 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); 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)); 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); 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); 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 = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(nextGetIndex()), 134 {#if[boB]?true:false}); 135 return $fromBits$(x); 136 } 137 138 public $type$ get(int i) { 139 $memtype$ x = UNSAFE.get$Memtype$Unaligned(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 = UNSAFE.get$Memtype$Unaligned(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 UNSAFE.put$Memtype$Unaligned(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 UNSAFE.put$Memtype$Unaligned(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 if ((end > limit()) || (start > end)) 210 throw new IndexOutOfBoundsException(); 211 try { 212 int len = end - start; 213 char[] ca = new char[len]; 214 CharBuffer cb = CharBuffer.wrap(ca); 215 CharBuffer db = this.duplicate(); 216 db.position(start); 217 db.limit(end); 218 cb.put(db); 219 return new String(ca); 220 } catch (StringIndexOutOfBoundsException x) { 221 throw new IndexOutOfBoundsException(); 222 } 223 } 224 225 226 // --- Methods to support CharSequence --- 227 228 public CharBuffer subSequence(int start, int end) { 229 int pos = position(); 230 int lim = limit(); 231 assert (pos <= lim); 232 pos = (pos <= lim ? pos : lim); 233 int len = lim - pos; 234 235 if ((start < 0) || (end > len) || (start > end)) 236 throw new IndexOutOfBoundsException(); 237 return new ByteBufferAsCharBuffer$RW$$BO$(bb, 238 -1, 239 pos + start, 240 pos + end, 241 capacity(), 242 address); 243 } 244 245 #end[char] 246 247 248 public ByteOrder order() { 249 #if[boB] 250 return ByteOrder.BIG_ENDIAN; 251 #end[boB] 252 #if[boL] 253 return ByteOrder.LITTLE_ENDIAN; 254 #end[boL] 255 } 256 257 #if[char] 258 ByteOrder charRegionOrder() { 259 return order(); 260 } 261 #end[char] 262 }