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 |