< prev index next >

src/java.base/share/classes/jdk/internal/jimage/UTF8String.java

Print this page




  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 jdk.internal.jimage;
  27 
  28 import java.nio.charset.Charset;
  29 import java.util.Arrays;
  30 
  31 public final class UTF8String implements CharSequence {
  32 
  33     // Same as StandardCharsets.UTF_8 without loading all of the standard charsets
  34     static final Charset UTF_8 = Charset.forName("UTF-8");
  35 
  36     static final int NOT_FOUND = -1;
  37     static final int HASH_MULTIPLIER = 0x01000193;
  38     static final UTF8String EMPTY_STRING  = new UTF8String("");
  39     static final UTF8String CLASS_STRING  = new UTF8String(".class");





  40 
  41     final byte[] bytes;
  42     final int offset;
  43     final int count;
  44     int hashcode;
  45 
  46     public UTF8String(byte[] bytes, int offset, int count) {
  47         if (offset < 0 || count < 0 || (offset + count) > bytes.length) {
  48             throw new IndexOutOfBoundsException("offset/count out of range");
  49         }
  50         this.bytes = bytes;
  51         this.offset = offset;
  52         this.count = count;
  53         this.hashcode = -1;
  54     }
  55 
  56     public UTF8String(byte[] bytes, int offset) {
  57         this(bytes, offset, bytes.length - offset);
  58     }
  59 


 143             if (byteAt(i) == ch) {
 144                 return i;
 145             }
 146         }
 147 
 148         return NOT_FOUND;
 149     }
 150 
 151     void writeTo(ImageStream buffer) {
 152         buffer.put(bytes, offset, count);
 153     }
 154 
 155     static int hashCode(int seed, byte[] bytes, int offset, int count) {
 156         for (int i = offset, limit = offset + count; i < limit; i++) {
 157             seed = (seed * HASH_MULTIPLIER) ^ (bytes[i] & 0xFF);
 158         }
 159 
 160         return seed & 0x7FFFFFFF;
 161     }
 162 
 163     int hashCode(int base) {
 164         return hashCode(base, bytes, offset, count);
 165     }
 166 
 167     @Override
 168     public int hashCode() {
 169         if (hashcode < 0) {
 170             hashcode = hashCode(HASH_MULTIPLIER, bytes, offset, count);
 171         }
 172 
 173         return hashcode;
 174     }
 175 
 176     @Override
 177     public boolean equals(Object obj) {
 178         if (obj == null) {
 179             return false;
 180         }
 181 
 182         if (getClass() != obj.getClass()) {
 183             return false;
 184         }
 185 
 186         return equals(this, (UTF8String)obj);
 187     }
 188 
 189     private static boolean equals(UTF8String a, UTF8String b) {
 190         if (a == b) {
 191             return true;
 192         }
 193 
 194         int count = a.count;
 195 
 196         if (count != b.count) {
 197             return false;
 198         }
 199 
 200         byte[] aBytes = a.bytes;
 201         byte[] bBytes = b.bytes;
 202         int aOffset = a.offset;
 203         int bOffset = b.offset;
 204 
 205         for (int i = 0; i < count; i++) {
 206             if (aBytes[aOffset + i] != bBytes[bOffset + i]) {
 207                 return false;
 208             }
 209         }
 210 
 211         return true;
 212     }
 213 




 214     byte[] getBytes() {
 215         if (offset != 0 || bytes.length != count) {
 216             return Arrays.copyOfRange(bytes, offset, offset + count);
 217         }
 218 
 219         return bytes;
 220     }
 221 
 222     private static byte[] stringToBytes(String string) {
 223         return string.getBytes(UTF_8);
 224     }
 225 
 226     @Override
 227     public String toString() {
 228         return new String(bytes, offset, count, UTF_8);
 229     }
 230 
 231     @Override
 232     public char charAt(int index) {
 233         int ch = byteAt(index);
 234 
 235         return (ch & 0x80) != 0 ? (char)ch : '\0';
 236     }
 237 
 238     @Override
 239     public CharSequence subSequence(int start, int end) {
 240         return (CharSequence)substring(start, end - start);
 241     }
 242 
 243     static UTF8String match(UTF8String a, UTF8String b) {
 244         int aCount = a.count;
 245         int bCount = b.count;
 246 
 247         if (aCount < bCount) {
 248             return null;
 249         }
 250 
 251         byte[] aBytes = a.bytes;
 252         byte[] bBytes = b.bytes;
 253         int aOffset = a.offset;
 254         int bOffset = b.offset;
 255 
 256         for (int i = 0; i < bCount; i++) {
 257             if (aBytes[aOffset + i] != bBytes[bOffset + i]) {
 258                 return null;
 259             }
 260         }
 261 
 262         return new UTF8String(aBytes, aOffset + bCount, aCount - bCount);
 263     }
 264 }


  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 jdk.internal.jimage;
  27 
  28 import java.nio.charset.Charset;
  29 import java.util.Arrays;
  30 
  31 public final class UTF8String implements CharSequence {

  32     // Same as StandardCharsets.UTF_8 without loading all of the standard charsets
  33     static final Charset UTF_8 = Charset.forName("UTF-8");
  34 
  35     static final int NOT_FOUND = -1;
  36     static final int HASH_MULTIPLIER = 0x01000193;
  37     static final UTF8String EMPTY_STRING = new UTF8String("");
  38     static final UTF8String SLASH_STRING = new UTF8String("/");
  39     static final UTF8String DOT_STRING = new UTF8String(".");
  40 
  41     // TODO This strings are implementation specific and should be defined elsewhere.
  42     static final UTF8String MODULES_STRING = new UTF8String("/modules");
  43     static final UTF8String PACKAGES_STRING = new UTF8String("/packages");
  44 
  45     final byte[] bytes;
  46     final int offset;
  47     final int count;
  48     int hashcode;
  49 
  50     public UTF8String(byte[] bytes, int offset, int count) {
  51         if (offset < 0 || count < 0 || (offset + count) > bytes.length) {
  52             throw new IndexOutOfBoundsException("offset/count out of range");
  53         }
  54         this.bytes = bytes;
  55         this.offset = offset;
  56         this.count = count;
  57         this.hashcode = -1;
  58     }
  59 
  60     public UTF8String(byte[] bytes, int offset) {
  61         this(bytes, offset, bytes.length - offset);
  62     }
  63 


 147             if (byteAt(i) == ch) {
 148                 return i;
 149             }
 150         }
 151 
 152         return NOT_FOUND;
 153     }
 154 
 155     void writeTo(ImageStream buffer) {
 156         buffer.put(bytes, offset, count);
 157     }
 158 
 159     static int hashCode(int seed, byte[] bytes, int offset, int count) {
 160         for (int i = offset, limit = offset + count; i < limit; i++) {
 161             seed = (seed * HASH_MULTIPLIER) ^ (bytes[i] & 0xFF);
 162         }
 163 
 164         return seed & 0x7FFFFFFF;
 165     }
 166 
 167     int hashCode(int seed) {
 168         return hashCode(seed, bytes, offset, count);
 169     }
 170 
 171     @Override
 172     public int hashCode() {
 173         if (hashcode < 0) {
 174             hashcode = hashCode(HASH_MULTIPLIER, bytes, offset, count);
 175         }
 176 
 177         return hashcode;
 178     }
 179 
 180     @Override
 181     public boolean equals(Object obj) {
 182         if (obj == null) {
 183             return false;
 184         }
 185 
 186         if (getClass() != obj.getClass()) {
 187             return false;
 188         }
 189 
 190         return equals(this, (UTF8String)obj);
 191     }
 192 
 193     public static boolean equals(UTF8String a, UTF8String b) {
 194         if (a == b) {
 195             return true;
 196         }
 197 
 198         int count = a.count;
 199 
 200         if (count != b.count) {
 201             return false;
 202         }
 203 
 204         byte[] aBytes = a.bytes;
 205         byte[] bBytes = b.bytes;
 206         int aOffset = a.offset;
 207         int bOffset = b.offset;
 208 
 209         for (int i = 0; i < count; i++) {
 210             if (aBytes[aOffset + i] != bBytes[bOffset + i]) {
 211                 return false;
 212             }
 213         }
 214 
 215         return true;
 216     }
 217 
 218     public byte[] getBytesCopy() {
 219         return Arrays.copyOfRange(bytes, offset, offset + count);
 220     }
 221 
 222     byte[] getBytes() {
 223         if (offset != 0 || bytes.length != count) {
 224             return Arrays.copyOfRange(bytes, offset, offset + count);
 225         }
 226 
 227         return bytes;
 228     }
 229 
 230     private static byte[] stringToBytes(String string) {
 231         return string.getBytes(UTF_8);
 232     }
 233 
 234     @Override
 235     public String toString() {
 236         return new String(bytes, offset, count, UTF_8);
 237     }
 238 
 239     @Override
 240     public char charAt(int index) {
 241         int ch = byteAt(index);
 242 
 243         return (ch & 0x80) == 0 ? (char)ch : '\0';
 244     }
 245 
 246     @Override
 247     public CharSequence subSequence(int start, int end) {
 248         return (CharSequence)substring(start, end - start);
 249     }






















 250 }
< prev index next >