service: time: Rewrite implementation of glue services.
This commit is contained in:
148
src/core/hle/service/time/time_zone_service.cpp
Normal file
148
src/core/hle/service/time/time_zone_service.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
// Copyright 2019 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/service/time/time_zone_content_manager.h"
|
||||
#include "core/hle/service/time/time_zone_service.h"
|
||||
#include "core/hle/service/time/time_zone_types.h"
|
||||
|
||||
namespace Service::Time {
|
||||
|
||||
ITimeZoneService ::ITimeZoneService(TimeZone::TimeZoneContentManager& time_zone_content_manager)
|
||||
: ServiceFramework("ITimeZoneService"), time_zone_content_manager{time_zone_content_manager} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ITimeZoneService::GetDeviceLocationName, "GetDeviceLocationName"},
|
||||
{1, nullptr, "SetDeviceLocationName"},
|
||||
{2, nullptr, "GetTotalLocationNameCount"},
|
||||
{3, nullptr, "LoadLocationNameList"},
|
||||
{4, &ITimeZoneService::LoadTimeZoneRule, "LoadTimeZoneRule"},
|
||||
{5, nullptr, "GetTimeZoneRuleVersion"},
|
||||
{100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"},
|
||||
{101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"},
|
||||
{201, &ITimeZoneService::ToPosixTime, "ToPosixTime"},
|
||||
{202, nullptr, "ToPosixTimeWithMyRule"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
void ITimeZoneService::GetDeviceLocationName(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_Time, "called");
|
||||
|
||||
TimeZone::LocationName location_name{};
|
||||
if (const ResultCode result{
|
||||
time_zone_content_manager.GetTimeZoneManager().GetDeviceLocationName(location_name)};
|
||||
result != RESULT_SUCCESS) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
return;
|
||||
}
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, (sizeof(location_name) / 4) + 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw(location_name);
|
||||
}
|
||||
|
||||
void ITimeZoneService::LoadTimeZoneRule(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto raw_location_name{rp.PopRaw<std::array<u8, 0x24>>()};
|
||||
|
||||
std::string location_name;
|
||||
for (const auto& byte : raw_location_name) {
|
||||
// Strip extra bytes
|
||||
if (byte == '\0') {
|
||||
break;
|
||||
}
|
||||
location_name.push_back(byte);
|
||||
}
|
||||
|
||||
LOG_DEBUG(Service_Time, "called, location_name={}", location_name);
|
||||
|
||||
TimeZone::TimeZoneRule time_zone_rule{};
|
||||
if (const ResultCode result{
|
||||
time_zone_content_manager.LoadTimeZoneRule(time_zone_rule, location_name)};
|
||||
result != RESULT_SUCCESS) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<u8> time_zone_rule_outbuffer(sizeof(TimeZone::TimeZoneRule));
|
||||
std::memcpy(time_zone_rule_outbuffer.data(), &time_zone_rule, sizeof(TimeZone::TimeZoneRule));
|
||||
ctx.WriteBuffer(time_zone_rule_outbuffer);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void ITimeZoneService::ToCalendarTime(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto posix_time{rp.Pop<s64>()};
|
||||
|
||||
LOG_DEBUG(Service_Time, "called, posix_time=0x{:016X}", posix_time);
|
||||
|
||||
TimeZone::TimeZoneRule time_zone_rule{};
|
||||
const auto buffer{ctx.ReadBuffer()};
|
||||
std::memcpy(&time_zone_rule, buffer.data(), buffer.size());
|
||||
|
||||
TimeZone::CalendarInfo calendar_info{};
|
||||
if (const ResultCode result{time_zone_content_manager.GetTimeZoneManager().ToCalendarTime(
|
||||
time_zone_rule, posix_time, calendar_info)};
|
||||
result != RESULT_SUCCESS) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
return;
|
||||
}
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2 + (sizeof(TimeZone::CalendarInfo) / 4)};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw(calendar_info);
|
||||
}
|
||||
|
||||
void ITimeZoneService::ToCalendarTimeWithMyRule(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto posix_time{rp.Pop<s64>()};
|
||||
|
||||
LOG_DEBUG(Service_Time, "called, posix_time=0x{:016X}", posix_time);
|
||||
|
||||
TimeZone::CalendarInfo calendar_info{};
|
||||
if (const ResultCode result{
|
||||
time_zone_content_manager.GetTimeZoneManager().ToCalendarTimeWithMyRules(
|
||||
posix_time, calendar_info)};
|
||||
result != RESULT_SUCCESS) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
return;
|
||||
}
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2 + (sizeof(TimeZone::CalendarInfo) / 4)};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw(calendar_info);
|
||||
}
|
||||
|
||||
void ITimeZoneService::ToPosixTime(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_Time, "called");
|
||||
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto calendar_time{rp.PopRaw<TimeZone::CalendarTime>()};
|
||||
TimeZone::TimeZoneRule time_zone_rule{};
|
||||
std::memcpy(&time_zone_rule, ctx.ReadBuffer().data(), sizeof(TimeZone::TimeZoneRule));
|
||||
|
||||
s64 posix_time{};
|
||||
if (const ResultCode result{time_zone_content_manager.GetTimeZoneManager().ToPosixTime(
|
||||
time_zone_rule, calendar_time, posix_time)};
|
||||
result != RESULT_SUCCESS) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(bunnei): Handle multiple times
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw<u32>(1); // Number of times we're returning
|
||||
ctx.WriteBuffer(&posix_time, sizeof(s64));
|
||||
}
|
||||
|
||||
} // namespace Service::Time
|
||||
Reference in New Issue
Block a user