ICU-3750 allow negative move amounts in UTF16.moveCodePointOffset()
X-SVN-Rev: 16089
This commit is contained in:
parent
eae23a295d
commit
25b3f18b38
@ -558,118 +558,235 @@ public final class UTF16Test extends TestFmwk
|
||||
/*
|
||||
* Testing moveCodePointOffset APIs
|
||||
*/
|
||||
|
||||
//
|
||||
// checkMoveCodePointOffset
|
||||
// Run a single test case through each of the moveCodePointOffset() functions.
|
||||
// Parameters -
|
||||
// s The string to work in.
|
||||
// startIdx The starting position within the string.
|
||||
// amount The number of code points to move.
|
||||
// expectedResult The string index after the move, or -1 if the
|
||||
// function should throw an exception.
|
||||
private void checkMoveCodePointOffset(String s, int startIdx, int amount, int expectedResult) {
|
||||
// Test with the String flavor of moveCodePointOffset
|
||||
try {
|
||||
int result = UTF16.moveCodePointOffset(s, startIdx, amount);
|
||||
if (result != expectedResult) {
|
||||
errln("FAIL: UTF16.moveCodePointOffset(String \"" + s + "\", " + startIdx + ", " + amount + ")" +
|
||||
" returned " + result + ", expected result was " +
|
||||
(expectedResult==-1 ? "exception" : Integer.toString(expectedResult)));
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfBoundsException e) {
|
||||
if (expectedResult != -1) {
|
||||
errln("FAIL: UTF16.moveCodePointOffset(String \"" + s + "\", " + startIdx + ", " + amount + ")" +
|
||||
" returned exception" + ", expected result was " + expectedResult);
|
||||
}
|
||||
}
|
||||
|
||||
// Test with the StringBuffer flavor of moveCodePointOffset
|
||||
StringBuffer sb = new StringBuffer(s);
|
||||
try {
|
||||
int result = UTF16.moveCodePointOffset(sb, startIdx, amount);
|
||||
if (result != expectedResult) {
|
||||
errln("FAIL: UTF16.moveCodePointOffset(StringBuffer \"" + s + "\", " + startIdx + ", " + amount + ")" +
|
||||
" returned " + result + ", expected result was " +
|
||||
(expectedResult==-1 ? "exception" : Integer.toString(expectedResult)));
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfBoundsException e) {
|
||||
if (expectedResult != -1) {
|
||||
errln("FAIL: UTF16.moveCodePointOffset(StringBuffer \"" + s + "\", " + startIdx + ", " + amount + ")" +
|
||||
" returned exception" + ", expected result was " + expectedResult);
|
||||
}
|
||||
}
|
||||
|
||||
// Test with the char[] flavor of moveCodePointOffset
|
||||
char ca[] = s.toCharArray();
|
||||
try {
|
||||
int result = UTF16.moveCodePointOffset(ca, 0, s.length(), startIdx, amount);
|
||||
if (result != expectedResult) {
|
||||
errln("FAIL: UTF16.moveCodePointOffset(char[] \"" + s + "\", 0, " + s.length()
|
||||
+ ", " + startIdx + ", " + amount + ")" +
|
||||
" returned " + result + ", expected result was " +
|
||||
(expectedResult==-1 ? "exception" : Integer.toString(expectedResult)));
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfBoundsException e) {
|
||||
if (expectedResult != -1) {
|
||||
errln("FAIL: UTF16.moveCodePointOffset(char[] \"" + s + "\", 0, " + s.length()
|
||||
+ ", " + startIdx + ", " + amount + ")" +
|
||||
" returned exception" + ", expected result was " + expectedResult);
|
||||
}
|
||||
}
|
||||
|
||||
// Put the test string into the interior of a char array,
|
||||
// run test on the subsection of the array.
|
||||
char ca2[] = new char[s.length()+2];
|
||||
ca2[0] = (char)0xd800;
|
||||
ca2[s.length()+1] = (char)0xd8ff;
|
||||
s.getChars(0, s.length(), ca2, 1);
|
||||
try {
|
||||
int result = UTF16.moveCodePointOffset(ca2, 1, s.length()+1, startIdx, amount);
|
||||
if (result != expectedResult) {
|
||||
errln("UTF16.moveCodePointOffset(char[] \"" + "." + s + ".\", 1, " + (s.length()+1)
|
||||
+ ", " + startIdx + ", " + amount + ")" +
|
||||
" returned " + result + ", expected result was " +
|
||||
(expectedResult==-1 ? "exception" : Integer.toString(expectedResult)));
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfBoundsException e) {
|
||||
if (expectedResult != -1) {
|
||||
errln("UTF16.moveCodePointOffset(char[] \"" + "." + s + ".\", 1, " + (s.length()+1)
|
||||
+ ", " + startIdx + ", " + amount + ")" +
|
||||
" returned exception" + ", expected result was " + expectedResult);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void TestMoveCodePointOffset()
|
||||
{
|
||||
//01234567890 1 2 3 45678901234
|
||||
String str = new String("0123456789\ud800\udc00\ud801\udc010123456789");
|
||||
int move1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 12, 14, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24};
|
||||
int move2[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 14, 15, 15, 16, 17,
|
||||
18, 19, 20, 21, 22, 23, 24};
|
||||
int move3[] = {3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 15, 16, 16, 17, 18,
|
||||
19, 20, 21, 22, 23, 24};
|
||||
int size = str.length();
|
||||
for (int i = 0; i < size; i ++) {
|
||||
if (UTF16.moveCodePointOffset(str, i, 1) != move1[i]) {
|
||||
errln("FAIL: Moving offset " + i +
|
||||
" by 1 codepoint expected result " + move1[i]);
|
||||
}
|
||||
try {
|
||||
if (UTF16.moveCodePointOffset(str, i, 2) != move2[i]) {
|
||||
errln("FAIL: Moving offset " + i +
|
||||
" by 2 codepoint expected result " + move2[i]);
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
if (i <= 22) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
if (UTF16.moveCodePointOffset(str, i, 3) != move3[i]) {
|
||||
errln("FAIL: Moving offset " + i +
|
||||
" by 3 codepoint expected result " + move3[i]);
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
if (i <= 21) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringBuffer strbuff = new StringBuffer(str);
|
||||
for (int i = 0; i < size; i ++) {
|
||||
if (UTF16.moveCodePointOffset(strbuff, i, 1) != move1[i]) {
|
||||
errln("FAIL: Moving offset " + i +
|
||||
" by 1 codepoint expected result " + move1[i]);
|
||||
}
|
||||
try {
|
||||
if (UTF16.moveCodePointOffset(strbuff, i, 2) != move2[i]) {
|
||||
errln("FAIL: Moving offset " + i +
|
||||
" by 2 codepoint expected result " + move2[i]);
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
if (i <= 22) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
if (UTF16.moveCodePointOffset(strbuff, i, 3) != move3[i]) {
|
||||
errln("FAIL: Moving offset " + i +
|
||||
" by 3 codepoint expected result " + move3[i]);
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
if (i <= 21) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char strarray[] = str.toCharArray();
|
||||
for (int i = 0; i < size; i ++) {
|
||||
if (UTF16.moveCodePointOffset(strarray, 0, size, i, 1) != move1[i])
|
||||
{
|
||||
errln("FAIL: Moving offset " + i +
|
||||
" by 1 codepoint expected result " + move1[i]);
|
||||
}
|
||||
try {
|
||||
if (UTF16.moveCodePointOffset(strarray, 0, size, i, 2) !=
|
||||
move2[i]) {
|
||||
errln("FAIL: Moving offset " + i +
|
||||
" by 2 codepoint expected result " + move2[i]);
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
if (i <= 22) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
if (UTF16.moveCodePointOffset(strarray, 0, size, i, 3) !=
|
||||
move3[i]) {
|
||||
errln("FAIL: Moving offset " + i +
|
||||
" by 3 codepoint expected result " + move3[i]);
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
if (i <= 21) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (UTF16.moveCodePointOffset(strarray, 9, 13, 0, 2) != 3) {
|
||||
errln("FAIL: Moving offset 0 by 2 codepoint in subarray [9, 13] " +
|
||||
"expected result 3");
|
||||
}
|
||||
if (UTF16.moveCodePointOffset(strarray, 9, 13, 1, 2) != 4) {
|
||||
errln("FAIL: Moving offset 1 by 2 codepoint in subarray [9, 13] " +
|
||||
"expected result 4");
|
||||
}
|
||||
if (UTF16.moveCodePointOffset(strarray, 11, 14, 0, 2) != 3) {
|
||||
errln("FAIL: Moving offset 0 by 2 codepoint in subarray [11, 14] "
|
||||
+ "expected result 3");
|
||||
}
|
||||
// checkMoveCodePointOffset(String, startIndex, amount, expected ); expected=-1 for exception.
|
||||
|
||||
// No Supplementary chars
|
||||
checkMoveCodePointOffset("abc", 1, 1, 2);
|
||||
checkMoveCodePointOffset("abc", 1, -1, 0);
|
||||
checkMoveCodePointOffset("abc", 1, -2, -1);
|
||||
checkMoveCodePointOffset("abc", 1, 2, 3);
|
||||
checkMoveCodePointOffset("abc", 1, 3, -1);
|
||||
checkMoveCodePointOffset("abc", 1, 0, 1);
|
||||
|
||||
checkMoveCodePointOffset("abc", 3, 0, 3);
|
||||
checkMoveCodePointOffset("abc", 4, 0, -1);
|
||||
checkMoveCodePointOffset("abc", 0, 0, 0);
|
||||
checkMoveCodePointOffset("abc", -1, 0, -1);
|
||||
|
||||
checkMoveCodePointOffset("", 0, 0, 0);
|
||||
checkMoveCodePointOffset("", 0, -1, -1);
|
||||
checkMoveCodePointOffset("", 0, 1, -1);
|
||||
|
||||
checkMoveCodePointOffset("a", 0, 0, 0);
|
||||
checkMoveCodePointOffset("a", 1, 0, 1);
|
||||
checkMoveCodePointOffset("a", 0, 1, 1);
|
||||
checkMoveCodePointOffset("a", 1, -1, 0);
|
||||
|
||||
|
||||
// Supplementary in middle of string
|
||||
checkMoveCodePointOffset("a\ud800\udc00b", 0, 1, 1);
|
||||
checkMoveCodePointOffset("a\ud800\udc00b", 0, 2, 3);
|
||||
checkMoveCodePointOffset("a\ud800\udc00b", 0, 3, 4);
|
||||
checkMoveCodePointOffset("a\ud800\udc00b", 0, 4, -1);
|
||||
|
||||
checkMoveCodePointOffset("a\ud800\udc00b", 4, -1, 3);
|
||||
checkMoveCodePointOffset("a\ud800\udc00b", 4, -2, 1);
|
||||
checkMoveCodePointOffset("a\ud800\udc00b", 4, -3, 0);
|
||||
checkMoveCodePointOffset("a\ud800\udc00b", 4, -4, -1);
|
||||
|
||||
// Supplementary at start of string
|
||||
checkMoveCodePointOffset("\ud800\udc00ab", 0, 1, 2);
|
||||
checkMoveCodePointOffset("\ud800\udc00ab", 1, 1, 2);
|
||||
checkMoveCodePointOffset("\ud800\udc00ab", 2, 1, 3);
|
||||
checkMoveCodePointOffset("\ud800\udc00ab", 2, -1, 0);
|
||||
checkMoveCodePointOffset("\ud800\udc00ab", 1, -1, 0);
|
||||
checkMoveCodePointOffset("\ud800\udc00ab", 0, -1, -1);
|
||||
|
||||
|
||||
// Supplementary at end of string
|
||||
checkMoveCodePointOffset("ab\ud800\udc00", 1, 1, 2);
|
||||
checkMoveCodePointOffset("ab\ud800\udc00", 2, 1, 4);
|
||||
checkMoveCodePointOffset("ab\ud800\udc00", 3, 1, 4);
|
||||
checkMoveCodePointOffset("ab\ud800\udc00", 4, 1, -1);
|
||||
|
||||
checkMoveCodePointOffset("ab\ud800\udc00", 5, -2, -1);
|
||||
checkMoveCodePointOffset("ab\ud800\udc00", 4, -1, 2);
|
||||
checkMoveCodePointOffset("ab\ud800\udc00", 3, -1, 2);
|
||||
checkMoveCodePointOffset("ab\ud800\udc00", 2, -1, 1);
|
||||
checkMoveCodePointOffset("ab\ud800\udc00", 1, -1, 0);
|
||||
|
||||
// Unpaired surrogate in middle
|
||||
checkMoveCodePointOffset("a\ud800b", 0, 1, 1);
|
||||
checkMoveCodePointOffset("a\ud800b", 1, 1, 2);
|
||||
checkMoveCodePointOffset("a\ud800b", 2, 1, 3);
|
||||
|
||||
checkMoveCodePointOffset("a\udc00b", 0, 1, 1);
|
||||
checkMoveCodePointOffset("a\udc00b", 1, 1, 2);
|
||||
checkMoveCodePointOffset("a\udc00b", 2, 1, 3);
|
||||
|
||||
checkMoveCodePointOffset("a\udc00\ud800b", 0, 1, 1);
|
||||
checkMoveCodePointOffset("a\udc00\ud800b", 1, 1, 2);
|
||||
checkMoveCodePointOffset("a\udc00\ud800b", 2, 1, 3);
|
||||
checkMoveCodePointOffset("a\udc00\ud800b", 3, 1, 4);
|
||||
|
||||
checkMoveCodePointOffset("a\ud800b", 1, -1, 0);
|
||||
checkMoveCodePointOffset("a\ud800b", 2, -1, 1);
|
||||
checkMoveCodePointOffset("a\ud800b", 3, -1, 2);
|
||||
|
||||
checkMoveCodePointOffset("a\udc00b", 1, -1, 0);
|
||||
checkMoveCodePointOffset("a\udc00b", 2, -1, 1);
|
||||
checkMoveCodePointOffset("a\udc00b", 3, -1, 2);
|
||||
|
||||
checkMoveCodePointOffset("a\udc00\ud800b", 1, -1, 0);
|
||||
checkMoveCodePointOffset("a\udc00\ud800b", 2, -1, 1);
|
||||
checkMoveCodePointOffset("a\udc00\ud800b", 3, -1, 2);
|
||||
checkMoveCodePointOffset("a\udc00\ud800b", 4, -1, 3);
|
||||
|
||||
// Unpaired surrogate at start
|
||||
checkMoveCodePointOffset("\udc00ab", 0, 1, 1);
|
||||
checkMoveCodePointOffset("\ud800ab", 0, 2, 2);
|
||||
checkMoveCodePointOffset("\ud800\ud800ab", 0, 3, 3);
|
||||
checkMoveCodePointOffset("\udc00\udc00ab", 0, 4, 4);
|
||||
|
||||
checkMoveCodePointOffset("\udc00ab", 2, -1, 1);
|
||||
checkMoveCodePointOffset("\ud800ab", 1, -1, 0);
|
||||
checkMoveCodePointOffset("\ud800ab", 1, -2, -1);
|
||||
checkMoveCodePointOffset("\ud800\ud800ab", 2, -1, 1);
|
||||
checkMoveCodePointOffset("\udc00\udc00ab", 2, -2, 0);
|
||||
checkMoveCodePointOffset("\udc00\udc00ab", 2, -3, -1);
|
||||
|
||||
// Unpaired surrogate at end
|
||||
checkMoveCodePointOffset("ab\udc00\udc00ab", 3, 1, 4);
|
||||
checkMoveCodePointOffset("ab\udc00\udc00ab", 2, 1, 3);
|
||||
checkMoveCodePointOffset("ab\udc00\udc00ab", 1, 1, 2);
|
||||
|
||||
checkMoveCodePointOffset("ab\udc00\udc00ab", 4, -1, 3);
|
||||
checkMoveCodePointOffset("ab\udc00\udc00ab", 3, -1, 2);
|
||||
checkMoveCodePointOffset("ab\udc00\udc00ab", 2, -1, 1);
|
||||
|
||||
|
||||
//01234567890 1 2 3 45678901234
|
||||
String str = new String("0123456789\ud800\udc00\ud801\udc010123456789");
|
||||
int move1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
||||
12, 12, 14, 14, 15, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 24};
|
||||
int move2[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 12,
|
||||
14, 14, 15, 15, 16, 17, 18, 19, 20, 21,
|
||||
22, 23, 24, -1};
|
||||
int move3[] = { 3, 4, 5, 6, 7, 8, 9, 10, 12, 14,
|
||||
15, 15, 16, 16, 17, 18, 19, 20, 21, 22,
|
||||
23, 24, -1, -1};
|
||||
int size = str.length();
|
||||
for (int i = 0; i < size; i ++) {
|
||||
checkMoveCodePointOffset(str, i, 1, move1[i]);
|
||||
checkMoveCodePointOffset(str, i, 2, move2[i]);
|
||||
checkMoveCodePointOffset(str, i, 3, move3[i]);
|
||||
}
|
||||
|
||||
char strarray[] = str.toCharArray();
|
||||
if (UTF16.moveCodePointOffset(strarray, 9, 13, 0, 2) != 3) {
|
||||
errln("FAIL: Moving offset 0 by 2 codepoint in subarray [9, 13] " +
|
||||
"expected result 3");
|
||||
}
|
||||
if (UTF16.moveCodePointOffset(strarray, 9, 13, 1, 2) != 4) {
|
||||
errln("FAIL: Moving offset 1 by 2 codepoint in subarray [9, 13] " +
|
||||
"expected result 4");
|
||||
}
|
||||
if (UTF16.moveCodePointOffset(strarray, 11, 14, 0, 2) != 3) {
|
||||
errln("FAIL: Moving offset 0 by 2 codepoint in subarray [11, 14] "
|
||||
+ "expected result 3");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1273,25 +1273,44 @@ public final class UTF16
|
||||
public static int moveCodePointOffset(String source, int offset16,
|
||||
int shift32)
|
||||
{
|
||||
int result = offset16;
|
||||
int size = source.length();
|
||||
if (offset16 < 0 || shift32 + offset16 > size) {
|
||||
int count;
|
||||
char ch;
|
||||
if (offset16<0 || offset16>size) {
|
||||
throw new StringIndexOutOfBoundsException(offset16);
|
||||
}
|
||||
char ch;
|
||||
int result = offset16;
|
||||
int count = shift32;
|
||||
while (result < size && count > 0)
|
||||
if (shift32 > 0 ) {
|
||||
if (shift32 + offset16 > size) {
|
||||
throw new StringIndexOutOfBoundsException(offset16);
|
||||
}
|
||||
count = shift32;
|
||||
while (result < size && count > 0)
|
||||
{
|
||||
ch = source.charAt(result);
|
||||
if (isLeadSurrogate(ch) && ((result + 1) < size) &&
|
||||
isTrailSurrogate(source.charAt(result + 1))) {
|
||||
isTrailSurrogate(source.charAt(result + 1))) {
|
||||
result ++;
|
||||
}
|
||||
|
||||
count --;
|
||||
result ++;
|
||||
}
|
||||
if (count != 0) {
|
||||
} else {
|
||||
if (offset16 + shift32 < 0) {
|
||||
throw new StringIndexOutOfBoundsException(offset16);
|
||||
}
|
||||
for (count=-shift32; count>0; count--) {
|
||||
result--;
|
||||
if (result<0) {
|
||||
break;
|
||||
}
|
||||
ch = source.charAt(result);
|
||||
if (isTrailSurrogate(ch) && result>0 && isLeadSurrogate(source.charAt(result-1))) {
|
||||
result--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count != 0) {
|
||||
throw new StringIndexOutOfBoundsException(shift32);
|
||||
}
|
||||
return result;
|
||||
@ -1310,28 +1329,47 @@ public final class UTF16
|
||||
public static int moveCodePointOffset(StringBuffer source, int offset16,
|
||||
int shift32)
|
||||
{
|
||||
int result = offset16;
|
||||
int size = source.length();
|
||||
if (offset16 < 0 || shift32 + offset16 > size) {
|
||||
int count;
|
||||
char ch;
|
||||
if (offset16<0 || offset16>size) {
|
||||
throw new StringIndexOutOfBoundsException(offset16);
|
||||
}
|
||||
char ch;
|
||||
int result = offset16;
|
||||
int count = shift32;
|
||||
while (result < size && count > 0)
|
||||
{
|
||||
ch = source.charAt(result);
|
||||
if (isLeadSurrogate(ch) && ((result + 1) < size) &&
|
||||
isTrailSurrogate(source.charAt(result + 1))) {
|
||||
result ++;
|
||||
}
|
||||
|
||||
count --;
|
||||
result ++;
|
||||
if (shift32 > 0 ) {
|
||||
if (shift32 + offset16 > size) {
|
||||
throw new StringIndexOutOfBoundsException(offset16);
|
||||
}
|
||||
count = shift32;
|
||||
while (result < size && count > 0)
|
||||
{
|
||||
ch = source.charAt(result);
|
||||
if (isLeadSurrogate(ch) && ((result + 1) < size) &&
|
||||
isTrailSurrogate(source.charAt(result + 1))) {
|
||||
result ++;
|
||||
}
|
||||
count --;
|
||||
result ++;
|
||||
}
|
||||
} else {
|
||||
if (offset16 + shift32 < 0) {
|
||||
throw new StringIndexOutOfBoundsException(offset16);
|
||||
}
|
||||
if (count != 0) {
|
||||
for (count=-shift32; count>0; count--) {
|
||||
result--;
|
||||
if (result<0) {
|
||||
break;
|
||||
}
|
||||
ch = source.charAt(result);
|
||||
if (isTrailSurrogate(ch) && result>0 && isLeadSurrogate(source.charAt(result-1))) {
|
||||
result--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count != 0) {
|
||||
throw new StringIndexOutOfBoundsException(shift32);
|
||||
}
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1343,34 +1381,61 @@ public final class UTF16
|
||||
* @param shift32 number of codepoints to shift
|
||||
* @return new shifted offset16 relative to start
|
||||
* @exception IndexOutOfBoundsException if the new offset16 is out of
|
||||
* bounds with respect to the subarray.
|
||||
* bounds with respect to the subarray or the subarray bounds
|
||||
* are out of range.
|
||||
* @stable ICU 2.1
|
||||
*/
|
||||
public static int moveCodePointOffset(char source[], int start, int limit,
|
||||
int offset16, int shift32)
|
||||
{
|
||||
offset16 += start;
|
||||
if (shift32 + offset16 > limit) {
|
||||
int size = source.length;
|
||||
int count;
|
||||
char ch;
|
||||
int result = offset16 + start;
|
||||
if (start<0 || limit<start) {
|
||||
throw new StringIndexOutOfBoundsException(start);
|
||||
}
|
||||
if (limit>size) {
|
||||
throw new StringIndexOutOfBoundsException(limit);
|
||||
}
|
||||
if (offset16<0 || result>limit) {
|
||||
throw new StringIndexOutOfBoundsException(offset16);
|
||||
}
|
||||
char ch;
|
||||
int result = offset16;
|
||||
int count = shift32;
|
||||
while (result < limit && count > 0)
|
||||
if (shift32 > 0 ) {
|
||||
if (shift32 + result > size) {
|
||||
throw new StringIndexOutOfBoundsException(result);
|
||||
}
|
||||
count = shift32;
|
||||
while (result < limit && count > 0)
|
||||
{
|
||||
ch = source[result];
|
||||
if (isLeadSurrogate(ch) && ((result + 1) < limit) &&
|
||||
isTrailSurrogate(source[result + 1])) {
|
||||
if (isLeadSurrogate(ch) && (result+1 < limit) &&
|
||||
isTrailSurrogate(source[result+1])) {
|
||||
result ++;
|
||||
}
|
||||
|
||||
count --;
|
||||
result ++;
|
||||
}
|
||||
if (count != 0) {
|
||||
} else {
|
||||
if (result + shift32 < start) {
|
||||
throw new StringIndexOutOfBoundsException(result);
|
||||
}
|
||||
for (count=-shift32; count>0; count--) {
|
||||
result--;
|
||||
if (result<start) {
|
||||
break;
|
||||
}
|
||||
ch = source[result];
|
||||
if (isTrailSurrogate(ch) && result>start && isLeadSurrogate(source[result-1])) {
|
||||
result--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count != 0) {
|
||||
throw new StringIndexOutOfBoundsException(shift32);
|
||||
}
|
||||
return result - start;
|
||||
result -= start;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user