#ifndef UTIL_H #define UTIL_H #include #include #include #include #include #include #include #include "base64.h" #include "openssl/md5.h" #include "config.h" extern "C" { int sceKernelSendNotificationRequest(int, void *, size_t, int); } typedef struct notify_request { char useless1[45]; char message[3075]; } notify_request_t; namespace Util { static void utf16_to_utf8(const uint16_t *src, uint8_t *dst) { int i; for (i = 0; src[i]; i++) { if ((src[i] & 0xFF80) == 0) { *(dst++) = src[i] & 0xFF; } else if ((src[i] & 0xF800) == 0) { *(dst++) = ((src[i] >> 6) & 0xFF) | 0xC0; *(dst++) = (src[i] & 0x3F) | 0x80; } else if ((src[i] & 0xFC00) == 0xD800 && (src[i + 1] & 0xFC00) == 0xDC00) { *(dst++) = (((src[i] + 64) >> 8) & 0x3) | 0xF0; *(dst++) = (((src[i] >> 2) + 16) & 0x3F) | 0x80; *(dst++) = ((src[i] >> 4) & 0x30) | 0x80 | ((src[i + 1] << 2) & 0xF); *(dst++) = (src[i + 1] & 0x3F) | 0x80; i += 1; } else { *(dst++) = ((src[i] >> 12) & 0xF) | 0xE0; *(dst++) = ((src[i] >> 6) & 0x3F) | 0x80; *(dst++) = (src[i] & 0x3F) | 0x80; } } *dst = '\0'; } static void utf8_to_utf16(const uint8_t *src, uint16_t *dst) { int i; for (i = 0; src[i];) { if ((src[i] & 0xE0) == 0xE0) { *(dst++) = ((src[i] & 0x0F) << 12) | ((src[i + 1] & 0x3F) << 6) | (src[i + 2] & 0x3F); i += 3; } else if ((src[i] & 0xC0) == 0xC0) { *(dst++) = ((src[i] & 0x1F) << 6) | (src[i + 1] & 0x3F); i += 2; } else { *(dst++) = src[i]; i += 1; } } *dst = '\0'; } static std::string &Ltrim(std::string &str, std::string chars) { str.erase(0, str.find_first_not_of(chars)); return str; } static std::string &Rtrim(std::string &str, std::string chars) { str.erase(str.find_last_not_of(chars) + 1); return str; } // trim from both ends (in place) static std::string &Trim(std::string &str, std::string chars) { return Ltrim(Rtrim(str, chars), chars); } static void ReplaceAll(std::string &data, std::string toSearch, std::string replaceStr) { size_t pos = data.find(toSearch); while (pos != std::string::npos) { data.replace(pos, toSearch.size(), replaceStr); pos = data.find(toSearch, pos + replaceStr.size()); } } static std::string ToLower(std::string s) { std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); }); return s; } static bool EndsWith(std::string const &value, std::string const &ending) { if (ending.size() > value.size()) return false; return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); } static std::vector Split(const std::string &str, const std::string &delimiter) { std::string text = std::string(str); std::vector tokens; size_t pos = 0; while ((pos = text.find(delimiter)) != std::string::npos) { if (text.substr(0, pos).length() > 0) tokens.push_back(text.substr(0, pos)); text.erase(0, pos + delimiter.length()); } if (text.length() > 0) { tokens.push_back(text); } return tokens; } static std::string ToString(int value) { std::ostringstream myObjectStream; myObjectStream << value; return myObjectStream.str(); } static std::string UrlHash(const std::string &text) { std::vector res(16); MD5((const unsigned char *)text.c_str(), text.length(), res.data()); std::string out; Base64::Encode(res.data(), res.size(), out); Util::ReplaceAll(out, "=", "a"); Util::ReplaceAll(out, "+", "b"); Util::ReplaceAll(out, "/", "c"); out = out + ".pkg"; return out; } static uint64_t GetTick() { static struct timeval tick; gettimeofday(&tick, NULL); return tick.tv_sec * 1000000 + tick.tv_usec; } static void Notify(const char *fmt, ...) { notify_request_t req; memset(&req, 0, sizeof(req)); va_list args; va_start(args, fmt); vsprintf(req.message, fmt, args); va_end(args); sceKernelSendNotificationRequest(0, &req, sizeof(req), 0); } static size_t NthOccurrence(const std::string &str, const std::string &findMe, int nth, size_t start_pos = 0, size_t end_pos = INT_MAX) { size_t prev_pos = std::string::npos; size_t pos = start_pos; int cnt = 0; while (cnt != nth) { pos += 1; pos = str.find(findMe, pos); if (pos > end_pos) return prev_pos; if (pos == std::string::npos) { if (cnt == 0) return std::string::npos; else break; } prev_pos = pos; cnt++; } return pos; } static size_t CountOccurrence(const std::string &str, const std::string &findMe, size_t start_pos = 0, size_t end_pos = INT_MAX) { size_t pos = start_pos; int cnt = 0; while (true) { pos += 1; pos = str.find(findMe, pos); if (pos > end_pos) return cnt; if (pos == std::string::npos) { break; } pos += 1; cnt++; } return cnt; } } #endif