diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/time/time_zone_manager.cpp | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp index 54c9ecf40..24a9aa55d 100644 --- a/src/core/hle/service/time/time_zone_manager.cpp +++ b/src/core/hle/service/time/time_zone_manager.cpp | |||
| @@ -524,6 +524,7 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi | |||
| 524 | 524 | ||
| 525 | constexpr s32 time_zone_max_leaps{50}; | 525 | constexpr s32 time_zone_max_leaps{50}; |
| 526 | constexpr s32 time_zone_max_chars{50}; | 526 | constexpr s32 time_zone_max_chars{50}; |
| 527 | constexpr s32 time_zone_max_times{1000}; | ||
| 527 | if (!(0 <= header.leap_count && header.leap_count < time_zone_max_leaps && | 528 | if (!(0 <= header.leap_count && header.leap_count < time_zone_max_leaps && |
| 528 | 0 < header.type_count && header.type_count < s32(time_zone_rule.ttis.size()) && | 529 | 0 < header.type_count && header.type_count < s32(time_zone_rule.ttis.size()) && |
| 529 | 0 <= header.time_count && header.time_count < s32(time_zone_rule.ats.size()) && | 530 | 0 <= header.time_count && header.time_count < s32(time_zone_rule.ats.size()) && |
| @@ -634,9 +635,66 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi | |||
| 634 | std::array<char, time_zone_name_max> name{}; | 635 | std::array<char, time_zone_name_max> name{}; |
| 635 | std::memcpy(name.data(), temp_name.data() + 1, std::size_t(bytes_read - 1)); | 636 | std::memcpy(name.data(), temp_name.data() + 1, std::size_t(bytes_read - 1)); |
| 636 | 637 | ||
| 638 | // Fill in computed transition times with temp rule | ||
| 637 | TimeZoneRule temp_rule; | 639 | TimeZoneRule temp_rule; |
| 638 | if (ParsePosixName(name.data(), temp_rule)) { | 640 | if (ParsePosixName(name.data(), temp_rule)) { |
| 639 | UNIMPLEMENTED(); | 641 | int have_abbreviation = 0; |
| 642 | int char_count = time_zone_rule.char_count; | ||
| 643 | |||
| 644 | for (int i = 0; i < temp_rule.type_count; i++) { | ||
| 645 | char* temp_abbreviation = | ||
| 646 | temp_rule.chars.data() + temp_rule.ttis[i].abbreviation_list_index; | ||
| 647 | int j; | ||
| 648 | for (j = 0; j < char_count; j++) { | ||
| 649 | if (std::strcmp(time_zone_rule.chars.data() + j, temp_abbreviation) == 0) { | ||
| 650 | temp_rule.ttis[i].abbreviation_list_index = j; | ||
| 651 | have_abbreviation++; | ||
| 652 | break; | ||
| 653 | } | ||
| 654 | } | ||
| 655 | if (j >= char_count) { | ||
| 656 | int temp_abbreviation_length = static_cast<int>(std::strlen(temp_abbreviation)); | ||
| 657 | if (j + temp_abbreviation_length < time_zone_max_chars) { | ||
| 658 | std::strcpy(time_zone_rule.chars.data() + j, temp_abbreviation); | ||
| 659 | char_count = j + temp_abbreviation_length + 1; | ||
| 660 | temp_rule.ttis[i].abbreviation_list_index = j; | ||
| 661 | have_abbreviation++; | ||
| 662 | } | ||
| 663 | } | ||
| 664 | } | ||
| 665 | |||
| 666 | if (have_abbreviation == temp_rule.type_count) { | ||
| 667 | time_zone_rule.char_count = char_count; | ||
| 668 | |||
| 669 | // Original comment: | ||
| 670 | /* Ignore any trailing, no-op transitions generated | ||
| 671 | by zic as they don't help here and can run afoul | ||
| 672 | of bugs in zic 2016j or earlier. */ | ||
| 673 | // This is possibly unnecessary for yuzu, since Nintendo doesn't run zic | ||
| 674 | while (1 < time_zone_rule.time_count && | ||
| 675 | (time_zone_rule.types[time_zone_rule.time_count - 1] == | ||
| 676 | time_zone_rule.types[time_zone_rule.time_count - 2])) { | ||
| 677 | time_zone_rule.time_count--; | ||
| 678 | } | ||
| 679 | |||
| 680 | for (int i = 0; | ||
| 681 | i < temp_rule.time_count && time_zone_rule.time_count < time_zone_max_times; | ||
| 682 | i++) { | ||
| 683 | const s64 transition_time = temp_rule.ats[i]; | ||
| 684 | if (0 < time_zone_rule.time_count && | ||
| 685 | transition_time <= time_zone_rule.ats[time_zone_rule.time_count - 1]) { | ||
| 686 | continue; | ||
| 687 | } | ||
| 688 | |||
| 689 | time_zone_rule.ats[time_zone_rule.time_count] = transition_time; | ||
| 690 | time_zone_rule.types[time_zone_rule.time_count] = | ||
| 691 | static_cast<s8>(time_zone_rule.type_count + temp_rule.types[i]); | ||
| 692 | time_zone_rule.time_count++; | ||
| 693 | } | ||
| 694 | for (int i = 0; i < temp_rule.type_count; i++) { | ||
| 695 | time_zone_rule.ttis[time_zone_rule.type_count++] = temp_rule.ttis[i]; | ||
| 696 | } | ||
| 697 | } | ||
| 640 | } | 698 | } |
| 641 | } | 699 | } |
| 642 | 700 | ||