Convert STFS filenames from Win-1252 to UTF-8
This commit is contained in:
parent
60b31af811
commit
6cba5ba7e6
|
@ -14,6 +14,9 @@
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
|
||||||
#include "xenia/base/platform.h"
|
#include "xenia/base/platform.h"
|
||||||
|
#if XE_PLATFORM_WIN32
|
||||||
|
#include "xenia/base/platform_win.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !XE_PLATFORM_WIN32
|
#if !XE_PLATFORM_WIN32
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
@ -58,4 +61,78 @@ std::u16string to_utf16(const std::string_view source) {
|
||||||
return utfcpp::utf8to16(source);
|
return utfcpp::utf8to16(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string utf8_to_win1252(const std::string_view source) {
|
||||||
|
#if XE_PLATFORM_WIN32
|
||||||
|
std::string input_str(source);
|
||||||
|
int srclen = static_cast<int>(input_str.size());
|
||||||
|
|
||||||
|
int wlen =
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, input_str.c_str(), srclen, NULL, 0);
|
||||||
|
if (!wlen) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
std::vector<WCHAR> wbuf(wlen);
|
||||||
|
int result = MultiByteToWideChar(CP_UTF8, 0, input_str.c_str(), srclen,
|
||||||
|
wbuf.data(), wlen);
|
||||||
|
if (!result) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = WideCharToMultiByte(1252, 0, wbuf.data(), wlen, NULL, 0, "_", NULL);
|
||||||
|
if (!len) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
std::vector<CHAR> buf(len);
|
||||||
|
result = WideCharToMultiByte(1252, 0, wbuf.data(), wlen, buf.data(), len, "_",
|
||||||
|
NULL);
|
||||||
|
if (!result) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string output_str(buf.begin(), buf.end());
|
||||||
|
return output_str;
|
||||||
|
#else
|
||||||
|
// TODO: Use iconv on POSIX.
|
||||||
|
std::string output_str(source);
|
||||||
|
return output_str;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string win1252_to_utf8(const std::string_view source) {
|
||||||
|
#if XE_PLATFORM_WIN32
|
||||||
|
std::string input_str(source);
|
||||||
|
int srclen = static_cast<int>(input_str.size());
|
||||||
|
|
||||||
|
int wlen = MultiByteToWideChar(1252, 0, input_str.c_str(), srclen, NULL, 0);
|
||||||
|
if (!wlen) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
std::vector<WCHAR> wbuf(wlen);
|
||||||
|
int result = MultiByteToWideChar(1252, 0, input_str.c_str(), srclen,
|
||||||
|
wbuf.data(), wlen);
|
||||||
|
if (!result) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
int len =
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wlen, NULL, 0, "_", NULL);
|
||||||
|
if (!len) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
std::vector<CHAR> buf(len);
|
||||||
|
result = WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wlen, buf.data(), len,
|
||||||
|
"_", NULL);
|
||||||
|
if (!result) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string output_str(buf.begin(), buf.end());
|
||||||
|
return output_str;
|
||||||
|
#else
|
||||||
|
// TODO: Use iconv on POSIX.
|
||||||
|
std::string output_str(source);
|
||||||
|
return output_str;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
@ -22,6 +22,8 @@ char* xe_strdup(const char* source);
|
||||||
|
|
||||||
std::string to_utf8(const std::u16string_view source);
|
std::string to_utf8(const std::u16string_view source);
|
||||||
std::u16string to_utf16(const std::string_view source);
|
std::u16string to_utf16(const std::string_view source);
|
||||||
|
std::string utf8_to_win1252(const std::string_view source);
|
||||||
|
std::string win1252_to_utf8(const std::string_view source);
|
||||||
|
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,9 @@ bool DiscImageDevice::ReadEntry(ParseState* state, const uint8_t* buffer,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = std::string(name_buffer, name_length);
|
// Filename is stored as Windows-1252, convert it to UTF-8.
|
||||||
|
auto ansi_name = std::string(name_buffer, name_length);
|
||||||
|
auto name = xe::win1252_to_utf8(ansi_name);
|
||||||
|
|
||||||
auto entry = DiscImageEntry::Create(this, parent, name, mmap_.get());
|
auto entry = DiscImageEntry::Create(this, parent, name, mmap_.get());
|
||||||
entry->attributes_ = attributes | kFileAttributeReadOnly;
|
entry->attributes_ = attributes | kFileAttributeReadOnly;
|
||||||
|
|
|
@ -113,8 +113,10 @@ StfsContainerDevice::Result StfsContainerDevice::Read() {
|
||||||
std::unique_ptr<XContentContainerEntry> StfsContainerDevice::ReadEntry(
|
std::unique_ptr<XContentContainerEntry> StfsContainerDevice::ReadEntry(
|
||||||
Entry* parent, MultiFileHandles* files,
|
Entry* parent, MultiFileHandles* files,
|
||||||
const StfsDirectoryEntry* dir_entry) {
|
const StfsDirectoryEntry* dir_entry) {
|
||||||
std::string name(reinterpret_cast<const char*>(dir_entry->name),
|
// Filename is stored as Windows-1252, convert it to UTF-8.
|
||||||
dir_entry->flags.name_length & 0x3F);
|
std::string ansi_name(reinterpret_cast<const char*>(dir_entry->name),
|
||||||
|
dir_entry->flags.name_length & 0x3F);
|
||||||
|
std::string name = xe::win1252_to_utf8(ansi_name);
|
||||||
|
|
||||||
auto entry = XContentContainerEntry::Create(this, parent, name, &files_);
|
auto entry = XContentContainerEntry::Create(this, parent, name, &files_);
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,9 @@ SvodContainerDevice::Result SvodContainerDevice::ReadEntry(
|
||||||
return Result::kReadError;
|
return Result::kReadError;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = std::string(name_buffer.get(), dir_entry.name_length);
|
// Filename is stored as Windows-1252, convert it to UTF-8.
|
||||||
|
auto ansi_name = std::string(name_buffer.get(), dir_entry.name_length);
|
||||||
|
auto name = xe::win1252_to_utf8(ansi_name);
|
||||||
|
|
||||||
// Read the left node
|
// Read the left node
|
||||||
if (dir_entry.node_l) {
|
if (dir_entry.node_l) {
|
||||||
|
|
Loading…
Reference in New Issue