1dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski/* 26f07fc6c80a7e85fdfffbc2ac4e15b53cdd04a3eYi Kong * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 3dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * 5dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 6dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 7dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 8dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 9dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 10dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * 11dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 12dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 15dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * accompanied this code). 16dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * 17dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 18dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 19dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * 21dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 23dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski * questions. 24dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski */ 25dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 26dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebskipackage java.nio; 27dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 2846edfaf31e67122f4f67780a83a0bda4dfbbf6a7Shubham Ajmeraimport libcore.io.Memory; 2946edfaf31e67122f4f67780a83a0bda4dfbbf6a7Shubham Ajmera 30622cc37ae444f5cbe18417a0b2da3cc14c85d219Shubham Ajmeraclass ByteBufferAsCharBuffer extends CharBuffer { // package-private 31dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 32dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski protected final ByteBuffer bb; 33dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski protected final int offset; 34622cc37ae444f5cbe18417a0b2da3cc14c85d219Shubham Ajmera private final ByteOrder order; 35dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 36622cc37ae444f5cbe18417a0b2da3cc14c85d219Shubham Ajmera ByteBufferAsCharBuffer(ByteBuffer bb, 37622cc37ae444f5cbe18417a0b2da3cc14c85d219Shubham Ajmera int mark, int pos, int lim, int cap, 38622cc37ae444f5cbe18417a0b2da3cc14c85d219Shubham Ajmera int off, ByteOrder order) { 39dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski super(mark, pos, lim, cap); 40e20e1b55eab0f2163e812a28cf3b3a682df38a1dShubham Ajmera this.bb = bb; 41d80eadc041c833c2808beb823f4edb90ff7410f7Shubham Ajmera this.isReadOnly = bb.isReadOnly; 4210bac63511d71b86bc753215c72bd805d407566aShubham Ajmera // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and 4310bac63511d71b86bc753215c72bd805d407566aShubham Ajmera // HeapByteBuffer. We only have to initialize the field when bb is an instance of 4410bac63511d71b86bc753215c72bd805d407566aShubham Ajmera // DirectByteBuffer. 4510bac63511d71b86bc753215c72bd805d407566aShubham Ajmera // The address field is used by NIOAccess#getBasePointer and GetDirectBufferAddress method 4610bac63511d71b86bc753215c72bd805d407566aShubham Ajmera // in art which return the address of the first usable byte of the underlying memory, i.e, 4710bac63511d71b86bc753215c72bd805d407566aShubham Ajmera // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's 4810bac63511d71b86bc753215c72bd805d407566aShubham Ajmera // position when the method is called from either HeapByteBuffer or DirectByteBuffer. 4910bac63511d71b86bc753215c72bd805d407566aShubham Ajmera if (bb instanceof DirectByteBuffer) { 5010bac63511d71b86bc753215c72bd805d407566aShubham Ajmera this.address = bb.address + off; 5110bac63511d71b86bc753215c72bd805d407566aShubham Ajmera } 52622cc37ae444f5cbe18417a0b2da3cc14c85d219Shubham Ajmera this.order = order; 53dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski offset = off; 54dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 55dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 56dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski public CharBuffer slice() { 57dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski int pos = this.position(); 58dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski int lim = this.limit(); 59dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski assert (pos <= lim); 60dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski int rem = (pos <= lim ? lim - pos : 0); 61dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski int off = (pos << 1) + offset; 62dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski assert (off >= 0); 6346edfaf31e67122f4f67780a83a0bda4dfbbf6a7Shubham Ajmera return new ByteBufferAsCharBuffer(bb, -1, 0, rem, rem, off, order); 64dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 65dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 66dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski public CharBuffer duplicate() { 67622cc37ae444f5cbe18417a0b2da3cc14c85d219Shubham Ajmera return new ByteBufferAsCharBuffer(bb, 68190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera markValue(), 69190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera position(), 70190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera limit(), 71190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera capacity(), 72190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera offset, 73190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera order); 74dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 75dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 76dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski public CharBuffer asReadOnlyBuffer() { 7746edfaf31e67122f4f67780a83a0bda4dfbbf6a7Shubham Ajmera return new ByteBufferAsCharBuffer(bb.asReadOnlyBuffer(), 78190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera markValue(), 79190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera position(), 80190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera limit(), 81190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera capacity(), 82190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera offset, 83190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera order); 84dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 85dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 86dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski protected int ix(int i) { 87dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski return (i << 1) + offset; 88dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 89dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 90dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski public char get() { 9146edfaf31e67122f4f67780a83a0bda4dfbbf6a7Shubham Ajmera return get(nextGetIndex()); 92dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 93dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 94dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski public char get(int i) { 95e20e1b55eab0f2163e812a28cf3b3a682df38a1dShubham Ajmera return bb.getCharUnchecked(ix(checkIndex(i))); 96dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 97dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 98f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera public CharBuffer get(char[] dst, int offset, int length) { 99f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera checkBounds(offset, length, dst.length); 100f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera if (length > remaining()) 101f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera throw new BufferUnderflowException(); 102f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera bb.getUnchecked(ix(position), dst, offset, length); 103f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera position += length; 104f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera return this; 105f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera } 106f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera 1076f07fc6c80a7e85fdfffbc2ac4e15b53cdd04a3eYi Kong char getUnchecked(int i) { 1086f07fc6c80a7e85fdfffbc2ac4e15b53cdd04a3eYi Kong return bb.getCharUnchecked(ix(i)); 1096f07fc6c80a7e85fdfffbc2ac4e15b53cdd04a3eYi Kong } 1106f07fc6c80a7e85fdfffbc2ac4e15b53cdd04a3eYi Kong 111dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski public CharBuffer put(char x) { 11246edfaf31e67122f4f67780a83a0bda4dfbbf6a7Shubham Ajmera put(nextPutIndex(), x); 113dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski return this; 114dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 115dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 116dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski public CharBuffer put(int i, char x) { 117e20e1b55eab0f2163e812a28cf3b3a682df38a1dShubham Ajmera if (isReadOnly) { 118e20e1b55eab0f2163e812a28cf3b3a682df38a1dShubham Ajmera throw new ReadOnlyBufferException(); 119e20e1b55eab0f2163e812a28cf3b3a682df38a1dShubham Ajmera } 120e20e1b55eab0f2163e812a28cf3b3a682df38a1dShubham Ajmera bb.putCharUnchecked(ix(checkIndex(i)), x); 121dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski return this; 122dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 123dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 124f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera public CharBuffer put(char[] src, int offset, int length) { 125f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera checkBounds(offset, length, src.length); 126f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera if (length > remaining()) 127f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera throw new BufferOverflowException(); 128f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera bb.putUnchecked(ix(position), src, offset, length); 129f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera position += length; 130f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera return this; 131f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera } 132f28b09a791e4e5635e4fcdfd1adde27aec0a1ed6Shubham Ajmera 133dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski public CharBuffer compact() { 134d80eadc041c833c2808beb823f4edb90ff7410f7Shubham Ajmera if (isReadOnly) { 135622cc37ae444f5cbe18417a0b2da3cc14c85d219Shubham Ajmera throw new ReadOnlyBufferException(); 136622cc37ae444f5cbe18417a0b2da3cc14c85d219Shubham Ajmera } 137dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski int pos = position(); 138dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski int lim = limit(); 139dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski assert (pos <= lim); 140dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski int rem = (pos <= lim ? lim - pos : 0); 14146edfaf31e67122f4f67780a83a0bda4dfbbf6a7Shubham Ajmera if (!(bb instanceof DirectByteBuffer)) { 14246edfaf31e67122f4f67780a83a0bda4dfbbf6a7Shubham Ajmera System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << 1); 14346edfaf31e67122f4f67780a83a0bda4dfbbf6a7Shubham Ajmera } else { 14446edfaf31e67122f4f67780a83a0bda4dfbbf6a7Shubham Ajmera Memory.memmove(this, ix(0), this, ix(pos), rem << 1); 14546edfaf31e67122f4f67780a83a0bda4dfbbf6a7Shubham Ajmera } 146dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski position(rem); 147dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski limit(capacity()); 148dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski discardMark(); 149dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski return this; 150dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 151dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 152dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski public boolean isDirect() { 153dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski return bb.isDirect(); 154dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 155dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 156dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski public boolean isReadOnly() { 157d80eadc041c833c2808beb823f4edb90ff7410f7Shubham Ajmera return isReadOnly; 158dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 159dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 160dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski public String toString(int start, int end) { 161dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski if ((end > limit()) || (start > end)) 162dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski throw new IndexOutOfBoundsException(); 163dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski try { 164dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski int len = end - start; 165dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski char[] ca = new char[len]; 166dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski CharBuffer cb = CharBuffer.wrap(ca); 167dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski CharBuffer db = this.duplicate(); 168dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski db.position(start); 169dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski db.limit(end); 170dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski cb.put(db); 171dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski return new String(ca); 172dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } catch (StringIndexOutOfBoundsException x) { 173dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski throw new IndexOutOfBoundsException(); 174dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 175dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 176dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 177dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski // --- Methods to support CharSequence --- 178dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 179dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski public CharBuffer subSequence(int start, int end) { 180dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski int pos = position(); 181dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski int lim = limit(); 182dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski assert (pos <= lim); 183dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski pos = (pos <= lim ? pos : lim); 184dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski int len = lim - pos; 185dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 186dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski if ((start < 0) || (end > len) || (start > end)) 187dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski throw new IndexOutOfBoundsException(); 188622cc37ae444f5cbe18417a0b2da3cc14c85d219Shubham Ajmera return new ByteBufferAsCharBuffer(bb, 189190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera -1, 190190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera pos + start, 191190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera pos + end, 192190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera capacity(), 193190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera offset, 194190a49036750b8bb6c979d958ed56aa3fb4f408aShubham Ajmera order); 195dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 196dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski 197dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski public ByteOrder order() { 198622cc37ae444f5cbe18417a0b2da3cc14c85d219Shubham Ajmera return order; 199dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski } 200dee594e6a72064fc994b305487a61f2e2bb250e1Piotr Jastrzebski} 201