Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 | 5 |
| 6 #ifdef V8_I18N_SUPPORT | 6 #ifdef V8_I18N_SUPPORT |
| 7 #include "src/runtime/runtime-utils.h" | 7 #include "src/runtime/runtime-utils.h" |
| 8 | 8 |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/api-natives.h" | 10 #include "src/api-natives.h" |
| (...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 746 } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) { | 746 } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) { |
| 747 return *isolate->factory()->NewStringFromStaticChars("kana"); | 747 return *isolate->factory()->NewStringFromStaticChars("kana"); |
| 748 } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) { | 748 } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) { |
| 749 return *isolate->factory()->NewStringFromStaticChars("ideo"); | 749 return *isolate->factory()->NewStringFromStaticChars("ideo"); |
| 750 } else { | 750 } else { |
| 751 return *isolate->factory()->NewStringFromStaticChars("unknown"); | 751 return *isolate->factory()->NewStringFromStaticChars("unknown"); |
| 752 } | 752 } |
| 753 } | 753 } |
| 754 | 754 |
| 755 namespace { | 755 namespace { |
| 756 #if 0 | |
| 756 inline void LocaleConvertCaseHelper(icu::UnicodeString* s, bool is_to_upper, | 757 inline void LocaleConvertCaseHelper(icu::UnicodeString* s, bool is_to_upper, |
| 757 const icu::Locale& locale) { | 758 const icu::Locale& locale) { |
| 758 if (is_to_upper) | 759 if (is_to_upper) |
| 759 s->toUpper(locale); | 760 s->toUpper(locale); |
| 760 else | 761 else |
| 761 s->toLower(locale); | 762 s->toLower(locale); |
| 762 } | 763 } |
| 763 void ConvertCaseWithTransliterator(icu::UnicodeString* input, | 764 void ConvertCaseWithTransliterator(icu::UnicodeString* input, |
| 764 const char* transliterator_id) { | 765 const char* transliterator_id) { |
| 765 UErrorCode status = U_ZERO_ERROR; | 766 UErrorCode status = U_ZERO_ERROR; |
| 766 base::SmartPointer<icu::Transliterator> translit( | 767 base::SmartPointer<icu::Transliterator> translit( |
| 767 icu::Transliterator::createInstance( | 768 icu::Transliterator::createInstance( |
| 768 icu::UnicodeString(transliterator_id, -1, US_INV), UTRANS_FORWARD, | 769 icu::UnicodeString(transliterator_id, -1, US_INV), UTRANS_FORWARD, |
| 769 status)); | 770 status)); |
| 770 if (U_FAILURE(status)) return; | 771 if (U_FAILURE(status)) return; |
| 771 translit->transliterate(*input); | 772 translit->transliterate(*input); |
| 772 } | 773 } |
| 774 #endif | |
| 773 | 775 |
| 774 MUST_USE_RESULT Object* LocaleConvertCase(Handle<String> s, Isolate* isolate, | 776 MUST_USE_RESULT Object* LocaleConvertCase(Handle<String> s, Isolate* isolate, |
| 775 bool is_to_upper, int locale_id) { | 777 bool is_to_upper, int locale_id) { |
| 776 static const char* conversion_locales[] = { | 778 static const char* conversion_locales[] = { |
| 777 "az", "el", "lt", "tr", | 779 "az", "el", "lt", "tr", |
| 778 }; | 780 }; |
| 779 RUNTIME_ASSERT(locale_id >= -1 && | 781 RUNTIME_ASSERT(locale_id >= -1 && |
| 780 locale_id < static_cast<int>(arraysize(conversion_locales))); | 782 locale_id < static_cast<int>(arraysize(conversion_locales))); |
| 781 int32_t length = s->length(); | 783 int32_t length = s->length(); |
| 782 icu::UnicodeString converted; | 784 base::SmartArrayPointer<uc16> sap; |
| 785 const UChar* src; | |
| 786 Handle<SeqTwoByteString> result = | |
| 787 isolate->factory()->NewRawTwoByteString(length).ToHandleChecked(); | |
| 783 { | 788 { |
| 784 DisallowHeapAllocation no_gc; | 789 DisallowHeapAllocation no_gc; |
| 785 DCHECK(s->IsFlat()); | 790 DCHECK(s->IsFlat()); |
| 786 String::FlatContent flat = s->GetFlatContent(); | 791 String::FlatContent flat = s->GetFlatContent(); |
| 787 | |
| 788 const UChar* src; | |
| 789 if (flat.IsOneByte()) { | 792 if (flat.IsOneByte()) { |
| 790 base::SmartArrayPointer<uc16> sap = s->ToWideCString(); | 793 sap = s->ToWideCString(); |
| 791 src = reinterpret_cast<const UChar*>(sap.get()); | 794 src = reinterpret_cast<const UChar*>(sap.get()); |
| 792 converted = icu::UnicodeString(src, length); | |
| 793 } else { | 795 } else { |
| 794 src = reinterpret_cast<const UChar*>(flat.ToUC16Vector().start()); | 796 src = reinterpret_cast<const UChar*>(flat.ToUC16Vector().start()); |
| 795 converted = icu::UnicodeString(src, length); | 797 } |
| 798 | |
| 799 if (V8_LIKELY(locale_id != 1 || !is_to_upper)) { | |
| 800 typedef int32_t (*case_conversion_fn)( | |
| 801 UChar * dest, int32_t destCapacity, const UChar* src, | |
| 802 int32_t srcLength, const char* locale, UErrorCode* pErrorCode); | |
| 803 case_conversion_fn fn = is_to_upper ? u_strToUpper : u_strToLower; | |
| 804 | |
| 805 int32_t target_length = length; | |
| 806 const char* locale = locale_id == -1 ? "" : conversion_locales[locale_id]; | |
| 807 UErrorCode error; | |
| 808 do { | |
| 809 error = U_ZERO_ERROR; | |
| 810 target_length = fn(reinterpret_cast<UChar*>(result->GetChars()), | |
| 811 target_length, src, length, locale, &error); | |
| 812 result->synchronized_set_length(target_length); | |
|
jungshik at Google
2016/04/14 07:46:31
|set_length| is called over |result| ( which is Se
| |
| 813 } while (error == U_BUFFER_OVERFLOW_ERROR); | |
| 814 return U_SUCCESS(error) ? *result : *s; | |
| 796 } | 815 } |
| 797 } | 816 } |
| 798 | 817 |
| 799 if (locale_id == -1) { | 818 return *s; |
| 800 LocaleConvertCaseHelper(&converted, is_to_upper, icu::Locale::getRoot()); | 819 #if 0 |
| 801 } else if (V8_UNLIKELY(locale_id == 1 && is_to_upper)) { | 820 // For Greek Uppercasing |
| 802 // TODO(jshin): Once http://bugs.icu-project.org/trac/ticket/10582 is | 821 icu::UnicodeString converted(false, src, length); |
| 803 // fixed, remove this special-casing for uppercasing in Greek(el) locale. | 822 ConvertCaseWithTransliterator(&converted, "el-Upper"); |
| 804 // This is ~500 times slower than using the case conversion API. | 823 Handle<String> greek_result; |
| 805 ConvertCaseWithTransliterator(&converted, "el-Upper"); | |
| 806 } else { | |
| 807 LocaleConvertCaseHelper(&converted, is_to_upper, | |
| 808 icu::Locale(conversion_locales[locale_id])); | |
| 809 } | |
| 810 | |
| 811 Handle<String> result; | |
| 812 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 824 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 813 isolate, result, | 825 isolate, greek_result, |
| 814 isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>( | 826 isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>( |
| 815 reinterpret_cast<const uint16_t*>(converted.getBuffer()), | 827 reinterpret_cast<const uint16_t*>(converted.getBuffer()), |
| 816 converted.length()))); | 828 converted.length()))); |
| 817 return *result; | 829 return *greek_result; |
| 830 #endif | |
| 818 } | 831 } |
| 819 | 832 |
| 820 inline bool IsASCIIUpper(uint16_t ch) { return ch >= 'A' && ch <= 'Z'; } | 833 inline bool IsASCIIUpper(uint16_t ch) { return ch >= 'A' && ch <= 'Z'; } |
| 821 | 834 |
| 822 inline uint16_t ToASCIILower(uint16_t ch) { | 835 inline uint16_t ToASCIILower(uint16_t ch) { |
| 823 return ch | ((ch >= 'A' && ch <= 'Z') << 5); | 836 return ch | ((ch >= 'A' && ch <= 'Z') << 5); |
| 824 } | 837 } |
| 825 | 838 |
| 826 inline uint16_t ToASCIIUpper(uint16_t ch) { | 839 inline uint16_t ToASCIIUpper(uint16_t ch) { |
| 827 return ch & ~((ch >= 'a' && ch <= 'z') << 5); | 840 return ch & ~((ch >= 'a' && ch <= 'z') << 5); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 970 CONVERT_BOOLEAN_ARG_CHECKED(is_upper, 1); | 983 CONVERT_BOOLEAN_ARG_CHECKED(is_upper, 1); |
| 971 CONVERT_NUMBER_CHECKED(int, lang_id, Int32, args[2]); | 984 CONVERT_NUMBER_CHECKED(int, lang_id, Int32, args[2]); |
| 972 | 985 |
| 973 return LocaleConvertCase(s, isolate, is_upper, lang_id); | 986 return LocaleConvertCase(s, isolate, is_upper, lang_id); |
| 974 } | 987 } |
| 975 | 988 |
| 976 } // namespace internal | 989 } // namespace internal |
| 977 } // namespace v8 | 990 } // namespace v8 |
| 978 | 991 |
| 979 #endif // V8_I18N_SUPPORT | 992 #endif // V8_I18N_SUPPORT |
| OLD | NEW |