1 /*
2  * Copyright (c) 2000, 2021, 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 package java.nio;
27 
28 import java.util.Objects;
29 
30 // ## If the sequence is a string, use reflection to share its array
31 
32 class StringCharBuffer                                  // package-private
33     extends CharBuffer
34 {
35     CharSequence str;
36 
StringCharBuffer(CharSequence s, int start, int end)37     StringCharBuffer(CharSequence s, int start, int end) { // package-private
38         // Android-removed: Remove unsupported MemorySegmentProxy.
39         // super(-1, start, end, s.length(), null);
40         super(-1, start, end, s.length());
41         int n = s.length();
42         Objects.checkFromToIndex(start, end, n);
43         str = s;
44         this.isReadOnly = true;
45     }
46 
slice()47     public CharBuffer slice() {
48         int pos = this.position();
49         int lim = this.limit();
50         int rem = (pos <= lim ? lim - pos : 0);
51         return new StringCharBuffer(str,
52                                     -1,
53                                     0,
54                                     rem,
55                                     rem,
56                                     offset + pos);
57     }
58 
59     @Override
slice(int index, int length)60     public CharBuffer slice(int index, int length) {
61         Objects.checkFromIndexSize(index, length, limit());
62         return new StringCharBuffer(str,
63                                     -1,
64                                     0,
65                                     length,
66                                     length,
67                                     offset + index);
68     }
69 
StringCharBuffer(CharSequence s, int mark, int pos, int limit, int cap, int offset)70     private StringCharBuffer(CharSequence s,
71                              int mark,
72                              int pos,
73                              int limit,
74                              int cap,
75                              int offset) {
76         // Android-removed: Remove unsupported MemorySegmentProxy.
77         // super(mark, pos, limit, cap, null, offset, null);
78         super(mark, pos, limit, cap, null, offset);
79         str = s;
80         this.isReadOnly = true;
81     }
82 
duplicate()83     public CharBuffer duplicate() {
84         return new StringCharBuffer(str, markValue(),
85                                     position(), limit(), capacity(), offset);
86     }
87 
asReadOnlyBuffer()88     public CharBuffer asReadOnlyBuffer() {
89         return duplicate();
90     }
91 
get()92     public final char get() {
93         return str.charAt(nextGetIndex() + offset);
94     }
95 
get(int index)96     public final char get(int index) {
97         return str.charAt(checkIndex(index) + offset);
98     }
99 
getUnchecked(int index)100     char getUnchecked(int index) {
101         return str.charAt(index + offset);
102     }
103 
104     // ## Override bulk get methods for better performance
105 
put(char c)106     public final CharBuffer put(char c) {
107         throw new ReadOnlyBufferException();
108     }
109 
put(int index, char c)110     public final CharBuffer put(int index, char c) {
111         throw new ReadOnlyBufferException();
112     }
113 
compact()114     public final CharBuffer compact() {
115         throw new ReadOnlyBufferException();
116     }
117 
isReadOnly()118     public final boolean isReadOnly() {
119         return true;
120     }
121 
toString(int start, int end)122     final String toString(int start, int end) {
123         return str.subSequence(start + offset, end + offset).toString();
124     }
125 
subSequence(int start, int end)126     public final CharBuffer subSequence(int start, int end) {
127         try {
128             int pos = position();
129             return new StringCharBuffer(str,
130                                         -1,
131                                         pos + checkIndex(start, pos),
132                                         pos + checkIndex(end, pos),
133                                         capacity(),
134                                         offset);
135         } catch (IllegalArgumentException x) {
136             throw new IndexOutOfBoundsException();
137         }
138     }
139 
isDirect()140     public boolean isDirect() {
141         return false;
142     }
143 
order()144     public ByteOrder order() {
145         return ByteOrder.nativeOrder();
146     }
147 
charRegionOrder()148     ByteOrder charRegionOrder() {
149         return null;
150     }
151 
isAddressable()152     boolean isAddressable() {
153         return false;
154     }
155 
equals(Object ob)156     public boolean equals(Object ob) {
157         if (this == ob)
158             return true;
159         if (!(ob instanceof CharBuffer that))
160             return false;
161         int thisPos = this.position();
162         int thisRem = this.limit() - thisPos;
163         int thatPos = that.position();
164         int thatRem = that.limit() - thatPos;
165         if (thisRem < 0 || thisRem != thatRem)
166             return false;
167         return BufferMismatch.mismatch(this, thisPos,
168                                        that, thatPos,
169                                        thisRem) < 0;
170     }
171 
compareTo(CharBuffer that)172     public int compareTo(CharBuffer that) {
173         int thisPos = this.position();
174         int thisRem = this.limit() - thisPos;
175         int thatPos = that.position();
176         int thatRem = that.limit() - thatPos;
177         int length = Math.min(thisRem, thatRem);
178         if (length < 0)
179             return -1;
180         int i = BufferMismatch.mismatch(this, thisPos,
181                                         that, thatPos,
182                                         length);
183         if (i >= 0) {
184             return Character.compare(this.get(thisPos + i), that.get(thatPos + i));
185         }
186         return thisRem - thatRem;
187     }
188 }
189