|
|
|
@ -2,6 +2,7 @@ |
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
|
|
#include <climits>
|
|
|
|
#include <limits>
|
|
|
|
|
|
|
|
#include "common/assert.h"
|
|
|
|
#include "common/logging/log.h"
|
|
|
|
@ -9,6 +10,7 @@ |
|
|
|
#include "core/file_sys/nca_metadata.h"
|
|
|
|
#include "core/file_sys/registered_cache.h"
|
|
|
|
#include "core/hle/service/time/time_zone_manager.h"
|
|
|
|
#include "core/hle/service/time/time_zone_types.h"
|
|
|
|
|
|
|
|
namespace Service::Time::TimeZone { |
|
|
|
|
|
|
|
@ -629,11 +631,47 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi |
|
|
|
UNIMPLEMENTED(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const auto typesequiv = [](TimeZoneRule& rule, int a, int b) -> bool { |
|
|
|
if (a < 0 || a >= rule.type_count || b < 0 || b >= rule.type_count) { |
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
const struct TimeTypeInfo* ap = &rule.ttis[a]; |
|
|
|
const struct TimeTypeInfo* bp = &rule.ttis[b]; |
|
|
|
|
|
|
|
return (ap->gmt_offset == bp->gmt_offset && ap->is_dst == bp->is_dst && |
|
|
|
(std::strcmp(&rule.chars[ap->abbreviation_list_index], |
|
|
|
&rule.chars[bp->abbreviation_list_index]) == 0)); |
|
|
|
}; |
|
|
|
|
|
|
|
if (time_zone_rule.type_count == 0) { |
|
|
|
return {}; |
|
|
|
} |
|
|
|
if (time_zone_rule.time_count > 1) { |
|
|
|
UNIMPLEMENTED(); |
|
|
|
if (time_zone_rule.ats[0] <= std::numeric_limits<s64>::max() - seconds_per_repeat) { |
|
|
|
s64 repeatat = time_zone_rule.ats[0] + seconds_per_repeat; |
|
|
|
int repeatattype = time_zone_rule.types[0]; |
|
|
|
for (int i = 1; i < time_zone_rule.time_count; ++i) { |
|
|
|
if (time_zone_rule.ats[i] == repeatat && |
|
|
|
typesequiv(time_zone_rule, time_zone_rule.types[i], repeatattype)) { |
|
|
|
time_zone_rule.go_back = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (std::numeric_limits<s64>::min() + seconds_per_repeat <= |
|
|
|
time_zone_rule.ats[time_zone_rule.time_count - 1]) { |
|
|
|
s64 repeatat = time_zone_rule.ats[time_zone_rule.time_count - 1] - seconds_per_repeat; |
|
|
|
int repeatattype = time_zone_rule.types[time_zone_rule.time_count - 1]; |
|
|
|
for (int i = time_zone_rule.time_count; i >= 0; --i) { |
|
|
|
if (time_zone_rule.ats[i] == repeatat && |
|
|
|
typesequiv(time_zone_rule, time_zone_rule.types[i], repeatattype)) { |
|
|
|
time_zone_rule.go_ahead = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
s32 default_type{}; |
|
|
|
|