#include "prx/libc/include/general/VabiMacros.hpp" #include "prx/libc/include/SonyCrt.hpp" #include #include #include #include #include #include #include #include extern "C" void APS5_VABI ignore_handler_s_nid_postfix(const char* message, void* pointer, int error) { SonyIgnoreHandlerS(message, pointer, error); } extern "C" void* APS5_VABI set_constraint_handler_s_nid_postfix(void* handler) { return SonySetConstraintHandlerS(handler); } extern "C" std::size_t APS5_VABI wcstombs_nid_postfix(char* destination, const std::uint16_t* source, std::size_t capacity) { std::size_t count = 0; while (!destination || count < capacity) { const auto value = source[count]; if (value > 255) { errno = 86; return static_cast(-1); } if (destination) destination[count] = static_cast(value); if (value == 0) break; ++count; } return count; } extern "C" int APS5_VABI wcscpy_s_nid_postfix(std::uint16_t* dest, std::size_t size, const std::uint16_t* src) { return SonyWcscpyS(dest, size, src); } extern "C" int APS5_VABI strerror_r_nid_postfix(int error, char* buffer, std::size_t capacity); namespace { std::size_t ReadErrorMessage(int error, char (&message)[128]) { const int result = strerror_r_nid_postfix(error, message, sizeof(message)); if (result != 0 && result != 22) throw std::runtime_error("strerror_s: error message exceeds internal buffer"); return std::strlen(message); } void ErrorMessageConstraint(char* buffer) { SonyConstraintHandler handler; { std::lock_guard lock(SonyConstraintMutex()); handler = SonyConstraintHandlerSlot(); } if (handler == SonyDefaultConstraintHandler) { SonyDefaultConstraintHandler("strerror_s", buffer, 22); } else { using GuestHandler = void (APS5_VABI *)(const char*, void*, int); reinterpret_cast(handler)("strerror_s", buffer, 22); } } } extern "C" std::size_t APS5_VABI strerrorlen_s_nid_postfix(int error) { char message[128]; return ReadErrorMessage(error, message); } extern "C" int APS5_VABI strerror_s_nid_postfix(char* buffer, std::size_t capacity, int error) { if (!buffer || capacity == 0 || capacity > (std::numeric_limits::max() >> 1)) { ErrorMessageConstraint(buffer); return 22; } char message[128]; const auto length = ReadErrorMessage(error, message); if (length < capacity) { std::memcpy(buffer, message, length + 1); return 0; } std::memcpy(buffer, message, capacity - 1); buffer[capacity - 1] = '\0'; if (capacity > 3) std::memcpy(buffer + capacity - 4, "...", 3); return 34; }