1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.nio;
28 
29 /**
30  * A read/write HeapCharBuffer.
31  */
32 
33 class HeapCharBuffer extends CharBuffer {
34 
35     // For speed these fields are actually declared in X-Buffer;
36     // these declarations are here as documentation
37     /*
38 
39       protected final char[] hb;
40       protected final int offset;
41 
42     */
43 
HeapCharBuffer(int cap, int lim)44     HeapCharBuffer(int cap, int lim) {            // package-private
45         this(cap, lim, false);
46     }
47 
HeapCharBuffer(int cap, int lim, boolean isReadOnly)48     HeapCharBuffer(int cap, int lim, boolean isReadOnly) {            // package-private
49         super(-1, 0, lim, cap, new char[cap], 0);
50         this.isReadOnly = isReadOnly;
51     }
52 
HeapCharBuffer(char[] buf, int off, int len)53     HeapCharBuffer(char[] buf, int off, int len) { // package-private
54         this(buf, off, len, false);
55     }
56 
HeapCharBuffer(char[] buf, int off, int len, boolean isReadOnly)57     HeapCharBuffer(char[] buf, int off, int len, boolean isReadOnly) { // package-private
58         super(-1, off, off + len, buf.length, buf, 0);
59         this.isReadOnly = isReadOnly;
60     }
61 
HeapCharBuffer(char[] buf, int mark, int pos, int lim, int cap, int off)62     protected HeapCharBuffer(char[] buf,
63                              int mark, int pos, int lim, int cap,
64                              int off) {
65         this(buf, mark, pos, lim, cap, off, false);
66     }
67 
HeapCharBuffer(char[] buf, int mark, int pos, int lim, int cap, int off, boolean isReadOnly)68     protected HeapCharBuffer(char[] buf,
69                              int mark, int pos, int lim, int cap,
70                              int off, boolean isReadOnly) {
71         super(mark, pos, lim, cap, buf, off);
72         this.isReadOnly = isReadOnly;
73     }
74 
slice()75     public CharBuffer slice() {
76         return new HeapCharBuffer(hb,
77                 -1,
78                 0,
79                 this.remaining(),
80                 this.remaining(),
81                 this.position() + offset,
82                 isReadOnly);
83     }
84 
duplicate()85     public CharBuffer duplicate() {
86         return new HeapCharBuffer(hb,
87                 this.markValue(),
88                 this.position(),
89                 this.limit(),
90                 this.capacity(),
91                 offset,
92                 isReadOnly);
93     }
94 
asReadOnlyBuffer()95     public CharBuffer asReadOnlyBuffer() {
96 
97         return new HeapCharBuffer(hb,
98                 this.markValue(),
99                 this.position(),
100                 this.limit(),
101                 this.capacity(),
102                 offset,
103                 true);
104     }
105 
ix(int i)106     protected int ix(int i) {
107         return i + offset;
108     }
109 
get()110     public char get() {
111         return hb[ix(nextGetIndex())];
112     }
113 
get(int i)114     public char get(int i) {
115         return hb[ix(checkIndex(i))];
116     }
117 
getUnchecked(int i)118     char getUnchecked(int i) {
119         return hb[ix(i)];
120     }
121 
get(char[] dst, int offset, int length)122     public CharBuffer get(char[] dst, int offset, int length) {
123         checkBounds(offset, length, dst.length);
124         if (length > remaining())
125             throw new BufferUnderflowException();
126         System.arraycopy(hb, ix(position()), dst, offset, length);
127         position(position() + length);
128         return this;
129     }
130 
isDirect()131     public boolean isDirect() {
132         return false;
133     }
134 
isReadOnly()135     public boolean isReadOnly() {
136         return isReadOnly;
137     }
138 
put(char x)139     public CharBuffer put(char x) {
140         if (isReadOnly) {
141             throw new ReadOnlyBufferException();
142         }
143         hb[ix(nextPutIndex())] = x;
144         return this;
145     }
146 
put(int i, char x)147     public CharBuffer put(int i, char x) {
148         if (isReadOnly) {
149             throw new ReadOnlyBufferException();
150         }
151         hb[ix(checkIndex(i))] = x;
152         return this;
153     }
154 
put(char[] src, int offset, int length)155     public CharBuffer put(char[] src, int offset, int length) {
156         if (isReadOnly) {
157             throw new ReadOnlyBufferException();
158         }
159         checkBounds(offset, length, src.length);
160         if (length > remaining())
161             throw new BufferOverflowException();
162         System.arraycopy(src, offset, hb, ix(position()), length);
163         position(position() + length);
164         return this;
165     }
166 
put(CharBuffer src)167     public CharBuffer put(CharBuffer src) {
168         if (src == this) {
169             throw new IllegalArgumentException();
170         }
171         if (isReadOnly) {
172             throw new ReadOnlyBufferException();
173         }
174         if (src instanceof HeapCharBuffer) {
175             HeapCharBuffer sb = (HeapCharBuffer) src;
176             int n = sb.remaining();
177             if (n > remaining())
178                 throw new BufferOverflowException();
179             System.arraycopy(sb.hb, sb.ix(sb.position()),
180                     hb, ix(position()), n);
181             sb.position(sb.position() + n);
182             position(position() + n);
183         } else if (src.isDirect()) {
184             int n = src.remaining();
185             if (n > remaining())
186                 throw new BufferOverflowException();
187             src.get(hb, ix(position()), n);
188             position(position() + n);
189         } else {
190             super.put(src);
191         }
192         return this;
193     }
194 
compact()195     public CharBuffer compact() {
196         if (isReadOnly) {
197             throw new ReadOnlyBufferException();
198         }
199         System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
200         position(remaining());
201         limit(capacity());
202         discardMark();
203         return this;
204     }
205 
toString(int start, int end)206     String toString(int start, int end) {               // package-private
207         try {
208             return new String(hb, start + offset, end - start);
209         } catch (StringIndexOutOfBoundsException x) {
210             throw new IndexOutOfBoundsException();
211         }
212     }
213 
subSequence(int start, int end)214     public CharBuffer subSequence(int start, int end) {
215         if ((start < 0)
216                 || (end > length())
217                 || (start > end))
218             throw new IndexOutOfBoundsException();
219         int pos = position();
220         return new HeapCharBuffer(hb,
221                 -1,
222                 pos + start,
223                 pos + end,
224                 capacity(),
225                 offset, isReadOnly);
226     }
227 
order()228     public ByteOrder order() {
229         return ByteOrder.nativeOrder();
230     }
231 }
232