160 if (c1 != c2) {
161 c1 = Character.toLowerCase(c1);
162 c2 = Character.toLowerCase(c2);
163 if (c1 != c2) {
164 return c1 - c2;
165 }
166 }
167 }
168 }
169 return len1 - len2;
170 }
171
172 public static int compareToCI_UTF16(byte[] value, byte[] other) {
173 int len1 = length(value);
174 int len2 = StringUTF16.length(other);
175 int lim = Math.min(len1, len2);
176 for (int k = 0; k < lim; k++) {
177 char c1 = getChar(value, k);
178 char c2 = StringUTF16.getChar(other, k);
179 if (c1 != c2) {
180 c1 = Character.toUpperCase(c1);
181 c2 = Character.toUpperCase(c2);
182 if (c1 != c2) {
183 c1 = Character.toLowerCase(c1);
184 c2 = Character.toLowerCase(c2);
185 if (c1 != c2) {
186 return c1 - c2;
187 }
188 }
189 }
190 }
191 return len1 - len2;
192 }
193
194 public static int hashCode(byte[] value) {
195 int h = 0;
196 for (byte v : value) {
197 h = 31 * h + (v & 0xff);
198 }
199 return h;
200 }
374 for (int k = 0; k < replLen; ++k) {
375 result[posTo++] = repl[k];
376 }
377 }
378 while (posFrom < valLen) {
379 result[posTo++] = value[posFrom++];
380 }
381 return new String(result, LATIN1);
382 }
383
384 // case insensitive
385 public static boolean regionMatchesCI(byte[] value, int toffset,
386 byte[] other, int ooffset, int len) {
387 int last = toffset + len;
388 while (toffset < last) {
389 char c1 = (char)(value[toffset++] & 0xff);
390 char c2 = (char)(other[ooffset++] & 0xff);
391 if (c1 == c2) {
392 continue;
393 }
394 char u1 = Character.toUpperCase(c1);
395 char u2 = Character.toUpperCase(c2);
396 if (u1 == u2) {
397 continue;
398 }
399 if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
400 continue;
401 }
402 return false;
403 }
404 return true;
405 }
406
407 public static boolean regionMatchesCI_UTF16(byte[] value, int toffset,
408 byte[] other, int ooffset, int len) {
409 int last = toffset + len;
410 while (toffset < last) {
411 char c1 = (char)(value[toffset++] & 0xff);
412 char c2 = StringUTF16.getChar(other, ooffset++);
413 if (c1 == c2) {
414 continue;
415 }
416 char u1 = Character.toUpperCase(c1);
417 char u2 = Character.toUpperCase(c2);
418 if (u1 == u2) {
419 continue;
420 }
421 if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
422 continue;
423 }
424 return false;
425 }
426 return true;
427 }
428
429 public static String toLowerCase(String str, byte[] value, Locale locale) {
430 if (locale == null) {
431 throw new NullPointerException();
432 }
433 int first;
434 final int len = value.length;
435 // Now check if there are any characters that need to be changed, or are surrogate
436 for (first = 0 ; first < len; first++) {
437 int cp = value[first] & 0xff;
438 if (cp != Character.toLowerCase(cp)) { // no need to check Character.ERROR
439 break;
440 }
441 }
442 if (first == len)
443 return str;
444 String lang = locale.getLanguage();
445 if (lang == "tr" || lang == "az" || lang == "lt") {
446 return toLowerCaseEx(str, value, first, locale, true);
447 }
448 byte[] result = new byte[len];
449 System.arraycopy(value, 0, result, 0, first); // Just copy the first few
450 // lowerCase characters.
451 for (int i = first; i < len; i++) {
452 int cp = value[i] & 0xff;
453 cp = Character.toLowerCase(cp);
454 if (!canEncode(cp)) { // not a latin1 character
455 return toLowerCaseEx(str, value, first, locale, false);
456 }
457 result[i] = (byte)cp;
458 }
459 return new String(result, LATIN1);
460 }
461
462 private static String toLowerCaseEx(String str, byte[] value,
463 int first, Locale locale, boolean localeDependent)
464 {
465 byte[] result = StringUTF16.newBytesFor(value.length);
466 int resultOffset = 0;
467 for (int i = 0; i < first; i++) {
468 StringUTF16.putChar(result, resultOffset++, value[i] & 0xff);
469 }
470 for (int i = first; i < value.length; i++) {
471 int srcChar = value[i] & 0xff;
472 int lowerChar;
473 char[] lowerCharArray;
474 if (localeDependent) {
475 lowerChar = ConditionalSpecialCasing.toLowerCaseEx(str, i, locale);
476 } else {
477 lowerChar = Character.toLowerCase(srcChar);
478 }
479 if (Character.isBmpCodePoint(lowerChar)) { // Character.ERROR is not a bmp
480 StringUTF16.putChar(result, resultOffset++, lowerChar);
481 } else {
482 if (lowerChar == Character.ERROR) {
483 lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(str, i, locale);
484 } else {
485 lowerCharArray = Character.toChars(lowerChar);
486 }
487 /* Grow result if needed */
488 int mapLen = lowerCharArray.length;
489 if (mapLen > 1) {
490 byte[] result2 = StringUTF16.newBytesFor((result.length >> 1) + mapLen - 1);
491 System.arraycopy(result, 0, result2, 0, resultOffset << 1);
492 result = result2;
493 }
494 for (int x = 0; x < mapLen; ++x) {
495 StringUTF16.putChar(result, resultOffset++, lowerCharArray[x]);
496 }
497 }
498 }
499 return StringUTF16.newString(result, 0, resultOffset);
500 }
501
502 public static String toUpperCase(String str, byte[] value, Locale locale) {
503 if (locale == null) {
504 throw new NullPointerException();
505 }
506 int first;
507 final int len = value.length;
508
509 // Now check if there are any characters that need to be changed, or are surrogate
510 for (first = 0 ; first < len; first++ ) {
511 int cp = value[first] & 0xff;
512 if (cp != Character.toUpperCaseEx(cp)) { // no need to check Character.ERROR
513 break;
514 }
515 }
516 if (first == len) {
517 return str;
518 }
519 String lang = locale.getLanguage();
520 if (lang == "tr" || lang == "az" || lang == "lt") {
521 return toUpperCaseEx(str, value, first, locale, true);
522 }
523 byte[] result = new byte[len];
524 System.arraycopy(value, 0, result, 0, first); // Just copy the first few
525 // upperCase characters.
526 for (int i = first; i < len; i++) {
527 int cp = value[i] & 0xff;
528 cp = Character.toUpperCaseEx(cp);
529 if (!canEncode(cp)) { // not a latin1 character
530 return toUpperCaseEx(str, value, first, locale, false);
531 }
532 result[i] = (byte)cp;
533 }
534 return new String(result, LATIN1);
535 }
536
537 private static String toUpperCaseEx(String str, byte[] value,
538 int first, Locale locale, boolean localeDependent)
539 {
540 byte[] result = StringUTF16.newBytesFor(value.length);
541 int resultOffset = 0;
542 for (int i = 0; i < first; i++) {
543 StringUTF16.putChar(result, resultOffset++, value[i] & 0xff);
544 }
545 for (int i = first; i < value.length; i++) {
546 int srcChar = value[i] & 0xff;
547 int upperChar;
548 char[] upperCharArray;
549 if (localeDependent) {
550 upperChar = ConditionalSpecialCasing.toUpperCaseEx(str, i, locale);
551 } else {
552 upperChar = Character.toUpperCaseEx(srcChar);
553 }
554 if (Character.isBmpCodePoint(upperChar)) {
555 StringUTF16.putChar(result, resultOffset++, upperChar);
556 } else {
557 if (upperChar == Character.ERROR) {
558 if (localeDependent) {
559 upperCharArray =
560 ConditionalSpecialCasing.toUpperCaseCharArray(str, i, locale);
561 } else {
562 upperCharArray = Character.toUpperCaseCharArray(srcChar);
563 }
564 } else {
565 upperCharArray = Character.toChars(upperChar);
566 }
567 /* Grow result if needed */
568 int mapLen = upperCharArray.length;
569 if (mapLen > 1) {
570 byte[] result2 = StringUTF16.newBytesFor((result.length >> 1) + mapLen - 1);
571 System.arraycopy(result, 0, result2, 0, resultOffset << 1);
572 result = result2;
573 }
574 for (int x = 0; x < mapLen; ++x) {
575 StringUTF16.putChar(result, resultOffset++, upperCharArray[x]);
576 }
577 }
578 }
579 return StringUTF16.newString(result, 0, resultOffset);
580 }
581
582 public static String trim(byte[] value) {
583 int len = value.length;
584 int st = 0;
585 while ((st < len) && ((value[st] & 0xff) <= ' ')) {
586 st++;
587 }
588 while ((st < len) && ((value[len - 1] & 0xff) <= ' ')) {
589 len--;
590 }
591 return ((st > 0) || (len < value.length)) ?
592 newString(value, st, len - st) : null;
593 }
594
595 public static int indexOfNonWhitespace(byte[] value) {
596 int length = value.length;
597 int left = 0;
598 while (left < length) {
599 char ch = getChar(value, left);
600 if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
601 break;
602 }
603 left++;
604 }
605 return left;
606 }
607
608 public static int lastIndexOfNonWhitespace(byte[] value) {
609 int length = value.length;
610 int right = length;
611 while (0 < right) {
612 char ch = getChar(value, right - 1);
613 if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
614 break;
615 }
616 right--;
617 }
618 return right;
619 }
620
621 public static String strip(byte[] value) {
622 int left = indexOfNonWhitespace(value);
623 if (left == value.length) {
624 return "";
625 }
626 int right = lastIndexOfNonWhitespace(value);
627 boolean ifChanged = (left > 0) || (right < value.length);
628 return ifChanged ? newString(value, left, right - left) : null;
629 }
630
631 public static String stripLeading(byte[] value) {
632 int left = indexOfNonWhitespace(value);
633 if (left == value.length) {
|
160 if (c1 != c2) {
161 c1 = Character.toLowerCase(c1);
162 c2 = Character.toLowerCase(c2);
163 if (c1 != c2) {
164 return c1 - c2;
165 }
166 }
167 }
168 }
169 return len1 - len2;
170 }
171
172 public static int compareToCI_UTF16(byte[] value, byte[] other) {
173 int len1 = length(value);
174 int len2 = StringUTF16.length(other);
175 int lim = Math.min(len1, len2);
176 for (int k = 0; k < lim; k++) {
177 char c1 = getChar(value, k);
178 char c2 = StringUTF16.getChar(other, k);
179 if (c1 != c2) {
180 c1 = (char) CharacterDataLatin1.instance.toUpperCase(c1);
181 c2 = Character.toUpperCase(c2);
182 if (c1 != c2) {
183 c1 = Character.toLowerCase(c1);
184 c2 = Character.toLowerCase(c2);
185 if (c1 != c2) {
186 return c1 - c2;
187 }
188 }
189 }
190 }
191 return len1 - len2;
192 }
193
194 public static int hashCode(byte[] value) {
195 int h = 0;
196 for (byte v : value) {
197 h = 31 * h + (v & 0xff);
198 }
199 return h;
200 }
374 for (int k = 0; k < replLen; ++k) {
375 result[posTo++] = repl[k];
376 }
377 }
378 while (posFrom < valLen) {
379 result[posTo++] = value[posFrom++];
380 }
381 return new String(result, LATIN1);
382 }
383
384 // case insensitive
385 public static boolean regionMatchesCI(byte[] value, int toffset,
386 byte[] other, int ooffset, int len) {
387 int last = toffset + len;
388 while (toffset < last) {
389 char c1 = (char)(value[toffset++] & 0xff);
390 char c2 = (char)(other[ooffset++] & 0xff);
391 if (c1 == c2) {
392 continue;
393 }
394 int u1 = CharacterDataLatin1.instance.toUpperCase(c1);
395 int u2 = CharacterDataLatin1.instance.toUpperCase(c2);
396 if (u1 == u2) {
397 continue;
398 }
399 if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
400 continue;
401 }
402 return false;
403 }
404 return true;
405 }
406
407 public static boolean regionMatchesCI_UTF16(byte[] value, int toffset,
408 byte[] other, int ooffset, int len) {
409 int last = toffset + len;
410 while (toffset < last) {
411 char c1 = (char)(value[toffset++] & 0xff);
412 char c2 = StringUTF16.getChar(other, ooffset++);
413 if (c1 == c2) {
414 continue;
415 }
416 char u1 = (char) CharacterDataLatin1.instance.toUpperCase(c1);
417 char u2 = Character.toUpperCase(c2);
418 if (u1 == u2) {
419 continue;
420 }
421 if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
422 continue;
423 }
424 return false;
425 }
426 return true;
427 }
428
429 public static String toLowerCase(String str, byte[] value, Locale locale) {
430 if (locale == null) {
431 throw new NullPointerException();
432 }
433 int first;
434 final int len = value.length;
435 // Now check if there are any characters that need to be changed, or are surrogate
436 for (first = 0 ; first < len; first++) {
437 int cp = value[first] & 0xff;
438 if (cp != CharacterDataLatin1.instance.toLowerCase(cp)) { // no need to check Character.ERROR
439 break;
440 }
441 }
442 if (first == len)
443 return str;
444 String lang = locale.getLanguage();
445 if (lang == "tr" || lang == "az" || lang == "lt") {
446 return toLowerCaseEx(str, value, first, locale, true);
447 }
448 byte[] result = new byte[len];
449 System.arraycopy(value, 0, result, 0, first); // Just copy the first few
450 // lowerCase characters.
451 for (int i = first; i < len; i++) {
452 int cp = value[i] & 0xff;
453 cp = CharacterDataLatin1.instance.toLowerCase(cp);
454 if (!canEncode(cp)) { // not a latin1 character
455 return toLowerCaseEx(str, value, first, locale, false);
456 }
457 result[i] = (byte)cp;
458 }
459 return new String(result, LATIN1);
460 }
461
462 private static String toLowerCaseEx(String str, byte[] value,
463 int first, Locale locale, boolean localeDependent)
464 {
465 byte[] result = StringUTF16.newBytesFor(value.length);
466 int resultOffset = 0;
467 for (int i = 0; i < first; i++) {
468 StringUTF16.putChar(result, resultOffset++, value[i] & 0xff);
469 }
470 for (int i = first; i < value.length; i++) {
471 int srcChar = value[i] & 0xff;
472 int lowerChar;
473 char[] lowerCharArray;
474 if (localeDependent) {
475 lowerChar = ConditionalSpecialCasing.toLowerCaseEx(str, i, locale);
476 } else {
477 lowerChar = CharacterDataLatin1.instance.toLowerCase(srcChar);
478 }
479 if (Character.isBmpCodePoint(lowerChar)) { // Character.ERROR is not a bmp
480 StringUTF16.putChar(result, resultOffset++, lowerChar);
481 } else {
482 if (lowerChar == Character.ERROR) {
483 lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(str, i, locale);
484 } else {
485 lowerCharArray = Character.toChars(lowerChar);
486 }
487 /* Grow result if needed */
488 int mapLen = lowerCharArray.length;
489 if (mapLen > 1) {
490 byte[] result2 = StringUTF16.newBytesFor((result.length >> 1) + mapLen - 1);
491 System.arraycopy(result, 0, result2, 0, resultOffset << 1);
492 result = result2;
493 }
494 for (int x = 0; x < mapLen; ++x) {
495 StringUTF16.putChar(result, resultOffset++, lowerCharArray[x]);
496 }
497 }
498 }
499 return StringUTF16.newString(result, 0, resultOffset);
500 }
501
502 public static String toUpperCase(String str, byte[] value, Locale locale) {
503 if (locale == null) {
504 throw new NullPointerException();
505 }
506 int first;
507 final int len = value.length;
508
509 // Now check if there are any characters that need to be changed, or are surrogate
510 for (first = 0 ; first < len; first++ ) {
511 int cp = value[first] & 0xff;
512 if (cp != CharacterDataLatin1.instance.toUpperCaseEx(cp)) { // no need to check Character.ERROR
513 break;
514 }
515 }
516 if (first == len) {
517 return str;
518 }
519 String lang = locale.getLanguage();
520 if (lang == "tr" || lang == "az" || lang == "lt") {
521 return toUpperCaseEx(str, value, first, locale, true);
522 }
523 byte[] result = new byte[len];
524 System.arraycopy(value, 0, result, 0, first); // Just copy the first few
525 // upperCase characters.
526 for (int i = first; i < len; i++) {
527 int cp = value[i] & 0xff;
528 cp = CharacterDataLatin1.instance.toUpperCaseEx(cp);
529 if (!canEncode(cp)) { // not a latin1 character
530 return toUpperCaseEx(str, value, first, locale, false);
531 }
532 result[i] = (byte)cp;
533 }
534 return new String(result, LATIN1);
535 }
536
537 private static String toUpperCaseEx(String str, byte[] value,
538 int first, Locale locale, boolean localeDependent)
539 {
540 byte[] result = StringUTF16.newBytesFor(value.length);
541 int resultOffset = 0;
542 for (int i = 0; i < first; i++) {
543 StringUTF16.putChar(result, resultOffset++, value[i] & 0xff);
544 }
545 for (int i = first; i < value.length; i++) {
546 int srcChar = value[i] & 0xff;
547 int upperChar;
548 char[] upperCharArray;
549 if (localeDependent) {
550 upperChar = ConditionalSpecialCasing.toUpperCaseEx(str, i, locale);
551 } else {
552 upperChar = CharacterDataLatin1.instance.toUpperCaseEx(srcChar);
553 }
554 if (Character.isBmpCodePoint(upperChar)) {
555 StringUTF16.putChar(result, resultOffset++, upperChar);
556 } else {
557 if (upperChar == Character.ERROR) {
558 if (localeDependent) {
559 upperCharArray =
560 ConditionalSpecialCasing.toUpperCaseCharArray(str, i, locale);
561 } else {
562 upperCharArray = CharacterDataLatin1.instance.toUpperCaseCharArray(srcChar);
563 }
564 } else {
565 upperCharArray = Character.toChars(upperChar);
566 }
567 /* Grow result if needed */
568 int mapLen = upperCharArray.length;
569 if (mapLen > 1) {
570 byte[] result2 = StringUTF16.newBytesFor((result.length >> 1) + mapLen - 1);
571 System.arraycopy(result, 0, result2, 0, resultOffset << 1);
572 result = result2;
573 }
574 for (int x = 0; x < mapLen; ++x) {
575 StringUTF16.putChar(result, resultOffset++, upperCharArray[x]);
576 }
577 }
578 }
579 return StringUTF16.newString(result, 0, resultOffset);
580 }
581
582 public static String trim(byte[] value) {
583 int len = value.length;
584 int st = 0;
585 while ((st < len) && ((value[st] & 0xff) <= ' ')) {
586 st++;
587 }
588 while ((st < len) && ((value[len - 1] & 0xff) <= ' ')) {
589 len--;
590 }
591 return ((st > 0) || (len < value.length)) ?
592 newString(value, st, len - st) : null;
593 }
594
595 public static int indexOfNonWhitespace(byte[] value) {
596 int length = value.length;
597 int left = 0;
598 while (left < length) {
599 char ch = getChar(value, left);
600 if (ch != ' ' && ch != '\t' && !CharacterDataLatin1.instance.isWhitespace(ch)) {
601 break;
602 }
603 left++;
604 }
605 return left;
606 }
607
608 public static int lastIndexOfNonWhitespace(byte[] value) {
609 int length = value.length;
610 int right = length;
611 while (0 < right) {
612 char ch = getChar(value, right - 1);
613 if (ch != ' ' && ch != '\t' && !CharacterDataLatin1.instance.isWhitespace(ch)) {
614 break;
615 }
616 right--;
617 }
618 return right;
619 }
620
621 public static String strip(byte[] value) {
622 int left = indexOfNonWhitespace(value);
623 if (left == value.length) {
624 return "";
625 }
626 int right = lastIndexOfNonWhitespace(value);
627 boolean ifChanged = (left > 0) || (right < value.length);
628 return ifChanged ? newString(value, left, right - left) : null;
629 }
630
631 public static String stripLeading(byte[] value) {
632 int left = indexOfNonWhitespace(value);
633 if (left == value.length) {
|