Files
2026-05-29 21:01:09 -07:00

236 lines
6.2 KiB
C++

#ifndef UTIL_H
#define UTIL_H
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <stdarg.h>
#include <sys/time.h>
#include <time.h>
#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<std::string> Split(const std::string &str, const std::string &delimiter)
{
std::string text = std::string(str);
std::vector<std::string> 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<unsigned char> 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