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