Working on switching to std::string.
This commit is contained in:
parent
01f0b14250
commit
a4dfc23abc
|
@ -13,7 +13,9 @@ namespace alloy {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
namespace ppc {
|
namespace ppc {
|
||||||
|
|
||||||
uint64_t ParseInt64(const char* value) { return xestrtoulla(value, NULL, 0); }
|
uint64_t ParseInt64(const char* value) {
|
||||||
|
return std::strtoull(value, nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void PPCContext::SetRegFromString(const char* name, const char* value) {
|
void PPCContext::SetRegFromString(const char* name, const char* value) {
|
||||||
int n;
|
int n;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
}],
|
}],
|
||||||
['OS == "linux"', {
|
['OS == "linux"', {
|
||||||
'sources': [
|
'sources': [
|
||||||
|
'threading_posix.cc',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
['OS == "mac"', {
|
['OS == "mac"', {
|
||||||
|
|
|
@ -23,4 +23,20 @@ std::wstring to_wstring(const std::string& source) {
|
||||||
return converter.from_bytes(source);
|
return converter.from_bytes(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string::size_type find_first_of_case(const std::string& target,
|
||||||
|
const std::string& search) {
|
||||||
|
const char* str = target.c_str();
|
||||||
|
while (*str) {
|
||||||
|
if (!strncasecmp(str, search.c_str(), search.size())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
if (*str) {
|
||||||
|
return str - target.c_str();
|
||||||
|
} else {
|
||||||
|
return std::string::npos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace poly
|
} // namespace poly
|
||||||
|
|
|
@ -12,13 +12,21 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <poly/config.h>
|
#include <poly/platform.h>
|
||||||
|
|
||||||
|
#if XE_LIKE_WIN32
|
||||||
|
#define strcasecmp _stricmp
|
||||||
|
#define strncasecmp _strnicmp
|
||||||
|
#endif // XE_LIKE_WIN32
|
||||||
|
|
||||||
namespace poly {
|
namespace poly {
|
||||||
|
|
||||||
std::string to_string(const std::wstring& source);
|
std::string to_string(const std::wstring& source);
|
||||||
std::wstring to_wstring(const std::string& source);
|
std::wstring to_wstring(const std::string& source);
|
||||||
|
|
||||||
|
std::string::size_type find_first_of_case(const std::string& target,
|
||||||
|
const std::string& search);
|
||||||
|
|
||||||
} // namespace poly
|
} // namespace poly
|
||||||
|
|
||||||
#endif // POLY_STRING_H_
|
#endif // POLY_STRING_H_
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include <poly/config.h>
|
#include <poly/config.h>
|
||||||
|
|
||||||
|
@ -28,6 +29,8 @@ uint32_t current_thread_id();
|
||||||
|
|
||||||
// Sets the current thread name.
|
// Sets the current thread name.
|
||||||
void set_name(const std::string& name);
|
void set_name(const std::string& name);
|
||||||
|
// Sets the target thread name.
|
||||||
|
void set_name(std::thread::native_handle_type handle, const std::string& name);
|
||||||
|
|
||||||
// Yields the current thread to the scheduler. Maybe.
|
// Yields the current thread to the scheduler. Maybe.
|
||||||
void Yield();
|
void Yield();
|
||||||
|
|
|
@ -25,11 +25,11 @@ uint32_t current_thread_id() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_name(const std::string& name) {
|
void set_name(const std::string& name) {
|
||||||
#if XE_LIKE_OSX
|
|
||||||
pthread_setname_np(name.c_str());
|
pthread_setname_np(name.c_str());
|
||||||
#else
|
}
|
||||||
pthread_setname_np(pthread_self(), name.c_str());
|
|
||||||
#endif // XE_LIKE_OSX
|
void set_name(std::thread::native_handle_type handle, const std::string& name) {
|
||||||
|
// ?
|
||||||
}
|
}
|
||||||
|
|
||||||
void Yield() { pthread_yield_np(); }
|
void Yield() { pthread_yield_np(); }
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <poly/threading.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
namespace poly {
|
||||||
|
namespace threading {
|
||||||
|
|
||||||
|
//uint64_t ticks() { return mach_absolute_time(); }
|
||||||
|
|
||||||
|
// uint32_t current_thread_id() {
|
||||||
|
// mach_port_t tid = pthread_mach_thread_np(pthread_self());
|
||||||
|
// return static_cast<uint32_t>(tid);
|
||||||
|
// }
|
||||||
|
|
||||||
|
void set_name(const std::string& name) {
|
||||||
|
pthread_setname_np(pthread_self(), name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_name(std::thread::native_handle_type handle, const std::string& name) {
|
||||||
|
pthread_setname_np(pthread_self(), name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Yield() { pthread_yield_np(); }
|
||||||
|
|
||||||
|
void Sleep(std::chrono::microseconds duration) {
|
||||||
|
timespec rqtp = {duration.count() / 1000000, duration.count() % 1000};
|
||||||
|
nanosleep(&rqtp, nullptr);
|
||||||
|
// TODO(benvanik): spin while rmtp >0?
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace threading
|
||||||
|
} // namespace poly
|
|
@ -57,6 +57,10 @@ void set_name(const std::string& name) {
|
||||||
set_name(static_cast<DWORD>(-1), name);
|
set_name(static_cast<DWORD>(-1), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_name(std::thread::native_handle_type handle, const std::string& name) {
|
||||||
|
set_name(GetThreadId(handle), name);
|
||||||
|
}
|
||||||
|
|
||||||
void Yield() { SwitchToThread(); }
|
void Yield() { SwitchToThread(); }
|
||||||
|
|
||||||
void Sleep(std::chrono::microseconds duration) {
|
void Sleep(std::chrono::microseconds duration) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ void ExportResolver::RegisterTable(
|
||||||
uint16_t ExportResolver::GetLibraryOrdinal(const char* library_name) {
|
uint16_t ExportResolver::GetLibraryOrdinal(const char* library_name) {
|
||||||
uint16_t n = 0;
|
uint16_t n = 0;
|
||||||
for (auto it = tables_.begin(); it != tables_.end(); ++it, n++) {
|
for (auto it = tables_.begin(); it != tables_.end(); ++it, n++) {
|
||||||
if (!xestrcmpa(library_name, it->name)) {
|
if (!strcmp(library_name, it->name)) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ KernelExport* ExportResolver::GetExportByOrdinal(const char* library_name,
|
||||||
const uint32_t ordinal) {
|
const uint32_t ordinal) {
|
||||||
for (std::vector<ExportTable>::iterator it = tables_.begin();
|
for (std::vector<ExportTable>::iterator it = tables_.begin();
|
||||||
it != tables_.end(); ++it) {
|
it != tables_.end(); ++it) {
|
||||||
if (!xestrcmpa(library_name, it->name)) {
|
if (!strcmp(library_name, it->name)) {
|
||||||
// TODO(benvanik): binary search?
|
// TODO(benvanik): binary search?
|
||||||
for (size_t n = 0; n < it->count; n++) {
|
for (size_t n = 0; n < it->count; n++) {
|
||||||
if (it->exports[n].ordinal == ordinal) {
|
if (it->exports[n].ordinal == ordinal) {
|
||||||
|
|
|
@ -128,7 +128,7 @@ int D3D11VertexShaderResource::Prepare(
|
||||||
XELOGE("D3D11: failed to translate vertex shader");
|
XELOGE("D3D11: failed to translate vertex shader");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
translated_src_ = xestrdupa(translator.translated_src());
|
translated_src_ = strdup(translator.translated_src());
|
||||||
|
|
||||||
ID3D10Blob* shader_blob = D3D11ShaderCompile(
|
ID3D10Blob* shader_blob = D3D11ShaderCompile(
|
||||||
XE_GPU_SHADER_TYPE_VERTEX, translated_src_, disasm_src());
|
XE_GPU_SHADER_TYPE_VERTEX, translated_src_, disasm_src());
|
||||||
|
@ -351,7 +351,7 @@ int D3D11PixelShaderResource::Prepare(const xe_gpu_program_cntl_t& program_cntl,
|
||||||
XELOGE("D3D11: failed to translate pixel shader");
|
XELOGE("D3D11: failed to translate pixel shader");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
translated_src_ = xestrdupa(translator.translated_src());
|
translated_src_ = strdup(translator.translated_src());
|
||||||
|
|
||||||
ID3D10Blob* shader_blob = D3D11ShaderCompile(
|
ID3D10Blob* shader_blob = D3D11ShaderCompile(
|
||||||
XE_GPU_SHADER_TYPE_PIXEL, translated_src_, disasm_src());
|
XE_GPU_SHADER_TYPE_PIXEL, translated_src_, disasm_src());
|
||||||
|
|
|
@ -754,7 +754,7 @@ char* xenos::DisassembleShader(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* result = xestrdupa(output->buffer);
|
char* result = strdup(output->buffer);
|
||||||
delete output;
|
delete output;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,4 @@ using namespace xe::kernel::fs;
|
||||||
|
|
||||||
Device::Device(const std::string& path) : path_(path) {}
|
Device::Device(const std::string& path) : path_(path) {}
|
||||||
|
|
||||||
Device::~Device() {}
|
Device::~Device() = default;
|
||||||
|
|
||||||
const char* Device::path() const { return path_.c_str(); }
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ class Device {
|
||||||
Device(const std::string& path);
|
Device(const std::string& path);
|
||||||
virtual ~Device();
|
virtual ~Device();
|
||||||
|
|
||||||
const char* path() const;
|
const std::string& path() const { return path_; }
|
||||||
|
|
||||||
virtual Entry* ResolvePath(const char* path) = 0;
|
virtual Entry* ResolvePath(const char* path) = 0;
|
||||||
|
|
||||||
|
|
|
@ -29,15 +29,15 @@ DiscImageFile::DiscImageFile(
|
||||||
DiscImageFile::~DiscImageFile() {
|
DiscImageFile::~DiscImageFile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* DiscImageFile::path(void) const {
|
const std::string& DiscImageFile::path() const {
|
||||||
return entry_->path();
|
return entry_->path();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* DiscImageFile::absolute_path(void) const {
|
const std::string& DiscImageFile::absolute_path() const {
|
||||||
return entry_->absolute_path();
|
return entry_->absolute_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* DiscImageFile::name(void) const {
|
const std::string& DiscImageFile::name() const {
|
||||||
return entry_->name();
|
return entry_->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,43 +15,39 @@
|
||||||
|
|
||||||
#include <xenia/kernel/objects/xfile.h>
|
#include <xenia/kernel/objects/xfile.h>
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace fs {
|
namespace fs {
|
||||||
|
|
||||||
class DiscImageEntry;
|
class DiscImageEntry;
|
||||||
|
|
||||||
|
|
||||||
class DiscImageFile : public XFile {
|
class DiscImageFile : public XFile {
|
||||||
public:
|
public:
|
||||||
DiscImageFile(KernelState* kernel_state, uint32_t desired_access,
|
DiscImageFile(KernelState* kernel_state, uint32_t desired_access,
|
||||||
DiscImageEntry* entry);
|
DiscImageEntry* entry);
|
||||||
virtual ~DiscImageFile();
|
~DiscImageFile() override;
|
||||||
|
|
||||||
virtual const char* path(void) const;
|
const std::string& path() const override;
|
||||||
virtual const char* absolute_path(void) const;
|
const std::string& absolute_path() const override;
|
||||||
virtual const char* name(void) const;
|
const std::string& name() const override;
|
||||||
|
|
||||||
virtual X_STATUS QueryInfo(XFileInfo* out_info);
|
X_STATUS QueryInfo(XFileInfo* out_info) override;
|
||||||
virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info,
|
X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length,
|
||||||
size_t length, const char* file_name, bool restart);
|
const char* file_name, bool restart) override;
|
||||||
virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length);
|
X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override;
|
||||||
virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length);
|
X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info,
|
||||||
|
size_t length) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual X_STATUS ReadSync(
|
X_STATUS ReadSync(void* buffer, size_t buffer_length, size_t byte_offset,
|
||||||
void* buffer, size_t buffer_length, size_t byte_offset,
|
size_t* out_bytes_read) override;
|
||||||
size_t* out_bytes_read);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DiscImageEntry* entry_;
|
DiscImageEntry* entry_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace fs
|
} // namespace fs
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
#endif // XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_FILE_H_
|
#endif // XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_FILE_H_
|
||||||
|
|
|
@ -29,15 +29,15 @@ HostPathFile::~HostPathFile() {
|
||||||
CloseHandle(file_handle_);
|
CloseHandle(file_handle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* HostPathFile::path(void) const {
|
const std::string& HostPathFile::path() const {
|
||||||
return entry_->path();
|
return entry_->path();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* HostPathFile::absolute_path(void) const {
|
const std::string& HostPathFile::absolute_path() const {
|
||||||
return entry_->absolute_path();
|
return entry_->absolute_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* HostPathFile::name(void) const {
|
const std::string& HostPathFile::name() const {
|
||||||
return entry_->name();
|
return entry_->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,49 +10,47 @@
|
||||||
#ifndef XENIA_KERNEL_FS_DEVICES_HOST_PATH_FILE_H_
|
#ifndef XENIA_KERNEL_FS_DEVICES_HOST_PATH_FILE_H_
|
||||||
#define XENIA_KERNEL_FS_DEVICES_HOST_PATH_FILE_H_
|
#define XENIA_KERNEL_FS_DEVICES_HOST_PATH_FILE_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <xenia/common.h>
|
#include <xenia/common.h>
|
||||||
#include <xenia/core.h>
|
#include <xenia/core.h>
|
||||||
|
|
||||||
#include <xenia/kernel/objects/xfile.h>
|
#include <xenia/kernel/objects/xfile.h>
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace fs {
|
namespace fs {
|
||||||
|
|
||||||
class HostPathEntry;
|
class HostPathEntry;
|
||||||
|
|
||||||
|
|
||||||
class HostPathFile : public XFile {
|
class HostPathFile : public XFile {
|
||||||
public:
|
public:
|
||||||
HostPathFile(KernelState* kernel_state, uint32_t desired_access,
|
HostPathFile(KernelState* kernel_state, uint32_t desired_access,
|
||||||
HostPathEntry* entry, HANDLE file_handle);
|
HostPathEntry* entry, HANDLE file_handle);
|
||||||
virtual ~HostPathFile();
|
~HostPathFile() override;
|
||||||
|
|
||||||
virtual const char* path(void) const;
|
const std::string& path() const override;
|
||||||
virtual const char* absolute_path(void) const;
|
const std::string& absolute_path() const override;
|
||||||
virtual const char* name(void) const;
|
const std::string& name() const override;
|
||||||
|
|
||||||
virtual X_STATUS QueryInfo(XFileInfo* out_info);
|
X_STATUS QueryInfo(XFileInfo* out_info) override;
|
||||||
virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info,
|
X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length,
|
||||||
size_t length, const char* file_name, bool restart);
|
const char* file_name, bool restart) override;
|
||||||
virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length);
|
X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override;
|
||||||
virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length);
|
X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info,
|
||||||
|
size_t length) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual X_STATUS ReadSync(
|
X_STATUS ReadSync(void* buffer, size_t buffer_length, size_t byte_offset,
|
||||||
void* buffer, size_t buffer_length, size_t byte_offset,
|
size_t* out_bytes_read) override;
|
||||||
size_t* out_bytes_read);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HostPathEntry* entry_;
|
HostPathEntry* entry_;
|
||||||
HANDLE file_handle_;
|
HANDLE file_handle_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace fs
|
} // namespace fs
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
#endif // XENIA_KERNEL_FS_DEVICES_HOST_PATH_FILE_H_
|
#endif // XENIA_KERNEL_FS_DEVICES_HOST_PATH_FILE_H_
|
||||||
|
|
|
@ -29,15 +29,15 @@ STFSContainerFile::STFSContainerFile(
|
||||||
STFSContainerFile::~STFSContainerFile() {
|
STFSContainerFile::~STFSContainerFile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* STFSContainerFile::path(void) const {
|
const std::string& STFSContainerFile::path() const {
|
||||||
return entry_->path();
|
return entry_->path();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* STFSContainerFile::absolute_path(void) const {
|
const std::string& STFSContainerFile::absolute_path() const {
|
||||||
return entry_->absolute_path();
|
return entry_->absolute_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* STFSContainerFile::name(void) const {
|
const std::string& STFSContainerFile::name() const {
|
||||||
return entry_->name();
|
return entry_->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,43 +15,39 @@
|
||||||
|
|
||||||
#include <xenia/kernel/objects/xfile.h>
|
#include <xenia/kernel/objects/xfile.h>
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace fs {
|
namespace fs {
|
||||||
|
|
||||||
class STFSContainerEntry;
|
class STFSContainerEntry;
|
||||||
|
|
||||||
|
|
||||||
class STFSContainerFile : public XFile {
|
class STFSContainerFile : public XFile {
|
||||||
public:
|
public:
|
||||||
STFSContainerFile(KernelState* kernel_state, uint32_t desired_access,
|
STFSContainerFile(KernelState* kernel_state, uint32_t desired_access,
|
||||||
STFSContainerEntry* entry);
|
STFSContainerEntry* entry);
|
||||||
virtual ~STFSContainerFile();
|
~STFSContainerFile() override;
|
||||||
|
|
||||||
virtual const char* path(void) const;
|
const std::string& path() const override;
|
||||||
virtual const char* absolute_path(void) const;
|
const std::string& absolute_path() const override;
|
||||||
virtual const char* name(void) const;
|
const std::string& name() const override;
|
||||||
|
|
||||||
virtual X_STATUS QueryInfo(XFileInfo* out_info);
|
X_STATUS QueryInfo(XFileInfo* out_info) override;
|
||||||
virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info,
|
X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length,
|
||||||
size_t length, const char* file_name, bool restart);
|
const char* file_name, bool restart) override;
|
||||||
virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length);
|
X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override;
|
||||||
virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length);
|
X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info,
|
||||||
|
size_t length) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual X_STATUS ReadSync(
|
X_STATUS ReadSync(void* buffer, size_t buffer_length, size_t byte_offset,
|
||||||
void* buffer, size_t buffer_length, size_t byte_offset,
|
size_t* out_bytes_read) override;
|
||||||
size_t* out_bytes_read);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
STFSContainerEntry* entry_;
|
STFSContainerEntry* entry_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace fs
|
} // namespace fs
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
#endif // XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_FILE_H_
|
#endif // XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_FILE_H_
|
||||||
|
|
|
@ -14,28 +14,17 @@ using namespace xe;
|
||||||
using namespace xe::kernel;
|
using namespace xe::kernel;
|
||||||
using namespace xe::kernel::fs;
|
using namespace xe::kernel::fs;
|
||||||
|
|
||||||
|
MemoryMapping::MemoryMapping(uint8_t* address, size_t length)
|
||||||
|
: address_(address), length_(length) {}
|
||||||
|
|
||||||
MemoryMapping::MemoryMapping(uint8_t* address, size_t length) :
|
MemoryMapping::~MemoryMapping() {}
|
||||||
address_(address), length_(length) {
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryMapping::~MemoryMapping() {
|
Entry::Entry(Type type, Device* device, const std::string& path)
|
||||||
}
|
: type_(type), device_(device), path_(path) {
|
||||||
|
|
||||||
|
|
||||||
Entry::Entry(Type type, Device* device, const char* path) :
|
|
||||||
type_(type),
|
|
||||||
device_(device) {
|
|
||||||
assert_not_null(device);
|
assert_not_null(device);
|
||||||
path_ = xestrdupa(path);
|
absolute_path_ = device->path() + path;
|
||||||
// TODO(benvanik): *shudder*
|
|
||||||
absolute_path_ = xestrdupa((std::string(device->path()) + std::string(path)).c_str());
|
|
||||||
// TODO(benvanik): last index of \, unless \ at end, then before that
|
// TODO(benvanik): last index of \, unless \ at end, then before that
|
||||||
name_ = NULL;
|
name_ = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry::~Entry() {
|
Entry::~Entry() = default;
|
||||||
xe_free(name_);
|
|
||||||
xe_free(path_);
|
|
||||||
xe_free(absolute_path_);
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#ifndef XENIA_KERNEL_FS_ENTRY_H_
|
#ifndef XENIA_KERNEL_FS_ENTRY_H_
|
||||||
#define XENIA_KERNEL_FS_ENTRY_H_
|
#define XENIA_KERNEL_FS_ENTRY_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <xenia/common.h>
|
#include <xenia/common.h>
|
||||||
#include <xenia/core.h>
|
#include <xenia/core.h>
|
||||||
|
|
||||||
|
@ -52,14 +54,14 @@ public:
|
||||||
kTypeDirectory,
|
kTypeDirectory,
|
||||||
};
|
};
|
||||||
|
|
||||||
Entry(Type type, Device* device, const char* path);
|
Entry(Type type, Device* device, const std::string& path);
|
||||||
virtual ~Entry();
|
virtual ~Entry();
|
||||||
|
|
||||||
Type type() const { return type_; }
|
Type type() const { return type_; }
|
||||||
Device* device() const { return device_; }
|
Device* device() const { return device_; }
|
||||||
const char* path() const { return path_; }
|
const std::string& path() const { return path_; }
|
||||||
const char* absolute_path() const { return absolute_path_; }
|
const std::string& absolute_path() const { return absolute_path_; }
|
||||||
const char* name() const { return name_; }
|
const std::string& name() const { return name_; }
|
||||||
|
|
||||||
virtual X_STATUS QueryInfo(XFileInfo* out_info) = 0;
|
virtual X_STATUS QueryInfo(XFileInfo* out_info) = 0;
|
||||||
virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info,
|
virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info,
|
||||||
|
@ -79,9 +81,9 @@ public:
|
||||||
private:
|
private:
|
||||||
Type type_;
|
Type type_;
|
||||||
Device* device_;
|
Device* device_;
|
||||||
char* path_;
|
std::string path_;
|
||||||
char* absolute_path_;
|
std::string absolute_path_;
|
||||||
char* name_;
|
std::string name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <xenia/kernel/fs/filesystem.h>
|
#include <xenia/kernel/fs/filesystem.h>
|
||||||
|
|
||||||
|
#include <poly/string.h>
|
||||||
#include <xenia/kernel/fs/devices/disc_image_device.h>
|
#include <xenia/kernel/fs/devices/disc_image_device.h>
|
||||||
#include <xenia/kernel/fs/devices/host_path_device.h>
|
#include <xenia/kernel/fs/devices/host_path_device.h>
|
||||||
#include <xenia/kernel/fs/devices/stfs_container_device.h>
|
#include <xenia/kernel/fs/devices/stfs_container_device.h>
|
||||||
|
@ -129,24 +130,22 @@ int FileSystem::RegisterSTFSContainerDevice(
|
||||||
return RegisterDevice(path, device);
|
return RegisterDevice(path, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileSystem::CreateSymbolicLink(const char* path, const char* target) {
|
int FileSystem::CreateSymbolicLink(const std::string& path,
|
||||||
symlinks_.insert(std::pair<const char*, const char*>(
|
const std::string& target) {
|
||||||
xestrdupa(path),
|
symlinks_.insert({path, target});
|
||||||
xestrdupa(target)));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileSystem::DeleteSymbolicLink(const char* path) {
|
int FileSystem::DeleteSymbolicLink(const std::string& path) {
|
||||||
std::unordered_map<std::string, std::string>::iterator it =
|
auto& it = symlinks_.find(path);
|
||||||
symlinks_.find(std::string(path));
|
if (it == symlinks_.end()) {
|
||||||
if (it != symlinks_.end()) {
|
return 1;
|
||||||
symlinks_.erase(it);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
return 1;
|
symlinks_.erase(it);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry* FileSystem::ResolvePath(const char* path) {
|
Entry* FileSystem::ResolvePath(const std::string& path) {
|
||||||
// Strip off prefix and pass to device.
|
// Strip off prefix and pass to device.
|
||||||
// e.g., d:\some\PATH.foo -> some\PATH.foo
|
// e.g., d:\some\PATH.foo -> some\PATH.foo
|
||||||
// Support both symlinks and device specifiers, like:
|
// Support both symlinks and device specifiers, like:
|
||||||
|
@ -158,33 +157,24 @@ Entry* FileSystem::ResolvePath(const char* path) {
|
||||||
// Resolve symlinks.
|
// Resolve symlinks.
|
||||||
// TODO(benvanik): more robust symlink handling - right now we assume simple
|
// TODO(benvanik): more robust symlink handling - right now we assume simple
|
||||||
// drive path -> device mappings with nothing nested.
|
// drive path -> device mappings with nothing nested.
|
||||||
char full_path[poly::max_path];
|
std::string full_path = path;
|
||||||
XEIGNORE(xestrcpya(full_path, XECOUNT(full_path), path));
|
for (const auto& it : symlinks_) {
|
||||||
for (std::unordered_map<std::string, std::string>::iterator it =
|
if (poly::find_first_of_case(path, it.first) == 0) {
|
||||||
symlinks_.begin(); it != symlinks_.end(); ++it) {
|
// Found symlink, fixup by replacing the prefix.
|
||||||
if (xestrcasestra(path, it->first.c_str()) == path) {
|
full_path = it.second + full_path.substr(it.first.size());
|
||||||
// Found symlink, fixup.
|
|
||||||
const char* after_path = path + it->first.size();
|
|
||||||
XEIGNORE(xesnprintfa(full_path, XECOUNT(full_path), "%s%s",
|
|
||||||
it->second.c_str(), after_path));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan all devices.
|
// Scan all devices.
|
||||||
for (std::vector<Device*>::iterator it = devices_.begin();
|
for (auto& device : devices_) {
|
||||||
it != devices_.end(); ++it) {
|
if (poly::find_first_of_case(full_path, device->path()) == 0) {
|
||||||
Device* device = *it;
|
// Found! Trim the device prefix off and pass down.
|
||||||
if (xestrcasestra(full_path, device->path()) == full_path) {
|
auto device_path = full_path.substr(device->path().size());
|
||||||
// Found!
|
return device->ResolvePath(device_path.c_str());
|
||||||
// Trim the device prefix off and pass down.
|
|
||||||
char device_path[poly::max_path];
|
|
||||||
XEIGNORE(xestrcpya(device_path, XECOUNT(device_path),
|
|
||||||
full_path + xestrlena(device->path())));
|
|
||||||
return device->ResolvePath(device_path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XELOGE("ResolvePath(%s) failed - no root found", path);
|
XELOGE("ResolvePath(%s) failed - no root found", path.c_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,10 +47,10 @@ class FileSystem {
|
||||||
int RegisterSTFSContainerDevice(const std::string& path,
|
int RegisterSTFSContainerDevice(const std::string& path,
|
||||||
const std::wstring& local_path);
|
const std::wstring& local_path);
|
||||||
|
|
||||||
int CreateSymbolicLink(const char* path, const char* target);
|
int CreateSymbolicLink(const std::string& path, const std::string& target);
|
||||||
int DeleteSymbolicLink(const char* path);
|
int DeleteSymbolicLink(const std::string& path);
|
||||||
|
|
||||||
Entry* ResolvePath(const char* path);
|
Entry* ResolvePath(const std::string& path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Device*> devices_;
|
std::vector<Device*> devices_;
|
||||||
|
|
|
@ -40,7 +40,7 @@ GDFXEntry* GDFXEntry::GetChild(const char* name) {
|
||||||
for (std::vector<GDFXEntry*>::iterator it = children.begin();
|
for (std::vector<GDFXEntry*>::iterator it = children.begin();
|
||||||
it != children.end(); ++it) {
|
it != children.end(); ++it) {
|
||||||
GDFXEntry* entry = *it;
|
GDFXEntry* entry = *it;
|
||||||
if (xestrcasecmpa(entry->name.c_str(), name) == 0) {
|
if (strcasecmp(entry->name.c_str(), name) == 0) {
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ STFSEntry* STFSEntry::GetChild(const char* name) {
|
||||||
// TODO(benvanik): a faster search
|
// TODO(benvanik): a faster search
|
||||||
for (auto it = children.begin(); it != children.end(); ++it) {
|
for (auto it = children.begin(); it != children.end(); ++it) {
|
||||||
STFSEntry* entry = *it;
|
STFSEntry* entry = *it;
|
||||||
if (xestrcasecmpa(entry->name.c_str(), name) == 0) {
|
if (strcasecmp(entry->name.c_str(), name) == 0) {
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,15 +80,15 @@ XModule* KernelState::GetModule(const char* name) {
|
||||||
// NULL name = self.
|
// NULL name = self.
|
||||||
// TODO(benvanik): lookup module from caller address.
|
// TODO(benvanik): lookup module from caller address.
|
||||||
return GetExecutableModule();
|
return GetExecutableModule();
|
||||||
} else if (xestrcasecmpa(name, "xam.xex") == 0) {
|
} else if (strcasecmp(name, "xam.xex") == 0) {
|
||||||
auto module = emulator_->xam();
|
auto module = emulator_->xam();
|
||||||
module->Retain();
|
module->Retain();
|
||||||
return module;
|
return module;
|
||||||
} else if (xestrcasecmpa(name, "xboxkrnl.exe") == 0) {
|
} else if (strcasecmp(name, "xboxkrnl.exe") == 0) {
|
||||||
auto module = emulator_->xboxkrnl();
|
auto module = emulator_->xboxkrnl();
|
||||||
module->Retain();
|
module->Retain();
|
||||||
return module;
|
return module;
|
||||||
} else if (xestrcasecmpa(name, "kernel32.dll") == 0) {
|
} else if (strcasecmp(name, "kernel32.dll") == 0) {
|
||||||
// Some games request this, for some reason. wtf.
|
// Some games request this, for some reason. wtf.
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -127,18 +127,19 @@ class XFile : public XObject {
|
||||||
public:
|
public:
|
||||||
virtual ~XFile();
|
virtual ~XFile();
|
||||||
|
|
||||||
virtual const char* path(void) const = 0;
|
virtual const std::string& path() const = 0;
|
||||||
virtual const char* absolute_path(void) const = 0;
|
virtual const std::string& absolute_path() const = 0;
|
||||||
virtual const char* name(void) const = 0;
|
virtual const std::string& name() const = 0;
|
||||||
|
|
||||||
size_t position() const { return position_; }
|
size_t position() const { return position_; }
|
||||||
void set_position(size_t value) { position_ = value; }
|
void set_position(size_t value) { position_ = value; }
|
||||||
|
|
||||||
virtual X_STATUS QueryInfo(XFileInfo* out_info) = 0;
|
virtual X_STATUS QueryInfo(XFileInfo* out_info) = 0;
|
||||||
virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info,
|
virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length,
|
||||||
size_t length, const char* file_name, bool restart) = 0;
|
const char* file_name, bool restart) = 0;
|
||||||
virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) = 0;
|
virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) = 0;
|
||||||
virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length) = 0;
|
virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info,
|
||||||
|
size_t length) = 0;
|
||||||
|
|
||||||
X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
||||||
size_t* out_bytes_read);
|
size_t* out_bytes_read);
|
||||||
|
|
|
@ -42,7 +42,6 @@ XThread::XThread(KernelState* kernel_state,
|
||||||
thread_state_address_(0),
|
thread_state_address_(0),
|
||||||
thread_state_(0),
|
thread_state_(0),
|
||||||
event_(NULL),
|
event_(NULL),
|
||||||
name_(0),
|
|
||||||
irql_(0) {
|
irql_(0) {
|
||||||
creation_params_.stack_size = stack_size;
|
creation_params_.stack_size = stack_size;
|
||||||
creation_params_.xapi_thread_startup = xapi_thread_startup;
|
creation_params_.xapi_thread_startup = xapi_thread_startup;
|
||||||
|
@ -95,9 +94,6 @@ XThread::~XThread() {
|
||||||
if (thread_state_address_) {
|
if (thread_state_address_) {
|
||||||
kernel_state()->memory()->HeapFree(thread_state_address_, 0);
|
kernel_state()->memory()->HeapFree(thread_state_address_, 0);
|
||||||
}
|
}
|
||||||
if (name_) {
|
|
||||||
xe_free(name_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thread_handle_) {
|
if (thread_handle_) {
|
||||||
// TODO(benvanik): platform kill
|
// TODO(benvanik): platform kill
|
||||||
|
@ -149,35 +145,9 @@ void XThread::set_last_error(uint32_t error_code) {
|
||||||
poly::store_and_swap<uint32_t>(p + 0x160, error_code);
|
poly::store_and_swap<uint32_t>(p + 0x160, error_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XThread::set_name(const char* name) {
|
void XThread::set_name(const std::string& name) {
|
||||||
if (name == name_) {
|
name_ = name;
|
||||||
return;
|
poly::threading::set_name(thread_handle_, name);
|
||||||
}
|
|
||||||
if (name_) {
|
|
||||||
xe_free(name_);
|
|
||||||
}
|
|
||||||
name_ = xestrdupa(name);
|
|
||||||
|
|
||||||
#if XE_PLATFORM_WIN32
|
|
||||||
// Do the nasty set for us.
|
|
||||||
#pragma pack(push, 8)
|
|
||||||
typedef struct tagTHREADNAME_INFO {
|
|
||||||
DWORD dwType; // must be 0x1000
|
|
||||||
LPCSTR szName; // pointer to name (in user addr space)
|
|
||||||
DWORD dwThreadID; // thread ID (-1=caller thread)
|
|
||||||
DWORD dwFlags; // reserved for future use, must be zero
|
|
||||||
} THREADNAME_INFO;
|
|
||||||
#pragma pack(pop)
|
|
||||||
THREADNAME_INFO info;
|
|
||||||
info.dwType = 0x1000;
|
|
||||||
info.szName = name_;
|
|
||||||
info.dwThreadID = ::GetThreadId(thread_handle_);
|
|
||||||
info.dwFlags = 0;
|
|
||||||
__try {
|
|
||||||
RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
|
|
||||||
} __except(EXCEPTION_CONTINUE_EXECUTION) {
|
|
||||||
}
|
|
||||||
#endif // WIN32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS XThread::Create() {
|
X_STATUS XThread::Create() {
|
||||||
|
@ -287,7 +257,7 @@ X_STATUS XThread::Exit(int exit_code) {
|
||||||
|
|
||||||
static uint32_t __stdcall XThreadStartCallbackWin32(void* param) {
|
static uint32_t __stdcall XThreadStartCallbackWin32(void* param) {
|
||||||
XThread* thread = reinterpret_cast<XThread*>(param);
|
XThread* thread = reinterpret_cast<XThread*>(param);
|
||||||
xe::Profiler::ThreadEnter(thread->name());
|
xe::Profiler::ThreadEnter(thread->name().c_str());
|
||||||
current_thread_tls = thread;
|
current_thread_tls = thread;
|
||||||
thread->Execute();
|
thread->Execute();
|
||||||
current_thread_tls = nullptr;
|
current_thread_tls = nullptr;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <xenia/kernel/xobject.h>
|
#include <xenia/kernel/xobject.h>
|
||||||
|
|
||||||
|
@ -44,8 +45,8 @@ public:
|
||||||
uint32_t thread_id();
|
uint32_t thread_id();
|
||||||
uint32_t last_error();
|
uint32_t last_error();
|
||||||
void set_last_error(uint32_t error_code);
|
void set_last_error(uint32_t error_code);
|
||||||
const char* name() const { return name_; }
|
const std::string& name() const { return name_; }
|
||||||
void set_name(const char* name);
|
void set_name(const std::string& name);
|
||||||
|
|
||||||
X_STATUS Create();
|
X_STATUS Create();
|
||||||
X_STATUS Exit(int exit_code);
|
X_STATUS Exit(int exit_code);
|
||||||
|
@ -96,7 +97,7 @@ private:
|
||||||
uint32_t thread_state_address_;
|
uint32_t thread_state_address_;
|
||||||
cpu::XenonThreadState* thread_state_;
|
cpu::XenonThreadState* thread_state_;
|
||||||
|
|
||||||
char* name_;
|
std::string name_;
|
||||||
|
|
||||||
std::atomic<uint32_t> irql_;
|
std::atomic<uint32_t> irql_;
|
||||||
std::mutex apc_lock_;
|
std::mutex apc_lock_;
|
||||||
|
|
|
@ -139,7 +139,7 @@ X_STATUS XUserModule::GetSection(
|
||||||
auto header = xe_xex2_get_header(xex_);
|
auto header = xe_xex2_get_header(xex_);
|
||||||
for (size_t n = 0; n < header->resource_info_count; n++) {
|
for (size_t n = 0; n < header->resource_info_count; n++) {
|
||||||
auto& res = header->resource_infos[n];
|
auto& res = header->resource_infos[n];
|
||||||
if (xestrcmpa(name, res.name) == 0) {
|
if (strcmp(name, res.name) == 0) {
|
||||||
// Found!
|
// Found!
|
||||||
*out_section_data = res.address;
|
*out_section_data = res.address;
|
||||||
*out_section_size = res.size;
|
*out_section_size = res.size;
|
||||||
|
|
|
@ -902,7 +902,7 @@ int xe_xex2_load_pe(xe_xex2_ref xex) {
|
||||||
const PESection* xe_xex2_get_pe_section(xe_xex2_ref xex, const char* name) {
|
const PESection* xe_xex2_get_pe_section(xe_xex2_ref xex, const char* name) {
|
||||||
for (std::vector<PESection*>::iterator it = xex->sections->begin();
|
for (std::vector<PESection*>::iterator it = xex->sections->begin();
|
||||||
it != xex->sections->end(); ++it) {
|
it != xex->sections->end(); ++it) {
|
||||||
if (!xestrcmpa((*it)->name, name)) {
|
if (!strcmp((*it)->name, name)) {
|
||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
'platform.h',
|
'platform.h',
|
||||||
'profiling.cc',
|
'profiling.cc',
|
||||||
'profiling.h',
|
'profiling.h',
|
||||||
'string.cc',
|
|
||||||
'string.h',
|
'string.h',
|
||||||
'types.h',
|
'types.h',
|
||||||
'xbox.h',
|
'xbox.h',
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xenia/string.h>
|
|
||||||
|
|
||||||
#include <xenia/common.h>
|
|
||||||
|
|
||||||
|
|
||||||
#if XE_PLATFORM_WIN32
|
|
||||||
|
|
||||||
char* xestrcasestra(const char* str, const char* substr) {
|
|
||||||
const size_t len = xestrlena(substr);
|
|
||||||
while (*str) {
|
|
||||||
if (!_strnicmp(str, substr, len)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
str++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*str) {
|
|
||||||
return (char*)str;
|
|
||||||
} else {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // WIN32
|
|
|
@ -11,46 +11,32 @@
|
||||||
#define XENIA_STRING_H_
|
#define XENIA_STRING_H_
|
||||||
|
|
||||||
#include <xenia/platform.h>
|
#include <xenia/platform.h>
|
||||||
|
#include <poly/string.h>
|
||||||
|
|
||||||
// NOTE: these differing implementations should behave pretty much the same.
|
// NOTE: these differing implementations should behave pretty much the same.
|
||||||
// If they don't, then they will have to be abstracted out.
|
// If they don't, then they will have to be abstracted out.
|
||||||
|
|
||||||
#define XEInvalidSize ((size_t)(-1))
|
|
||||||
|
|
||||||
#if !XE_LIKE_WIN32
|
#if !XE_LIKE_WIN32
|
||||||
int strncpy_s(char* dest, size_t destLength, const char* source, size_t count);
|
int strncpy_s(char* dest, size_t destLength, const char* source, size_t count);
|
||||||
#define strcpy_s(dest, destLength, source) !(strcpy(dest, source) == dest + (destLength*0))
|
#define strcpy_s(dest, destLength, source) !(strcpy(dest, source) == dest + (destLength*0))
|
||||||
#define strcat_s(dest, destLength, source) !(strcat(dest, source) == dest + (destLength*0))
|
#define strcat_s(dest, destLength, source) !(strcat(dest, source) == dest + (destLength*0))
|
||||||
#define _snprintf_s(dest, destLength, x, format, ...) snprintf(dest, destLength, format, ##__VA_ARGS__)
|
#define _snprintf_s(dest, destLength, x, format, ...) snprintf(dest, destLength, format, ##__VA_ARGS__)
|
||||||
#define xestrdupa strdup
|
#define xestrdupa strdup
|
||||||
#define xestrtoulla strtoull
|
|
||||||
#define xestrcasestra strcasestr
|
|
||||||
#else
|
#else
|
||||||
#define strcasecmp _stricmp
|
|
||||||
#define xestrdupa _strdup
|
#define xestrdupa _strdup
|
||||||
#define xestrtoullw _wcstoui64
|
|
||||||
#define xestrtoulla _strtoui64
|
|
||||||
char* xestrcasestra(const char* str, const char* substr);
|
|
||||||
#endif // !WIN32
|
#endif // !WIN32
|
||||||
|
|
||||||
#define xestrlenw wcslen
|
#define xestrlenw wcslen
|
||||||
#define xestrcmpw wcscmp
|
|
||||||
#define xestrcasecmpw _wcsicmp
|
|
||||||
#define xestrdupw _wcsdup
|
#define xestrdupw _wcsdup
|
||||||
#define xestrchrw wcschr
|
#define xestrchrw wcschr
|
||||||
#define xestrrchrw wcsrchr
|
#define xestrrchrw wcsrchr
|
||||||
#define xestrcasestrw ??
|
|
||||||
#define xestrcpyw(dest, destLength, source) (wcscpy_s(dest, destLength, source) == 0)
|
#define xestrcpyw(dest, destLength, source) (wcscpy_s(dest, destLength, source) == 0)
|
||||||
#define xestrncpyw(dest, destLength, source, count) (wcsncpy_s(dest, destLength, source, count) == 0)
|
#define xestrncpyw(dest, destLength, source, count) (wcsncpy_s(dest, destLength, source, count) == 0)
|
||||||
#define xestrcatw(dest, destLength, source) (wcscat_s(dest, destLength, source) == 0)
|
#define xestrcatw(dest, destLength, source) (wcscat_s(dest, destLength, source) == 0)
|
||||||
#define xesnprintfw(buffer, bufferCount, format, ...) _snwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, ##__VA_ARGS__)
|
#define xesnprintfw(buffer, bufferCount, format, ...) _snwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, ##__VA_ARGS__)
|
||||||
#define xevsnprintfw(buffer, bufferCount, format, args) _vsnwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, args)
|
#define xevsnprintfw(buffer, bufferCount, format, args) _vsnwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, args)
|
||||||
#define xevscprintfw(format, args) _vscwprintf(format, args)
|
|
||||||
|
|
||||||
#define xestrlena strlen
|
#define xestrlena strlen
|
||||||
#define xestrcmpa strcmp
|
|
||||||
#define xestrcasecmpa strcasecmp
|
|
||||||
#define xestrchra strchr
|
#define xestrchra strchr
|
||||||
#define xestrrchra strrchr
|
#define xestrrchra strrchr
|
||||||
#define xestrcpya(dest, destLength, source) (strcpy_s(dest, destLength, source) == 0)
|
#define xestrcpya(dest, destLength, source) (strcpy_s(dest, destLength, source) == 0)
|
||||||
|
@ -65,13 +51,9 @@ typedef wchar_t xechar_t;
|
||||||
#define XE_WCHAR 1
|
#define XE_WCHAR 1
|
||||||
|
|
||||||
#define xestrlen xestrlenw
|
#define xestrlen xestrlenw
|
||||||
#define xestrcmp xestrcmpw
|
|
||||||
#define xestrcasecmp xestrcasecmpw
|
|
||||||
#define xestrdup xestrdupw
|
#define xestrdup xestrdupw
|
||||||
#define xestrchr xestrchrw
|
#define xestrchr xestrchrw
|
||||||
#define xestrrchr xestrrchrw
|
#define xestrrchr xestrrchrw
|
||||||
#define xestrcasestr xestrcasestrw
|
|
||||||
#define xestrtoull xestrtoullw
|
|
||||||
#define xestrcpy xestrcpyw
|
#define xestrcpy xestrcpyw
|
||||||
#define xestrncpy xestrncpyw
|
#define xestrncpy xestrncpyw
|
||||||
#define xestrcat xestrcatw
|
#define xestrcat xestrcatw
|
||||||
|
@ -86,13 +68,9 @@ typedef char xechar_t;
|
||||||
#define XE_CHAR 1
|
#define XE_CHAR 1
|
||||||
|
|
||||||
#define xestrlen xestrlena
|
#define xestrlen xestrlena
|
||||||
#define xestrcmp xestrcmpa
|
|
||||||
#define xestrcasecmp xestrcasecmpa
|
|
||||||
#define xestrdup xestrdupa
|
#define xestrdup xestrdupa
|
||||||
#define xestrchr xestrchra
|
#define xestrchr xestrchra
|
||||||
#define xestrrchr xestrrchra
|
#define xestrrchr xestrrchra
|
||||||
#define xestrcasestr xestrcasestra
|
|
||||||
#define xestrtoull xestrtoulla
|
|
||||||
#define xestrcpy xestrcpya
|
#define xestrcpy xestrcpya
|
||||||
#define xestrncpy xestrncpya
|
#define xestrncpy xestrncpya
|
||||||
#define xestrcat xestrcata
|
#define xestrcat xestrcata
|
||||||
|
|
Loading…
Reference in New Issue