emul/src/main/java/java/lang/String.java
changeset 241 2177242dff06
parent 240 4e88a33d7972
child 249 001389026dbf
     1.1 --- a/emul/src/main/java/java/lang/String.java	Sun Dec 02 23:10:51 2012 +0100
     1.2 +++ b/emul/src/main/java/java/lang/String.java	Mon Dec 03 00:03:40 2012 +0100
     1.3 @@ -109,18 +109,6 @@
     1.4      implements java.io.Serializable, Comparable<String>, CharSequence
     1.5  {
     1.6      @JavaScriptOnly
     1.7 -    /** The value is used for character storage. */
     1.8 -    private final char value[];
     1.9 -
    1.10 -    @JavaScriptOnly
    1.11 -    /** The offset is the first index of the storage that is used. */
    1.12 -    private final int offset;
    1.13 -
    1.14 -    @JavaScriptOnly
    1.15 -    /** The count is the number of characters in the String. */
    1.16 -    private final int count;
    1.17 -
    1.18 -    @JavaScriptOnly
    1.19      /** Cache the hash code for the string */
    1.20      private int hash; // Default to 0
    1.21      
    1.22 @@ -158,11 +146,8 @@
    1.23       * an empty character sequence.  Note that use of this constructor is
    1.24       * unnecessary since Strings are immutable.
    1.25       */
    1.26 -    @JavaScriptBody(args = "self", body = "self.fld_r = '';")
    1.27      public String() {
    1.28 -        this.offset = 0;
    1.29 -        this.count = 0;
    1.30 -        this.value = new char[0];
    1.31 +        this.r = "";
    1.32      }
    1.33  
    1.34      /**
    1.35 @@ -175,25 +160,8 @@
    1.36       * @param  original
    1.37       *         A {@code String}
    1.38       */
    1.39 -    @JavaScriptBody(args = {"self", "original"}, body = "self.fld_r = original.toString();")
    1.40      public String(String original) {
    1.41 -        int size = original.count;
    1.42 -        char[] originalValue = original.value;
    1.43 -        char[] v;
    1.44 -        if (originalValue.length > size) {
    1.45 -            // The array representing the String is bigger than the new
    1.46 -            // String itself.  Perhaps this constructor is being called
    1.47 -            // in order to trim the baggage, so make a copy of the array.
    1.48 -            int off = original.offset;
    1.49 -            v = AbstractStringBuilder.copyOfRange(originalValue, off, off+size);
    1.50 -        } else {
    1.51 -            // The array representing the String is the same
    1.52 -            // size as the String, so no point in making a copy.
    1.53 -            v = originalValue;
    1.54 -        }
    1.55 -        this.offset = 0;
    1.56 -        this.count = size;
    1.57 -        this.value = v;
    1.58 +        this.r = original.toString();
    1.59      }
    1.60  
    1.61      /**
    1.62 @@ -212,10 +180,6 @@
    1.63        + "self.fld_r = charArr.join('');\n"
    1.64      )
    1.65      public String(char value[]) {
    1.66 -        int size = value.length;
    1.67 -        this.offset = 0;
    1.68 -        this.count = size;
    1.69 -        this.value = AbstractStringBuilder.copyOf(value, size);
    1.70      }
    1.71  
    1.72      /**
    1.73 @@ -247,19 +211,6 @@
    1.74          "self.fld_r = charArr.slice(off, up).join(\"\");\n"
    1.75      )
    1.76      public String(char value[], int offset, int count) {
    1.77 -        if (offset < 0) {
    1.78 -            throw new StringIndexOutOfBoundsException(offset);
    1.79 -        }
    1.80 -        if (count < 0) {
    1.81 -            throw new StringIndexOutOfBoundsException(count);
    1.82 -        }
    1.83 -        // Note: offset or count might be near -1>>>1.
    1.84 -        if (offset > value.length - count) {
    1.85 -            throw new StringIndexOutOfBoundsException(offset + count);
    1.86 -        }
    1.87 -        this.offset = 0;
    1.88 -        this.count = count;
    1.89 -        this.value = AbstractStringBuilder.copyOfRange(value, offset, offset+count);
    1.90      }
    1.91  
    1.92      /**
    1.93 @@ -326,9 +277,7 @@
    1.94                  Character.toSurrogates(c, v, j++);
    1.95          }
    1.96  
    1.97 -        this.value  = v;
    1.98 -        this.count  = n;
    1.99 -        this.offset = 0;
   1.100 +        this.r = new String(v, 0, n);
   1.101      }
   1.102  
   1.103      /**
   1.104 @@ -385,9 +334,7 @@
   1.105                  value[i] = (char) (hibyte | (ascii[i + offset] & 0xff));
   1.106              }
   1.107          }
   1.108 -        this.offset = 0;
   1.109 -        this.count = count;
   1.110 -        this.value = value;
   1.111 +        this.r = new String(value, 0, count);
   1.112      }
   1.113  
   1.114      /**
   1.115 @@ -612,9 +559,7 @@
   1.116          for (int i = 0; i < length; i++) {
   1.117              v[i] = (char)bytes[offset++];
   1.118          }
   1.119 -        this.offset = 0;
   1.120 -        this.count = v.length;
   1.121 -        this.value = v;
   1.122 +        this.r = new String(v, 0, v.length);
   1.123      }
   1.124  
   1.125      /**
   1.126 @@ -647,10 +592,7 @@
   1.127       *         A {@code StringBuffer}
   1.128       */
   1.129      public String(StringBuffer buffer) {
   1.130 -        r = buffer.toString();
   1.131 -        this.value = null;
   1.132 -        this.count = 0;
   1.133 -        this.offset = -1;
   1.134 +        this.r = buffer.toString();
   1.135      }
   1.136  
   1.137      /**
   1.138 @@ -669,10 +611,7 @@
   1.139       * @since  1.5
   1.140       */
   1.141      public String(StringBuilder builder) {
   1.142 -        r = builder.toString();
   1.143 -        this.value = null;
   1.144 -        this.count = 0;
   1.145 -        this.offset = -1;
   1.146 +        this.r = builder.toString();
   1.147      }
   1.148  
   1.149      /**
   1.150 @@ -685,7 +624,7 @@
   1.151       */
   1.152      @JavaScriptBody(args = "self", body = "return self.toString().length;")
   1.153      public int length() {
   1.154 -        return count;
   1.155 +        throw new UnsupportedOperationException();
   1.156      }
   1.157  
   1.158      /**
   1.159 @@ -698,7 +637,7 @@
   1.160       */
   1.161      @JavaScriptBody(args = "self", body="return self.toString().length === 0;")
   1.162      public boolean isEmpty() {
   1.163 -        return count == 0;
   1.164 +        return length() == 0;
   1.165      }
   1.166  
   1.167      /**
   1.168 @@ -723,10 +662,7 @@
   1.169          body = "return self.toString().charCodeAt(index);"
   1.170      )
   1.171      public char charAt(int index) {
   1.172 -        if ((index < 0) || (index >= count)) {
   1.173 -            throw new StringIndexOutOfBoundsException(index);
   1.174 -        }
   1.175 -        return value[index + offset];
   1.176 +        throw new UnsupportedOperationException();
   1.177      }
   1.178  
   1.179      /**
   1.180 @@ -752,10 +688,10 @@
   1.181       * @since      1.5
   1.182       */
   1.183      public int codePointAt(int index) {
   1.184 -        if ((index < 0) || (index >= count)) {
   1.185 +        if ((index < 0) || (index >= length())) {
   1.186              throw new StringIndexOutOfBoundsException(index);
   1.187          }
   1.188 -        return Character.codePointAtImpl(value, offset + index, offset + count);
   1.189 +        return Character.codePointAtImpl(toCharArray(), offset() + index, offset() + length());
   1.190      }
   1.191  
   1.192      /**
   1.193 @@ -782,10 +718,10 @@
   1.194       */
   1.195      public int codePointBefore(int index) {
   1.196          int i = index - 1;
   1.197 -        if ((i < 0) || (i >= count)) {
   1.198 +        if ((i < 0) || (i >= length())) {
   1.199              throw new StringIndexOutOfBoundsException(index);
   1.200          }
   1.201 -        return Character.codePointBeforeImpl(value, offset + index, offset);
   1.202 +        return Character.codePointBeforeImpl(toCharArray(), offset() + index, offset());
   1.203      }
   1.204  
   1.205      /**
   1.206 @@ -810,10 +746,10 @@
   1.207       * @since  1.5
   1.208       */
   1.209      public int codePointCount(int beginIndex, int endIndex) {
   1.210 -        if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
   1.211 +        if (beginIndex < 0 || endIndex > length() || beginIndex > endIndex) {
   1.212              throw new IndexOutOfBoundsException();
   1.213          }
   1.214 -        return Character.codePointCountImpl(value, offset+beginIndex, endIndex-beginIndex);
   1.215 +        return Character.codePointCountImpl(toCharArray(), offset()+beginIndex, endIndex-beginIndex);
   1.216      }
   1.217  
   1.218      /**
   1.219 @@ -837,11 +773,11 @@
   1.220       * @since 1.5
   1.221       */
   1.222      public int offsetByCodePoints(int index, int codePointOffset) {
   1.223 -        if (index < 0 || index > count) {
   1.224 +        if (index < 0 || index > length()) {
   1.225              throw new IndexOutOfBoundsException();
   1.226          }
   1.227 -        return Character.offsetByCodePointsImpl(value, offset, count,
   1.228 -                                                offset+index, codePointOffset) - offset;
   1.229 +        return Character.offsetByCodePointsImpl(toCharArray(), offset(), length(),
   1.230 +                                                offset()+index, codePointOffset) - offset();
   1.231      }
   1.232  
   1.233      /**
   1.234 @@ -855,7 +791,7 @@
   1.235          "}"
   1.236      )
   1.237      void getChars(char dst[], int dstBegin) {
   1.238 -        AbstractStringBuilder.arraycopy(value, offset, dst, dstBegin, count);
   1.239 +        AbstractStringBuilder.arraycopy(toCharArray(), offset(), dst, dstBegin, length());
   1.240      }
   1.241  
   1.242      /**
   1.243 @@ -898,13 +834,13 @@
   1.244          if (srcBegin < 0) {
   1.245              throw new StringIndexOutOfBoundsException(srcBegin);
   1.246          }
   1.247 -        if (srcEnd > count) {
   1.248 +        if (srcEnd > length()) {
   1.249              throw new StringIndexOutOfBoundsException(srcEnd);
   1.250          }
   1.251          if (srcBegin > srcEnd) {
   1.252              throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
   1.253          }
   1.254 -        AbstractStringBuilder.arraycopy(value, offset + srcBegin, dst, dstBegin,
   1.255 +        AbstractStringBuilder.arraycopy(toCharArray(), offset() + srcBegin, dst, dstBegin,
   1.256               srcEnd - srcBegin);
   1.257      }
   1.258  
   1.259 @@ -956,16 +892,16 @@
   1.260          if (srcBegin < 0) {
   1.261              throw new StringIndexOutOfBoundsException(srcBegin);
   1.262          }
   1.263 -        if (srcEnd > count) {
   1.264 +        if (srcEnd > length()) {
   1.265              throw new StringIndexOutOfBoundsException(srcEnd);
   1.266          }
   1.267          if (srcBegin > srcEnd) {
   1.268              throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
   1.269          }
   1.270          int j = dstBegin;
   1.271 -        int n = offset + srcEnd;
   1.272 -        int i = offset + srcBegin;
   1.273 -        char[] val = value;   /* avoid getfield opcode */
   1.274 +        int n = offset() + srcEnd;
   1.275 +        int i = offset() + srcBegin;
   1.276 +        char[] val = toCharArray();   /* avoid getfield opcode */
   1.277  
   1.278          while (i < n) {
   1.279              dst[j++] = (byte)val[i++];
   1.280 @@ -1071,12 +1007,12 @@
   1.281          }
   1.282          if (anObject instanceof String) {
   1.283              String anotherString = (String)anObject;
   1.284 -            int n = count;
   1.285 -            if (n == anotherString.count) {
   1.286 -                char v1[] = value;
   1.287 -                char v2[] = anotherString.value;
   1.288 -                int i = offset;
   1.289 -                int j = anotherString.offset;
   1.290 +            int n = length();
   1.291 +            if (n == anotherString.length()) {
   1.292 +                char v1[] = toCharArray();
   1.293 +                char v2[] = anotherString.toCharArray();
   1.294 +                int i = offset();
   1.295 +                int j = anotherString.offset();
   1.296                  while (n-- != 0) {
   1.297                      if (v1[i++] != v2[j++])
   1.298                          return false;
   1.299 @@ -1122,15 +1058,15 @@
   1.300       * @since  1.5
   1.301       */
   1.302      public boolean contentEquals(CharSequence cs) {
   1.303 -        if (count != cs.length())
   1.304 +        if (length() != cs.length())
   1.305              return false;
   1.306          // Argument is a StringBuffer, StringBuilder
   1.307          if (cs instanceof AbstractStringBuilder) {
   1.308 -            char v1[] = value;
   1.309 +            char v1[] = toCharArray();
   1.310              char v2[] = ((AbstractStringBuilder)cs).getValue();
   1.311 -            int i = offset;
   1.312 +            int i = offset();
   1.313              int j = 0;
   1.314 -            int n = count;
   1.315 +            int n = length();
   1.316              while (n-- != 0) {
   1.317                  if (v1[i++] != v2[j++])
   1.318                      return false;
   1.319 @@ -1141,10 +1077,10 @@
   1.320          if (cs.equals(this))
   1.321              return true;
   1.322          // Argument is a generic CharSequence
   1.323 -        char v1[] = value;
   1.324 -        int i = offset;
   1.325 +        char v1[] = toCharArray();
   1.326 +        int i = offset();
   1.327          int j = 0;
   1.328 -        int n = count;
   1.329 +        int n = length();
   1.330          while (n-- != 0) {
   1.331              if (v1[i++] != cs.charAt(j++))
   1.332                  return false;
   1.333 @@ -1182,8 +1118,8 @@
   1.334       */
   1.335      public boolean equalsIgnoreCase(String anotherString) {
   1.336          return (this == anotherString) ? true :
   1.337 -               (anotherString != null) && (anotherString.count == count) &&
   1.338 -               regionMatches(true, 0, anotherString, 0, count);
   1.339 +               (anotherString != null) && (anotherString.length() == length()) &&
   1.340 +               regionMatches(true, 0, anotherString, 0, length());
   1.341      }
   1.342  
   1.343      /**
   1.344 @@ -1228,13 +1164,13 @@
   1.345       *          lexicographically greater than the string argument.
   1.346       */
   1.347      public int compareTo(String anotherString) {
   1.348 -        int len1 = count;
   1.349 -        int len2 = anotherString.count;
   1.350 +        int len1 = length();
   1.351 +        int len2 = anotherString.length();
   1.352          int n = Math.min(len1, len2);
   1.353 -        char v1[] = value;
   1.354 -        char v2[] = anotherString.value;
   1.355 -        int i = offset;
   1.356 -        int j = anotherString.offset;
   1.357 +        char v1[] = toCharArray();
   1.358 +        char v2[] = anotherString.toCharArray();
   1.359 +        int i = offset();
   1.360 +        int j = anotherString.offset();
   1.361  
   1.362          if (i == j) {
   1.363              int k = i;
   1.364 @@ -1273,6 +1209,11 @@
   1.365       */
   1.366      public static final Comparator<String> CASE_INSENSITIVE_ORDER
   1.367                                           = new CaseInsensitiveComparator();
   1.368 +
   1.369 +    private static int offset() {
   1.370 +        return 0;
   1.371 +    }
   1.372 +    
   1.373      private static class CaseInsensitiveComparator
   1.374                           implements Comparator<String>, java.io.Serializable {
   1.375          // use serialVersionUID from JDK 1.2.2 for interoperability
   1.376 @@ -1359,13 +1300,13 @@
   1.377       */
   1.378      public boolean regionMatches(int toffset, String other, int ooffset,
   1.379                                   int len) {
   1.380 -        char ta[] = value;
   1.381 -        int to = offset + toffset;
   1.382 -        char pa[] = other.value;
   1.383 -        int po = other.offset + ooffset;
   1.384 +        char ta[] = toCharArray();
   1.385 +        int to = offset() + toffset;
   1.386 +        char pa[] = other.toCharArray();
   1.387 +        int po = other.offset() + ooffset;
   1.388          // Note: toffset, ooffset, or len might be near -1>>>1.
   1.389 -        if ((ooffset < 0) || (toffset < 0) || (toffset > (long)count - len)
   1.390 -            || (ooffset > (long)other.count - len)) {
   1.391 +        if ((ooffset < 0) || (toffset < 0) || (toffset > (long)length() - len)
   1.392 +            || (ooffset > (long)other.length() - len)) {
   1.393              return false;
   1.394          }
   1.395          while (len-- > 0) {
   1.396 @@ -1428,13 +1369,13 @@
   1.397       */
   1.398      public boolean regionMatches(boolean ignoreCase, int toffset,
   1.399                             String other, int ooffset, int len) {
   1.400 -        char ta[] = value;
   1.401 -        int to = offset + toffset;
   1.402 -        char pa[] = other.value;
   1.403 -        int po = other.offset + ooffset;
   1.404 +        char ta[] = toCharArray();
   1.405 +        int to = offset() + toffset;
   1.406 +        char pa[] = other.toCharArray();
   1.407 +        int po = other.offset() + ooffset;
   1.408          // Note: toffset, ooffset, or len might be near -1>>>1.
   1.409 -        if ((ooffset < 0) || (toffset < 0) || (toffset > (long)count - len) ||
   1.410 -                (ooffset > (long)other.count - len)) {
   1.411 +        if ((ooffset < 0) || (toffset < 0) || (toffset > (long)length() - len) ||
   1.412 +                (ooffset > (long)other.length() - len)) {
   1.413              return false;
   1.414          }
   1.415          while (len-- > 0) {
   1.416 @@ -1488,13 +1429,13 @@
   1.417          "return self.toString().substring(from, find.length) === find;\n"
   1.418      )
   1.419      public boolean startsWith(String prefix, int toffset) {
   1.420 -        char ta[] = value;
   1.421 -        int to = offset + toffset;
   1.422 -        char pa[] = prefix.value;
   1.423 -        int po = prefix.offset;
   1.424 -        int pc = prefix.count;
   1.425 +        char ta[] = toCharArray();
   1.426 +        int to = offset() + toffset;
   1.427 +        char pa[] = prefix.toCharArray();
   1.428 +        int po = prefix.offset();
   1.429 +        int pc = prefix.length();
   1.430          // Note: toffset might be near -1>>>1.
   1.431 -        if ((toffset < 0) || (toffset > count - pc)) {
   1.432 +        if ((toffset < 0) || (toffset > length() - pc)) {
   1.433              return false;
   1.434          }
   1.435          while (--pc >= 0) {
   1.436 @@ -1534,7 +1475,7 @@
   1.437       *          as determined by the {@link #equals(Object)} method.
   1.438       */
   1.439      public boolean endsWith(String suffix) {
   1.440 -        return startsWith(suffix, count - suffix.count);
   1.441 +        return startsWith(suffix, length() - suffix.length());
   1.442      }
   1.443  
   1.444      /**
   1.445 @@ -1561,10 +1502,10 @@
   1.446      )
   1.447      public int hashCode() {
   1.448          int h = hash;
   1.449 -        if (h == 0 && count > 0) {
   1.450 -            int off = offset;
   1.451 -            char val[] = value;
   1.452 -            int len = count;
   1.453 +        if (h == 0 && length() > 0) {
   1.454 +            int off = offset();
   1.455 +            char val[] = toCharArray();
   1.456 +            int len = length();
   1.457  
   1.458              for (int i = 0; i < len; i++) {
   1.459                  h = 31*h + val[off++];
   1.460 @@ -1648,7 +1589,7 @@
   1.461      public int indexOf(int ch, int fromIndex) {
   1.462          if (fromIndex < 0) {
   1.463              fromIndex = 0;
   1.464 -        } else if (fromIndex >= count) {
   1.465 +        } else if (fromIndex >= length()) {
   1.466              // Note: fromIndex might be near -1>>>1.
   1.467              return -1;
   1.468          }
   1.469 @@ -1656,9 +1597,9 @@
   1.470          if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
   1.471              // handle most cases here (ch is a BMP code point or a
   1.472              // negative value (invalid code point))
   1.473 -            final char[] value = this.value;
   1.474 -            final int offset = this.offset;
   1.475 -            final int max = offset + count;
   1.476 +            final char[] value = this.toCharArray();
   1.477 +            final int offset = this.offset();
   1.478 +            final int max = offset + length();
   1.479              for (int i = offset + fromIndex; i < max ; i++) {
   1.480                  if (value[i] == ch) {
   1.481                      return i - offset;
   1.482 @@ -1675,11 +1616,11 @@
   1.483       */
   1.484      private int indexOfSupplementary(int ch, int fromIndex) {
   1.485          if (Character.isValidCodePoint(ch)) {
   1.486 -            final char[] value = this.value;
   1.487 -            final int offset = this.offset;
   1.488 +            final char[] value = this.toCharArray();
   1.489 +            final int offset = this.offset();
   1.490              final char hi = Character.highSurrogate(ch);
   1.491              final char lo = Character.lowSurrogate(ch);
   1.492 -            final int max = offset + count - 1;
   1.493 +            final int max = offset + length() - 1;
   1.494              for (int i = offset + fromIndex; i < max; i++) {
   1.495                  if (value[i] == hi && value[i+1] == lo) {
   1.496                      return i - offset;
   1.497 @@ -1713,7 +1654,7 @@
   1.498       *          <code>-1</code> if the character does not occur.
   1.499       */
   1.500      public int lastIndexOf(int ch) {
   1.501 -        return lastIndexOf(ch, count - 1);
   1.502 +        return lastIndexOf(ch, length() - 1);
   1.503      }
   1.504  
   1.505      /**
   1.506 @@ -1754,9 +1695,9 @@
   1.507          if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
   1.508              // handle most cases here (ch is a BMP code point or a
   1.509              // negative value (invalid code point))
   1.510 -            final char[] value = this.value;
   1.511 -            final int offset = this.offset;
   1.512 -            int i = offset + Math.min(fromIndex, count - 1);
   1.513 +            final char[] value = this.toCharArray();
   1.514 +            final int offset = this.offset();
   1.515 +            int i = offset + Math.min(fromIndex, length() - 1);
   1.516              for (; i >= offset ; i--) {
   1.517                  if (value[i] == ch) {
   1.518                      return i - offset;
   1.519 @@ -1773,11 +1714,11 @@
   1.520       */
   1.521      private int lastIndexOfSupplementary(int ch, int fromIndex) {
   1.522          if (Character.isValidCodePoint(ch)) {
   1.523 -            final char[] value = this.value;
   1.524 -            final int offset = this.offset;
   1.525 +            final char[] value = this.toCharArray();
   1.526 +            final int offset = this.offset();
   1.527              char hi = Character.highSurrogate(ch);
   1.528              char lo = Character.lowSurrogate(ch);
   1.529 -            int i = offset + Math.min(fromIndex, count - 2);
   1.530 +            int i = offset + Math.min(fromIndex, length() - 2);
   1.531              for (; i >= offset; i--) {
   1.532                  if (value[i] == hi && value[i+1] == lo) {
   1.533                      return i - offset;
   1.534 @@ -1825,8 +1766,7 @@
   1.535          "return self.toString().indexOf(str.toString(), fromIndex) >= 0;"
   1.536      )
   1.537      public int indexOf(String str, int fromIndex) {
   1.538 -        return indexOf(value, offset, count,
   1.539 -                       str.value, str.offset, str.count, fromIndex);
   1.540 +        return indexOf(toCharArray(), offset(), length(), str.toCharArray(), str.offset(), str.length(), fromIndex);
   1.541      }
   1.542  
   1.543      /**
   1.544 @@ -1896,7 +1836,7 @@
   1.545       *          or {@code -1} if there is no such occurrence.
   1.546       */
   1.547      public int lastIndexOf(String str) {
   1.548 -        return lastIndexOf(str, count);
   1.549 +        return lastIndexOf(str, length());
   1.550      }
   1.551  
   1.552      /**
   1.553 @@ -1916,8 +1856,7 @@
   1.554       *          or {@code -1} if there is no such occurrence.
   1.555       */
   1.556      public int lastIndexOf(String str, int fromIndex) {
   1.557 -        return lastIndexOf(value, offset, count,
   1.558 -                           str.value, str.offset, str.count, fromIndex);
   1.559 +        return lastIndexOf(toCharArray(), offset(), length(), str.toCharArray(), str.offset(), str.length(), fromIndex);
   1.560      }
   1.561  
   1.562      /**
   1.563 @@ -1997,7 +1936,7 @@
   1.564       *             length of this <code>String</code> object.
   1.565       */
   1.566      public String substring(int beginIndex) {
   1.567 -        return substring(beginIndex, count);
   1.568 +        return substring(beginIndex, length());
   1.569      }
   1.570  
   1.571      /**
   1.572 @@ -2029,14 +1968,14 @@
   1.573          if (beginIndex < 0) {
   1.574              throw new StringIndexOutOfBoundsException(beginIndex);
   1.575          }
   1.576 -        if (endIndex > count) {
   1.577 +        if (endIndex > length()) {
   1.578              throw new StringIndexOutOfBoundsException(endIndex);
   1.579          }
   1.580          if (beginIndex > endIndex) {
   1.581              throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
   1.582          }
   1.583 -        return ((beginIndex == 0) && (endIndex == count)) ? this :
   1.584 -            new String(value, offset + beginIndex, endIndex - beginIndex);
   1.585 +        return ((beginIndex == 0) && (endIndex == length())) ? this :
   1.586 +            new String(toCharArray(), offset() + beginIndex, endIndex - beginIndex);
   1.587      }
   1.588  
   1.589      /**
   1.590 @@ -2096,10 +2035,10 @@
   1.591          if (otherLen == 0) {
   1.592              return this;
   1.593          }
   1.594 -        char buf[] = new char[count + otherLen];
   1.595 -        getChars(0, count, buf, 0);
   1.596 -        str.getChars(0, otherLen, buf, count);
   1.597 -        return new String(buf, 0, count + otherLen);
   1.598 +        char buf[] = new char[length() + otherLen];
   1.599 +        getChars(0, length(), buf, 0);
   1.600 +        str.getChars(0, otherLen, buf, length());
   1.601 +        return new String(buf, 0, length() + otherLen);
   1.602      }
   1.603  
   1.604      /**
   1.605 @@ -2145,10 +2084,10 @@
   1.606      )
   1.607      public String replace(char oldChar, char newChar) {
   1.608          if (oldChar != newChar) {
   1.609 -            int len = count;
   1.610 +            int len = length();
   1.611              int i = -1;
   1.612 -            char[] val = value; /* avoid getfield opcode */
   1.613 -            int off = offset;   /* avoid getfield opcode */
   1.614 +            char[] val = toCharArray(); /* avoid getfield opcode */
   1.615 +            int off = offset();   /* avoid getfield opcode */
   1.616  
   1.617              while (++i < len) {
   1.618                  if (val[off + i] == oldChar) {
   1.619 @@ -2810,10 +2749,10 @@
   1.620       *          trailing white space.
   1.621       */
   1.622      public String trim() {
   1.623 -        int len = count;
   1.624 +        int len = length();
   1.625          int st = 0;
   1.626 -        int off = offset;      /* avoid getfield opcode */
   1.627 -        char[] val = value;    /* avoid getfield opcode */
   1.628 +        int off = offset();      /* avoid getfield opcode */
   1.629 +        char[] val = toCharArray();    /* avoid getfield opcode */
   1.630  
   1.631          while ((st < len) && (val[off + st] <= ' ')) {
   1.632              st++;
   1.633 @@ -2821,7 +2760,7 @@
   1.634          while ((st < len) && (val[off + len - 1] <= ' ')) {
   1.635              len--;
   1.636          }
   1.637 -        return ((st > 0) || (len < count)) ? substring(st, len) : this;
   1.638 +        return ((st > 0) || (len < length())) ? substring(st, len) : this;
   1.639      }
   1.640  
   1.641      /**
   1.642 @@ -2843,8 +2782,8 @@
   1.643       */
   1.644      @JavaScriptBody(args = "self", body = "return self.toString().split('');")
   1.645      public char[] toCharArray() {
   1.646 -        char result[] = new char[count];
   1.647 -        getChars(0, count, result, 0);
   1.648 +        char result[] = new char[length()];
   1.649 +        getChars(0, length(), result, 0);
   1.650          return result;
   1.651      }
   1.652