Files
Xenia-Canary/src/xenia/kernel/xam/user_data.cc

120 lines
3.6 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2024 Xenia Canary. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/kernel/xam/user_data.h"
#include "xenia/base/string_util.h"
#include "xenia/kernel/util/shim_utils.h"
namespace xe {
namespace kernel {
namespace xam {
UserData::UserData() {}
UserData::~UserData() {}
UserData::UserData(const UserData& user_data) {
data_ = user_data.data_;
extended_data_ = user_data.extended_data_;
}
UserData::UserData(X_USER_DATA_TYPE data_type, UserDataTypes user_data) {
data_.data = {};
data_.type = data_type;
switch (data_type) {
case X_USER_DATA_TYPE::BINARY:
extended_data_ = std::get<std::vector<uint8_t>>(user_data);
data_.data.binary.size = static_cast<uint16_t>(extended_data_.size());
break;
case X_USER_DATA_TYPE::WSTRING: {
std::u16string str = std::get<std::u16string>(user_data);
data_.data.unicode.size =
static_cast<uint16_t>(string_util::size_in_bytes(str));
extended_data_.resize(data_.data.unicode.size);
memcpy(extended_data_.data(), reinterpret_cast<uint8_t*>(str.data()),
data_.data.unicode.size);
break;
}
case X_USER_DATA_TYPE::INT32:
data_.data.s32 = std::get<int32_t>(user_data);
break;
case X_USER_DATA_TYPE::FLOAT:
data_.data.f32 = std::get<float>(user_data);
break;
case X_USER_DATA_TYPE::CONTEXT:
data_.data.s32 = std::get<uint32_t>(user_data);
break;
case X_USER_DATA_TYPE::DOUBLE:
data_.data.f64 = std::get<double>(user_data);
break;
case X_USER_DATA_TYPE::DATETIME:
case X_USER_DATA_TYPE::INT64:
data_.data.s64 = std::get<int64_t>(user_data);
break;
default:
assert_always();
}
}
UserData::UserData(const X_USER_DATA_TYPE data_type,
const uint32_t data_max_size, const X_USER_DATA* user_data) {
memcpy(&data_, user_data, sizeof(X_USER_DATA));
data_.type = data_type;
if (requires_additional_data()) {
data_.data.binary.size = std::min(
static_cast<uint32_t>(data_.data.binary.size), kMaxUserDataSize);
if (!data_.data.binary.size) {
return;
}
extended_data_.resize(data_.data.binary.size);
if (!user_data->data.binary.ptr) {
return;
}
memcpy(
extended_data_.data(),
kernel_memory()->TranslateVirtual<uint8_t*>(user_data->data.binary.ptr),
data_.data.binary.size);
}
}
UserData::UserData(X_USER_DATA_TYPE data_type, std::span<const uint8_t> data) {
data_.data = {};
data_.type = data_type;
if (!requires_additional_data()) {
memcpy(&data_.data, data.data(),
std::min(static_cast<size_t>(8), data.size()));
return;
}
data_.data.binary.size = static_cast<uint32_t>(data.size());
extended_data_.insert(extended_data_.begin(), data.begin(), data.end());
}
UserData::UserData(const X_USER_DATA_TYPE data_type,
const X_USER_DATA_UNION* user_data,
std::span<const uint8_t> extended_data) {
data_.type = data_type;
data_.data = *user_data;
if (requires_additional_data()) {
extended_data_.insert(extended_data_.begin(), extended_data.begin(),
extended_data.end());
}
}
} // namespace xam
} // namespace kernel
} // namespace xe