36#include <sys/system_properties.h>
42inline size_t KTGetPageSize()
44 static long pageSize = 0;
47 pageSize = sysconf(_SC_PAGESIZE);
49 return pageSize > 0 ?
static_cast<size_t>(pageSize) : 4096;
52#define KT_PAGE_SIZE (KTGetPageSize())
53#define KT_PAGE_START(x) (uintptr_t(x) & ~(KT_PAGE_SIZE - 1))
54#define KT_PAGE_END(x) (KT_PAGE_START(uintptr_t(x) + KT_PAGE_SIZE - 1))
55#define KT_PAGE_OFFSET(x) (uintptr_t(x) - KT_PAGE_START(x))
56#define KT_PAGE_REMAIN(x) (size_t(KT_PAGE_SIZE - KT_PAGE_OFFSET(x)))
58#define KT_ALIGN_UP(ptr, align) (((uintptr_t)(ptr) + (align) - 1) & ~((align) - 1))
59#define KT_ALIGN_DOWN(ptr, align) (((uintptr_t)(ptr)) & ~((uintptr_t)(align) - 1))
61#define KT_IS_ALIGNED_OF(ptr, align) ((((uintptr_t)(ptr)) & ((uintptr_t)(align) - 1)) == 0)
63#define KT_IO_CHUNK_SIZE ((size_t)(1024 * 1024))
65#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
66typedef off_t kt_off64_t;
67typedef struct stat kt_stat64_t;
68#define kt_lseek64 ::lseek
69#define kt_pread64 ::pread
70#define kt_pwrite64 ::pwrite
71#define kt_stat64 ::stat
73typedef off64_t kt_off64_t;
74typedef struct stat64 kt_stat64_t;
75#define kt_lseek64 ::lseek64
76#define kt_pread64 ::pread64
77#define kt_pwrite64 ::pwrite64
78#define kt_stat64 ::stat64
81#define KT_EINTR_RETRY(exp) \
83 __typeof__(exp) _rc; \
87 } while (_rc == -1 && errno == EINTR); \
91#if defined(__ANDROID__) && defined(kUSE_LOGCAT)
93#include <android/log.h>
94#define KITTY_LOG_TAG "KittyMemoryEx"
96#ifdef kITTYMEMORY_DEBUG
97#define KITTY_LOGD(fmt, ...) ((void)__android_log_print(ANDROID_LOG_DEBUG, KITTY_LOG_TAG, fmt, ##__VA_ARGS__))
99#define KITTY_LOGD(fmt, ...) \
105#define KITTY_LOGI(fmt, ...) ((void)__android_log_print(ANDROID_LOG_INFO, KITTY_LOG_TAG, fmt, ##__VA_ARGS__))
106#define KITTY_LOGE(fmt, ...) ((void)__android_log_print(ANDROID_LOG_ERROR, KITTY_LOG_TAG, fmt, ##__VA_ARGS__))
107#define KITTY_LOGW(fmt, ...) ((void)__android_log_print(ANDROID_LOG_WARN, KITTY_LOG_TAG, fmt, ##__VA_ARGS__))
111#ifdef kITTYMEMORY_DEBUG
112#define KITTY_LOGD(fmt, ...) \
115 printf("D: " fmt "\n", ##__VA_ARGS__); \
118#define KITTY_LOGD(fmt, ...) \
124#define KITTY_LOGI(fmt, ...) \
127 printf("I: " fmt "\n", ##__VA_ARGS__); \
130#define KITTY_LOGE(fmt, ...) \
135 fprintf(stderr, "E: " fmt "\n", ##__VA_ARGS__); \
139#define KITTY_LOGW(fmt, ...) \
142 printf("W: " fmt "\n", ##__VA_ARGS__); \
149#define KT_ELFCLASS_BITS 64
150#define KT_ELF_EICLASS 2
151#define KT_ElfW(x) Elf64_##x
152#define KT_ELFW(x) ELF64_##x
154#define KT_ELFCLASS_BITS 32
155#define KT_ELF_EICLASS 1
156#define KT_ElfW(x) Elf32_##x
157#define KT_ELFW(x) ELF32_##x
159#define KT_ELF_ST_BIND(val) (((unsigned char)(val)) >> 4)
160#define KT_ELF_ST_TYPE(val) ((val) & 0xf)
161#define KT_ELF_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
162#define KT_ELF_ST_VISIBILITY(o) ((o) & 0x03)
176 explicit KTScopedFD(
int fd) : _fd(fd)
183 KT_EINTR_RETRY(close(_fd));
191 KTScopedFD(
const KTScopedFD &) =
delete;
192 KTScopedFD &operator=(
const KTScopedFD &) =
delete;
204 KTScopedMMap(
void *ptr,
size_t size) : _ptr(ptr), _size(size)
210 if (_ptr && _ptr != MAP_FAILED)
214 uint8_t *data()
const
216 return static_cast<uint8_t *
>(_ptr);
226 return _ptr && _ptr != MAP_FAILED;
240 inline int getUserId()
242 uid_t uid = getuid();
257 template <
typename T>
261 std::is_same_v<T, std::string> || std::is_same_v<T, bool> || std::is_integral_v<T> ||
262 std::is_floating_point_v<T>,
263 "getSystemProperty: unsupported type. Supported types: string, bool, integral, floating-point.");
265 char value[PROP_VALUE_MAX] = {0};
266 int len = __system_property_get(key.c_str(), value);
270 if constexpr (std::is_same_v<T, std::string>)
272 return std::string(value, len);
274 else if constexpr (std::is_same_v<T, bool>)
276 for (
int i = 0; i < len; ++i)
277 value[i] = std::tolower(value[i]);
279 if (std::strcmp(value,
"1") == 0 || std::strcmp(value,
"true") == 0 || std::strcmp(value,
"y") == 0 ||
280 std::strcmp(value,
"yes") == 0)
283 if (std::strcmp(value,
"0") == 0 || std::strcmp(value,
"false") == 0 || std::strcmp(value,
"n") == 0 ||
284 std::strcmp(value,
"no") == 0)
289 else if constexpr (std::is_integral_v<T>)
292 long long result = std::strtoll(value, &end, 0);
295 return static_cast<T
>(result);
297 else if constexpr (std::is_floating_point_v<T>)
300 double result = std::strtod(value, &end);
303 return static_cast<T
>(result);
337 const char *storage = std::getenv(
"EXTERNAL_STORAGE");
338 return (storage && storage[0] !=
'\0') ? storage :
"/sdcard";
476#if defined(__LP64__) && defined(__ANDROID__)
477 return ptr & ((
static_cast<uintptr_t
>(1) << 56) - 1);
489 template <
typename T>
492 return reinterpret_cast<T *
>(
untagPointer(
reinterpret_cast<uintptr_t
>(ptr)));
501 template <
typename T>
504 return reinterpret_cast<const T *
>(
untagPointer(
reinterpret_cast<uintptr_t
>(ptr)));
550 return std::tolower(
static_cast<unsigned char>(a)) == std::tolower(
static_cast<unsigned char>(b));
562 bool startsWith(
const std::string &str,
const std::string &prefix,
bool sensitive =
true);
573 bool startsWith(
const std::string &str,
const std::vector<std::string> &prefixes,
bool sensitive =
true);
584 bool contains(
const std::string &str,
const std::string &substring,
bool sensitive =
true);
595 bool contains(
const std::string &str,
const std::vector<std::string> &substrings,
bool sensitive =
true);
606 bool endsWith(
const std::string &str,
const std::string &suffix,
bool sensitive =
true);
617 bool endsWith(
const std::string &str,
const std::vector<std::string> &suffixes,
bool sensitive =
true);
670 template <
typename T>
673 using param_type =
typename std::uniform_int_distribution<T>::param_type;
675 static std::mutex mtx;
676 std::lock_guard<std::mutex> lock(mtx);
678 static std::mt19937 gen{std::random_device{}()};
680 std::uniform_int_distribution<T> dist;
681 return dist(gen, param_type{min, max});
724 std::string
toHex(
const void *data,
const size_t dataLength);
734 template <
typename T>
737 return toHex(&data,
sizeof(T));
757 template <
size_t rowSize = 8,
bool showASCII = true>
758 std::string
hexDump(
const void *address,
size_t len)
760 if (!address || len == 0 || rowSize == 0)
763 const unsigned char *data =
static_cast<const unsigned char *
>(address);
765 std::stringstream ss;
766 ss << std::hex << std::uppercase << std::setfill(
'0');
770 for (i = 0; i < len; i += rowSize)
773 ss << std::setw(8) << i <<
": ";
776 for (j = 0; (j < rowSize) && ((i + j) < len); j++)
777 ss << std::setw(2) <<
static_cast<unsigned int>(data[i + j]) <<
" ";
780 for (; j < rowSize; j++)
788 for (j = 0; (j < rowSize) && ((i + j) < len); j++)
790 if (std::isprint(data[i + j]))
816 uint64_t entries = 0;
825 std::string fileName;
826 uint64_t compressedSize = 0;
827 uint64_t uncompressedSize = 0;
828 uint16_t compressionMethod = 0;
830 uint16_t modTime = 0;
831 uint16_t modDate = 0;
832 uint64_t dataOffset = 0;
840 void *mappingBase =
nullptr;
841 size_t mappingSize = 0;
842 uint8_t *data =
nullptr;
Provides utility functions for Android.
Definition KittyUtils.hpp:239
std::string getAppInternalDataDir(const std::string &packageName)
Get the Android app-specific internal data directory.
std::string getAppExternalDataDir(const std::string &packageName)
Get the Android app-specific external data directory.
Definition KittyUtils.hpp:394
std::string getAppExternalFilesDir(const std::string &packageName)
Get the Android app-specific external files directory.
Definition KittyUtils.hpp:411
std::string getExternalStorage()
Get the base external storage directory.
Definition KittyUtils.hpp:335
std::string getAppObbDir(const std::string &packageName)
Get the Android app-specific OBB directory.
Definition KittyUtils.hpp:456
bool is64BitSupported()
Returns true if Android operating system supports 64bit.
int getSDK()
Returns the SDK version of the Android operating system.
T getSystemProperty(const std::string &key, T defaultValue)
Get an Android system property as a typed value.
Definition KittyUtils.hpp:258
std::string getAppInternalFilesDir(const std::string &packageName)
Get the Android app-specific internal files directory.
std::string getAppInternalCacheDir(const std::string &packageName)
Get the Android app-specific internal cache directory. the system usually sets the TMPDIR environment...
int getVersion()
Returns the version of the Android operating system.
std::string getAppExternalMediaDir(const std::string &packageName)
Get the Android app-specific external media directory (Android 10+).
Definition KittyUtils.hpp:442
std::string getAppExternalCacheDir(const std::string &packageName)
Get the Android app-specific external cache directory.
Definition KittyUtils.hpp:428
Provides utility functions for data.
Definition KittyUtils.hpp:704
bool fromHex(std::string in, void *data)
Converts a hexadecimal string to a binary data buffer.
std::string hexDump(const void *address, size_t len)
Hex dumps the memory block at the specified address.
Definition KittyUtils.hpp:758
std::string toHex(const void *data, const size_t dataLength)
Converts binary data to a hexadecimal string.
Provides utility functions for paths.
Definition KittyUtils.hpp:511
std::string fileExtension(const std::string &filePath)
Extracts the file extension from a given file path.
std::string fileDirectory(const std::string &filePath)
Extracts the directory from a given file path.
std::string fileName(const std::string &filePath)
Extracts the file name from a given file path.
Provides utility functions for strings.
Definition KittyUtils.hpp:544
bool charEqualsIgnoreCase(char a, char b)
Helper to compare two characters case-insensitively.
Definition KittyUtils.hpp:548
void trim(std::string &str)
Trims whitespace from the beginning and end of a string.
bool startsWith(const std::string &str, const std::string &prefix, bool sensitive=true)
Checks if a string starts with a given prefix.
bool contains(const std::string &str, const std::string &substring, bool sensitive=true)
Checks if a string contains a given substring.
bool validateHex(std::string &hex)
Validates a hexadecimal string.
std::string fmt(const char *fmt,...)
Formats a string using a printf-style format.
void removeAllWhitespace(std::string &str)
Removes all whitespace characters from a string, not just leading/trailing.
bool endsWith(const std::string &str, const std::string &suffix, bool sensitive=true)
Checks if a string ends with a given suffix.
bool isValidHex(const std::string &hex)
Checks if the provided string is a valid hexadecimal representation.
Provides utility functions for handling ZIP files.
Definition KittyUtils.hpp:808
std::vector< ZipEntryInfo > listEntriesInZip(const std::string &zipPath)
Lists all entries in a ZIP file.
bool findEntryInfoByDataOffset(const std::string &zipPath, uint64_t dataOffset, ZipEntryInfo *out)
Finds the ZipEntryInfo for an entry by its data offset.
bool findCentralDirectory(const uint8_t *data, uint64_t fileSize, CentralDirectoryInfo *info)
Finds the central directory of a ZIP file.
bool mmapEntryByDataOffset(const std::string &zipPath, uint64_t dataOffset, ZipEntryMMap *out)
Maps an entry in a ZIP file by its data offset.
Provides general utility functions.
Definition KittyUtils.hpp:168
std::string randomString(size_t length)
Generates a random string of a specified length.
std::vector< uint8_t > randomBytes(std::size_t length)
Generates a random bytes of a specified length.
uintptr_t untagPointer(uintptr_t ptr)
Removes AArch64 top-byte pointer tags from an address.
Definition KittyUtils.hpp:474
T randInt(T min, T max)
Generates a random number of type T within a specified range.
Definition KittyUtils.hpp:671
Structure to hold ZIP Central Directory info.
Definition KittyUtils.hpp:813
Structure to hold ZIP entry info.
Definition KittyUtils.hpp:824
Structure to hold memory mapped ZIP entry info.
Definition KittyUtils.hpp:839