Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 // limitations under the License. | 4 // limitations under the License. |
| 5 | 5 |
| 6 #include "src/i18n.h" | 6 #include "src/i18n.h" |
| 7 | 7 |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "src/api.h" | 10 #include "src/api.h" |
| (...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 892 return reinterpret_cast<icu::BreakIterator*>(obj->GetInternalField(0)); | 892 return reinterpret_cast<icu::BreakIterator*>(obj->GetInternalField(0)); |
| 893 } | 893 } |
| 894 | 894 |
| 895 void V8BreakIterator::DeleteBreakIterator( | 895 void V8BreakIterator::DeleteBreakIterator( |
| 896 const v8::WeakCallbackInfo<void>& data) { | 896 const v8::WeakCallbackInfo<void>& data) { |
| 897 delete reinterpret_cast<icu::BreakIterator*>(data.GetInternalField(0)); | 897 delete reinterpret_cast<icu::BreakIterator*>(data.GetInternalField(0)); |
| 898 delete reinterpret_cast<icu::UnicodeString*>(data.GetInternalField(1)); | 898 delete reinterpret_cast<icu::UnicodeString*>(data.GetInternalField(1)); |
| 899 GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter())); | 899 GlobalHandles::Destroy(reinterpret_cast<Object**>(data.GetParameter())); |
| 900 } | 900 } |
| 901 | 901 |
| 902 ICUTimezoneCache::ICUTimezoneCache() { Clear(); } | |
|
jgruber
2017/03/03 08:35:29
I'm surprised this doesn't fail. Clear() deletes t
Dan Ehrenberg
2017/03/03 13:20:27
Wow, not sure how I got this so wrong; I guess I s
| |
| 903 | |
| 904 ICUTimezoneCache::~ICUTimezoneCache() { Clear(); } | |
| 905 | |
| 906 const char* ICUTimezoneCache::LocalTimezone(double time_ms) { | |
| 907 bool is_dst = DaylightSavingsOffset(time_ms) != 0; | |
| 908 char* name = is_dst ? dst_timezone_name_ : timezone_name_; | |
|
jgruber
2017/03/03 08:35:29
The cache is never filled, not sure if that's on p
Dan Ehrenberg
2017/03/03 13:20:27
What do you mean? Why is it never filled? I though
jgruber
2017/03/03 13:29:08
Yup you're right. Sorry, my mistake.
| |
| 909 if (name[0] == '\0') { | |
| 910 icu::UnicodeString result; | |
| 911 GetTimeZone()->getDisplayName(is_dst, icu::TimeZone::SHORT, result); | |
| 912 | |
| 913 // With the SHORT format and the default locale, the result should be of | |
| 914 // the form PST or CET, short and within ASCII range. | |
| 915 int32_t length = result.length(); | |
| 916 CHECK(length < kMaxTimezoneChars); | |
| 917 for (int32_t i = 0; i < length; i++) { | |
| 918 UChar ch = result[i]; | |
| 919 CHECK(ch == static_cast<UChar>(static_cast<char>(ch))); | |
| 920 name[i] = static_cast<char>(ch); | |
| 921 } | |
| 922 name[length] = '\0'; | |
| 923 } | |
| 924 return const_cast<const char*>(name); | |
| 925 } | |
| 926 | |
| 927 icu::TimeZone* ICUTimezoneCache::GetTimeZone() { | |
| 928 if (timezone_ == nullptr) { | |
| 929 timezone_ = icu::TimeZone::createDefault(); | |
| 930 } | |
| 931 return timezone_; | |
| 932 } | |
| 933 | |
| 934 bool ICUTimezoneCache::GetOffsets(double time_ms, int32_t* raw_offset, | |
| 935 int32_t* dst_offset) { | |
| 936 UErrorCode status = U_ZERO_ERROR; | |
| 937 GetTimeZone()->getOffset(time_ms, false, *raw_offset, *dst_offset, status); | |
| 938 if (!U_SUCCESS(status)) return false; | |
|
jgruber
2017/03/03 08:35:29
Nit: return U_SUCCESS(status)
Dan Ehrenberg
2017/03/03 13:20:27
Done, but I would be interested in more feedback h
| |
| 939 return true; | |
| 940 } | |
| 941 | |
| 942 double ICUTimezoneCache::DaylightSavingsOffset(double time_ms) { | |
| 943 int32_t raw_offset, dst_offset; | |
| 944 if (!GetOffsets(time_ms, &raw_offset, &dst_offset)) return 0; | |
| 945 return dst_offset; | |
| 946 } | |
| 947 | |
| 948 double ICUTimezoneCache::LocalTimeOffset() { | |
| 949 int32_t raw_offset, dst_offset; | |
| 950 if (!GetOffsets(icu::Calendar::getNow(), &raw_offset, &dst_offset)) return 0; | |
| 951 return raw_offset; | |
| 952 } | |
| 953 | |
| 954 void ICUTimezoneCache::Clear() { | |
| 955 delete timezone_; | |
| 956 timezone_ = nullptr; | |
| 957 timezone_name_[0] = '\0'; | |
| 958 dst_timezone_name_[0] = '\0'; | |
| 959 } | |
| 960 | |
| 961 ICUOSTimezoneCache::ICUOSTimezoneCache() : os_tz_cache_(nullptr) {} | |
| 962 | |
| 963 ICUOSTimezoneCache::~ICUOSTimezoneCache() { delete os_tz_cache_; } | |
| 964 | |
| 965 const char* ICUOSTimezoneCache::LocalTimezone(double time_ms) { | |
| 966 const char* result = ICUTimezoneCache::LocalTimezone(time_ms); | |
| 967 // ICU often returns timezones which are not as descriptive as they | |
| 968 // could be, e.g., GMT+1 for Europe/Madrid when in en_US. When a timezone | |
| 969 // starts with GMT, call out to the OS to get the 'real' name. | |
|
ulan
2017/03/03 13:20:27
This seems hacky as it breaks the "cache" semantic
Dan Ehrenberg
2017/03/03 15:06:54
I agree that it's hacky, but I'm not sure we'll ge
| |
| 970 if (result[0] == 'G' && result[1] == 'M' && result[2] == 'T') { | |
|
jgruber
2017/03/03 08:35:29
Nit: Another option would be to use strncmp.
Dan Ehrenberg
2017/03/03 13:20:27
Done.
| |
| 971 if (os_tz_cache_ == nullptr) { | |
| 972 os_tz_cache_ = base::OS::CreateTimezoneCache(); | |
| 973 } | |
| 974 return os_tz_cache_->LocalTimezone(time_ms); | |
| 975 } | |
| 976 return result; | |
| 977 } | |
| 978 | |
| 979 void ICUOSTimezoneCache::Clear() { | |
| 980 ICUTimezoneCache::Clear(); | |
| 981 if (os_tz_cache_) os_tz_cache_->Clear(); | |
| 982 } | |
| 983 | |
| 902 } // namespace internal | 984 } // namespace internal |
| 903 } // namespace v8 | 985 } // namespace v8 |
| OLD | NEW |