mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-30 10:15:36 +01:00
clang-format ui/util/windows
This commit is contained in:
committed by
Hielke Morsink
parent
abb097124c
commit
adb69a2fe8
@@ -7,9 +7,8 @@
|
||||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include "Util.h"
|
||||
|
||||
#include "../common.h"
|
||||
#include "../core/Guard.hpp"
|
||||
#include "../core/Math.hpp"
|
||||
@@ -17,9 +16,12 @@
|
||||
#include "../localisation/Localisation.h"
|
||||
#include "../platform/platform.h"
|
||||
#include "../title/TitleScreen.h"
|
||||
#include "Util.h"
|
||||
#include "zlib.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
|
||||
int32_t squaredmetres_to_squaredfeet(int32_t squaredMetres)
|
||||
{
|
||||
// 1 metre squared = 10.7639104 feet squared
|
||||
@@ -47,39 +49,41 @@ int32_t mph_to_dmps(int32_t mph)
|
||||
return (mph * 73243) >> 14;
|
||||
}
|
||||
|
||||
bool filename_valid_characters(const utf8 *filename)
|
||||
bool filename_valid_characters(const utf8* filename)
|
||||
{
|
||||
for (int32_t i = 0; filename[i] != '\0'; i++) {
|
||||
if (filename[i] == '\\' || filename[i] == '/' || filename[i] == ':' || filename[i] == '?' ||
|
||||
filename[i] == '*' || filename[i] == '<' || filename[i] == '>' || filename[i] == '|')
|
||||
for (int32_t i = 0; filename[i] != '\0'; i++)
|
||||
{
|
||||
if (filename[i] == '\\' || filename[i] == '/' || filename[i] == ':' || filename[i] == '?' || filename[i] == '*'
|
||||
|| filename[i] == '<' || filename[i] == '>' || filename[i] == '|')
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
utf8 *path_get_directory(const utf8 *path)
|
||||
utf8* path_get_directory(const utf8* path)
|
||||
{
|
||||
// Find the last slash or backslash in the path
|
||||
char * filename = (char *)strrchr(path, *PATH_SEPARATOR);
|
||||
char * filename_posix = (char *)strrchr(path, '/');
|
||||
char* filename = (char*)strrchr(path, *PATH_SEPARATOR);
|
||||
char* filename_posix = (char*)strrchr(path, '/');
|
||||
filename = filename < filename_posix ? filename_posix : filename;
|
||||
|
||||
// If the path is invalid (e.g. just a file name), return NULL
|
||||
if (filename == nullptr) {
|
||||
if (filename == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char *directory = _strdup(path);
|
||||
char* directory = _strdup(path);
|
||||
safe_strtrunc(directory, strlen(path) - strlen(filename) + 2);
|
||||
|
||||
return directory;
|
||||
}
|
||||
|
||||
const char *path_get_filename(const utf8 *path)
|
||||
const char* path_get_filename(const utf8* path)
|
||||
{
|
||||
// Find last slash or backslash in the path
|
||||
char * filename = (char *)strrchr(path, *PATH_SEPARATOR);
|
||||
char * filename_posix = (char *)strchr(path, '/');
|
||||
char* filename = (char*)strrchr(path, *PATH_SEPARATOR);
|
||||
char* filename_posix = (char*)strchr(path, '/');
|
||||
filename = filename < filename_posix ? filename_posix : filename;
|
||||
|
||||
// Checks if the path is valid (e.g. not just a file name)
|
||||
@@ -97,22 +101,22 @@ const char *path_get_filename(const utf8 *path)
|
||||
|
||||
// Returns the extension (dot inclusive) from the given path, or the end of the
|
||||
// string when no extension was found.
|
||||
const char *path_get_extension(const utf8 *path)
|
||||
const char* path_get_extension(const utf8* path)
|
||||
{
|
||||
// Get the filename from the path
|
||||
const char *filename = path_get_filename(path);
|
||||
const char* filename = path_get_filename(path);
|
||||
|
||||
// Try to find the most-right dot in the filename
|
||||
char * extension = (char *)strrchr(filename, '.');
|
||||
char* extension = (char*)strrchr(filename, '.');
|
||||
|
||||
// When no dot was found, return a pointer to the null-terminator
|
||||
if (extension == nullptr)
|
||||
extension = (char *)strrchr(filename, '\0');
|
||||
extension = (char*)strrchr(filename, '\0');
|
||||
|
||||
return extension;
|
||||
}
|
||||
|
||||
void path_set_extension(utf8 *path, const utf8 *newExtension, size_t size)
|
||||
void path_set_extension(utf8* path, const utf8* newExtension, size_t size)
|
||||
{
|
||||
// Remove existing extension (check first if there is one)
|
||||
if (path_get_extension(path) < strrchr(path, '\0'))
|
||||
@@ -121,7 +125,7 @@ void path_set_extension(utf8 *path, const utf8 *newExtension, size_t size)
|
||||
path_append_extension(path, newExtension, size);
|
||||
}
|
||||
|
||||
void path_append_extension(utf8 *path, const utf8 *newExtension, size_t size)
|
||||
void path_append_extension(utf8* path, const utf8* newExtension, size_t size)
|
||||
{
|
||||
// Append a dot to the filename if the new extension doesn't start with it
|
||||
if (newExtension[0] != '.')
|
||||
@@ -131,36 +135,39 @@ void path_append_extension(utf8 *path, const utf8 *newExtension, size_t size)
|
||||
safe_strcat(path, newExtension, size);
|
||||
}
|
||||
|
||||
void path_remove_extension(utf8 *path)
|
||||
void path_remove_extension(utf8* path)
|
||||
{
|
||||
// Find last dot in filename, and replace it with a null-terminator
|
||||
char * lastDot = (char *)strrchr(path_get_filename(path), '.');
|
||||
char* lastDot = (char*)strrchr(path_get_filename(path), '.');
|
||||
if (lastDot != nullptr)
|
||||
*lastDot = '\0';
|
||||
else
|
||||
log_warning("No extension found. (path = %s)", path);
|
||||
}
|
||||
|
||||
void path_end_with_separator(utf8 *path, size_t size) {
|
||||
void path_end_with_separator(utf8* path, size_t size)
|
||||
{
|
||||
size_t length = strnlen(path, size);
|
||||
if (length >= size - 1) return;
|
||||
if (length >= size - 1)
|
||||
return;
|
||||
|
||||
if ((length == 0) || ((path[length - 1] != *PATH_SEPARATOR) && path[length - 1] != '/')) {
|
||||
if ((length == 0) || ((path[length - 1] != *PATH_SEPARATOR) && path[length - 1] != '/'))
|
||||
{
|
||||
safe_strcat(path, PATH_SEPARATOR, size);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t bitscanforward(int32_t source)
|
||||
{
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) // Visual Studio 2005
|
||||
DWORD i;
|
||||
uint8_t success = _BitScanForward(&i, (uint32_t)source);
|
||||
return success != 0 ? i : -1;
|
||||
#elif defined(__GNUC__)
|
||||
int32_t success = __builtin_ffs(source);
|
||||
return success - 1;
|
||||
#else
|
||||
#pragma message "Falling back to iterative bitscan forward, consider using intrinsics"
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) // Visual Studio 2005
|
||||
DWORD i;
|
||||
uint8_t success = _BitScanForward(&i, (uint32_t)source);
|
||||
return success != 0 ? i : -1;
|
||||
#elif defined(__GNUC__)
|
||||
int32_t success = __builtin_ffs(source);
|
||||
return success - 1;
|
||||
#else
|
||||
#pragma message "Falling back to iterative bitscan forward, consider using intrinsics"
|
||||
// This is a low-hanging optimisation boost, check if your compiler offers
|
||||
// any intrinsic.
|
||||
// cf. https://github.com/OpenRCT2/OpenRCT2/pull/2093
|
||||
@@ -169,26 +176,26 @@ int32_t bitscanforward(int32_t source)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
|
||||
#include <cpuid.h>
|
||||
#define OpenRCT2_CPUID_GNUC_X86
|
||||
#include <cpuid.h>
|
||||
#define OpenRCT2_CPUID_GNUC_X86
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_X64) || defined(_M_IX86)) // VS2008
|
||||
#include <intrin.h>
|
||||
#include <nmmintrin.h>
|
||||
#define OpenRCT2_CPUID_MSVC_X86
|
||||
#include <intrin.h>
|
||||
#include <nmmintrin.h>
|
||||
#define OpenRCT2_CPUID_MSVC_X86
|
||||
#endif
|
||||
|
||||
#ifdef OPENRCT2_X86
|
||||
static bool cpuid_x86(uint32_t * cpuid_outdata, int32_t eax)
|
||||
static bool cpuid_x86(uint32_t* cpuid_outdata, int32_t eax)
|
||||
{
|
||||
#if defined(OpenRCT2_CPUID_GNUC_X86)
|
||||
int ret = __get_cpuid(eax, &cpuid_outdata[0], &cpuid_outdata[1], &cpuid_outdata[2], &cpuid_outdata[3]);
|
||||
return ret == 1;
|
||||
#elif defined(OpenRCT2_CPUID_MSVC_X86)
|
||||
__cpuid((int *)cpuid_outdata, (int)eax);
|
||||
__cpuid((int*)cpuid_outdata, (int)eax);
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
@@ -245,38 +252,35 @@ static bool bitcount_popcnt_available()
|
||||
|
||||
static int32_t bitcount_popcnt(uint32_t source)
|
||||
{
|
||||
// Use CPUID defines to figure out calling style
|
||||
#if defined(OpenRCT2_CPUID_GNUC_X86)
|
||||
// use asm directly in order to actually emit the instruction : using
|
||||
// __builtin_popcount results in an extra call to a library function.
|
||||
int32_t rv;
|
||||
asm volatile ("popcnt %1,%0" : "=r"(rv) : "rm"(source) : "cc");
|
||||
return rv;
|
||||
#elif defined(OpenRCT2_CPUID_MSVC_X86)
|
||||
return _mm_popcnt_u32(source);
|
||||
#else
|
||||
openrct2_assert(false, "bitcount_popcnt() called, without support compiled in");
|
||||
return INT_MAX;
|
||||
#endif
|
||||
// Use CPUID defines to figure out calling style
|
||||
#if defined(OpenRCT2_CPUID_GNUC_X86)
|
||||
// use asm directly in order to actually emit the instruction : using
|
||||
// __builtin_popcount results in an extra call to a library function.
|
||||
int32_t rv;
|
||||
asm volatile("popcnt %1,%0" : "=r"(rv) : "rm"(source) : "cc");
|
||||
return rv;
|
||||
#elif defined(OpenRCT2_CPUID_MSVC_X86)
|
||||
return _mm_popcnt_u32(source);
|
||||
#else
|
||||
openrct2_assert(false, "bitcount_popcnt() called, without support compiled in");
|
||||
return INT_MAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int32_t bitcount_lut(uint32_t source)
|
||||
{
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html
|
||||
static constexpr const uint8_t BitsSetTable256[256] =
|
||||
{
|
||||
#define B2(n) n, (n) + 1, (n) + 1, (n) + 2
|
||||
#define B4(n) B2(n), B2((n) + 1), B2((n) + 1), B2((n) + 2)
|
||||
#define B6(n) B4(n), B4((n) + 1), B4((n) + 1), B4((n) + 2)
|
||||
B6(0), B6(1), B6(1), B6(2)
|
||||
static constexpr const uint8_t BitsSetTable256[256] = {
|
||||
#define B2(n) n, (n) + 1, (n) + 1, (n) + 2
|
||||
#define B4(n) B2(n), B2((n) + 1), B2((n) + 1), B2((n) + 2)
|
||||
#define B6(n) B4(n), B4((n) + 1), B4((n) + 1), B4((n) + 2)
|
||||
B6(0), B6(1), B6(1), B6(2)
|
||||
};
|
||||
return BitsSetTable256[source & 0xff] +
|
||||
BitsSetTable256[(source >> 8) & 0xff] +
|
||||
BitsSetTable256[(source >> 16) & 0xff] +
|
||||
BitsSetTable256[source >> 24];
|
||||
return BitsSetTable256[source & 0xff] + BitsSetTable256[(source >> 8) & 0xff] + BitsSetTable256[(source >> 16) & 0xff]
|
||||
+ BitsSetTable256[source >> 24];
|
||||
}
|
||||
|
||||
static int32_t(*bitcount_fn)(uint32_t);
|
||||
static int32_t (*bitcount_fn)(uint32_t);
|
||||
|
||||
void bitcount_init()
|
||||
{
|
||||
@@ -288,17 +292,16 @@ int32_t bitcount(uint32_t source)
|
||||
return bitcount_fn(source);
|
||||
}
|
||||
|
||||
bool strequals(const char *a, const char *b, int32_t length, bool caseInsensitive)
|
||||
bool strequals(const char* a, const char* b, int32_t length, bool caseInsensitive)
|
||||
{
|
||||
return caseInsensitive ?
|
||||
_strnicmp(a, b, length) == 0 :
|
||||
strncmp(a, b, length) == 0;
|
||||
return caseInsensitive ? _strnicmp(a, b, length) == 0 : strncmp(a, b, length) == 0;
|
||||
}
|
||||
|
||||
/* case insensitive compare */
|
||||
int32_t strcicmp(char const *a, char const *b)
|
||||
int32_t strcicmp(char const* a, char const* b)
|
||||
{
|
||||
for (;; a++, b++) {
|
||||
for (;; a++, b++)
|
||||
{
|
||||
int32_t d = tolower(*a) - tolower(*b);
|
||||
if (d != 0 || !*a)
|
||||
return d;
|
||||
@@ -312,42 +315,60 @@ int32_t strcicmp(char const *a, char const *b)
|
||||
// - Guest 100
|
||||
// - John v2.0
|
||||
// - John v2.1
|
||||
int32_t strlogicalcmp(char const *a, char const *b) {
|
||||
for (;; a++, b++) {
|
||||
int32_t strlogicalcmp(char const* a, char const* b)
|
||||
{
|
||||
for (;; a++, b++)
|
||||
{
|
||||
int32_t result = tolower(*a) - tolower(*b);
|
||||
bool both_numeric = *a >= '0' && *a <= '9' && *b >= '0' && *b <= '9';
|
||||
if (result != 0 || !*a || both_numeric) { // difference found || end of string
|
||||
if (both_numeric) { // a and b both start with a number
|
||||
if (result != 0 || !*a || both_numeric)
|
||||
{ // difference found || end of string
|
||||
if (both_numeric)
|
||||
{ // a and b both start with a number
|
||||
// Get the numbers in the string at current positions
|
||||
int32_t na = 0 , nb = 0;
|
||||
for (; *a >= '0' && *a <= '9'; a++) { na *= 10; na += *a - '0'; }
|
||||
for (; *b >= '0' && *b <= '9'; b++) { nb *= 10; nb += *b - '0'; }
|
||||
int32_t na = 0, nb = 0;
|
||||
for (; *a >= '0' && *a <= '9'; a++)
|
||||
{
|
||||
na *= 10;
|
||||
na += *a - '0';
|
||||
}
|
||||
for (; *b >= '0' && *b <= '9'; b++)
|
||||
{
|
||||
nb *= 10;
|
||||
nb += *b - '0';
|
||||
}
|
||||
// In case the numbers are the same
|
||||
if (na == nb)
|
||||
continue;
|
||||
return na - nb;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
utf8 * safe_strtrunc(utf8 * text, size_t size)
|
||||
utf8* safe_strtrunc(utf8* text, size_t size)
|
||||
{
|
||||
assert(text != nullptr);
|
||||
|
||||
if (size == 0) return text;
|
||||
if (size == 0)
|
||||
return text;
|
||||
|
||||
const char *sourceLimit = text + size - 1;
|
||||
char *ch = text;
|
||||
char *last = text;
|
||||
const char* sourceLimit = text + size - 1;
|
||||
char* ch = text;
|
||||
char* last = text;
|
||||
uint32_t codepoint;
|
||||
while ((codepoint = utf8_get_next(ch, (const utf8 **)&ch)) != 0) {
|
||||
if (ch <= sourceLimit) {
|
||||
while ((codepoint = utf8_get_next(ch, (const utf8**)&ch)) != 0)
|
||||
{
|
||||
if (ch <= sourceLimit)
|
||||
{
|
||||
last = ch;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -356,66 +377,82 @@ utf8 * safe_strtrunc(utf8 * text, size_t size)
|
||||
return text;
|
||||
}
|
||||
|
||||
char *safe_strcpy(char * destination, const char * source, size_t size)
|
||||
char* safe_strcpy(char* destination, const char* source, size_t size)
|
||||
{
|
||||
assert(destination != nullptr);
|
||||
assert(source != nullptr);
|
||||
|
||||
if (size == 0) return destination;
|
||||
if (size == 0)
|
||||
return destination;
|
||||
|
||||
char * result = destination;
|
||||
char* result = destination;
|
||||
|
||||
bool truncated = false;
|
||||
const char *sourceLimit = source + size - 1;
|
||||
const char *ch = source;
|
||||
const char* sourceLimit = source + size - 1;
|
||||
const char* ch = source;
|
||||
uint32_t codepoint;
|
||||
while ((codepoint = utf8_get_next(ch, &ch)) != 0) {
|
||||
if (ch <= sourceLimit) {
|
||||
while ((codepoint = utf8_get_next(ch, &ch)) != 0)
|
||||
{
|
||||
if (ch <= sourceLimit)
|
||||
{
|
||||
destination = utf8_write_codepoint(destination, codepoint);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
truncated = true;
|
||||
}
|
||||
}
|
||||
*destination = 0;
|
||||
|
||||
if (truncated) {
|
||||
if (truncated)
|
||||
{
|
||||
log_warning("Truncating string \"%s\" to %d bytes.", result, size);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
char *safe_strcat(char *destination, const char *source, size_t size)
|
||||
char* safe_strcat(char* destination, const char* source, size_t size)
|
||||
{
|
||||
assert(destination != nullptr);
|
||||
assert(source != nullptr);
|
||||
|
||||
if (size == 0) {
|
||||
if (size == 0)
|
||||
{
|
||||
return destination;
|
||||
}
|
||||
|
||||
char *result = destination;
|
||||
char* result = destination;
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < size; i++) {
|
||||
if (*destination == '\0') {
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (*destination == '\0')
|
||||
{
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
destination++;
|
||||
}
|
||||
}
|
||||
|
||||
bool terminated = false;
|
||||
for (; i < size; i++) {
|
||||
if (*source != '\0') {
|
||||
for (; i < size; i++)
|
||||
{
|
||||
if (*source != '\0')
|
||||
{
|
||||
*destination++ = *source++;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
*destination = *source;
|
||||
terminated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!terminated) {
|
||||
if (!terminated)
|
||||
{
|
||||
result[size - 1] = '\0';
|
||||
log_warning("Truncating string \"%s\" to %d bytes.", result, size);
|
||||
}
|
||||
@@ -423,7 +460,7 @@ char *safe_strcat(char *destination, const char *source, size_t size)
|
||||
return result;
|
||||
}
|
||||
|
||||
char *safe_strcat_path(char *destination, const char *source, size_t size)
|
||||
char* safe_strcat_path(char* destination, const char* source, size_t size)
|
||||
{
|
||||
path_end_with_separator(destination, size);
|
||||
if (source[0] == *PATH_SEPARATOR)
|
||||
@@ -433,23 +470,25 @@ char *safe_strcat_path(char *destination, const char *source, size_t size)
|
||||
return safe_strcat(destination, source, size);
|
||||
}
|
||||
|
||||
char *safe_strtrimleft(char *destination, const char *source, size_t size)
|
||||
char* safe_strtrimleft(char* destination, const char* source, size_t size)
|
||||
{
|
||||
while (*source == ' ') {
|
||||
while (*source == ' ')
|
||||
{
|
||||
source++;
|
||||
}
|
||||
return safe_strcpy(destination, source, size);
|
||||
}
|
||||
|
||||
#if !(defined(_GNU_SOURCE) || (defined(__DARWIN_C_LEVEL) && __DARWIN_C_LEVEL >= 200809L))
|
||||
char * strcasestr(const char * haystack, const char * needle)
|
||||
char* strcasestr(const char* haystack, const char* needle)
|
||||
{
|
||||
const char * p1 = haystack;
|
||||
const char * p2 = needle;
|
||||
const char * r = *p2 == 0 ? haystack : 0;
|
||||
const char* p1 = haystack;
|
||||
const char* p2 = needle;
|
||||
const char* r = *p2 == 0 ? haystack : 0;
|
||||
|
||||
while (*p1 != 0 && *p2 != 0) {
|
||||
if (tolower((unsigned char) *p1) == tolower((unsigned char) *p2))
|
||||
while (*p1 != 0 && *p2 != 0)
|
||||
{
|
||||
if (tolower((unsigned char)*p1) == tolower((unsigned char)*p2))
|
||||
{
|
||||
if (r == 0)
|
||||
r = p1;
|
||||
@@ -461,7 +500,7 @@ char * strcasestr(const char * haystack, const char * needle)
|
||||
if (r != 0)
|
||||
p1 = r + 1;
|
||||
|
||||
if (tolower((unsigned char) *p1) == tolower((unsigned char) *p2))
|
||||
if (tolower((unsigned char)*p1) == tolower((unsigned char)*p2))
|
||||
{
|
||||
r = p1;
|
||||
p2++;
|
||||
@@ -475,26 +514,28 @@ char * strcasestr(const char * haystack, const char * needle)
|
||||
p1++;
|
||||
}
|
||||
|
||||
return *p2 == 0 ? (char *) r : 0;
|
||||
return *p2 == 0 ? (char*)r : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool utf8_is_bom(const char *str)
|
||||
bool utf8_is_bom(const char* str)
|
||||
{
|
||||
return str[0] == (char)(uint8_t)0xEF && str[1] == (char)(uint8_t)0xBB && str[2] == (char)(uint8_t)0xBF;
|
||||
}
|
||||
|
||||
bool str_is_null_or_empty(const char *str)
|
||||
bool str_is_null_or_empty(const char* str)
|
||||
{
|
||||
return str == nullptr || str[0] == 0;
|
||||
}
|
||||
|
||||
void util_srand(int32_t source) {
|
||||
void util_srand(int32_t source)
|
||||
{
|
||||
srand(source);
|
||||
}
|
||||
|
||||
// Caveat: rand() might only return values up to 0x7FFF, which is the minimum specified in the C standard.
|
||||
uint32_t util_rand() {
|
||||
uint32_t util_rand()
|
||||
{
|
||||
return rand();
|
||||
}
|
||||
|
||||
@@ -505,11 +546,12 @@ uint32_t util_rand() {
|
||||
* @brief Inflates zlib-compressed data
|
||||
* @param data Data to be decompressed
|
||||
* @param data_in_size Size of data to be decompressed
|
||||
* @param data_out_size Pointer to a variable where output size will be written. If not 0, it will be used to set initial output buffer size.
|
||||
* @param data_out_size Pointer to a variable where output size will be written. If not 0, it will be used to set initial output
|
||||
* buffer size.
|
||||
* @return Returns a pointer to memory holding decompressed data or NULL on failure.
|
||||
* @note It is caller's responsibility to free() the returned pointer once done with it.
|
||||
*/
|
||||
uint8_t *util_zlib_inflate(uint8_t *data, size_t data_in_size, size_t *data_out_size)
|
||||
uint8_t* util_zlib_inflate(uint8_t* data, size_t data_in_size, size_t* data_out_size)
|
||||
{
|
||||
int32_t ret = Z_OK;
|
||||
uLongf out_size = (uLong)*data_out_size;
|
||||
@@ -521,25 +563,30 @@ uint8_t *util_zlib_inflate(uint8_t *data, size_t data_in_size, size_t *data_out_
|
||||
out_size = std::min((uLongf)MAX_ZLIB_REALLOC, out_size);
|
||||
}
|
||||
uLongf buffer_size = out_size;
|
||||
uint8_t *buffer = (uint8_t *)malloc(buffer_size);
|
||||
do {
|
||||
uint8_t* buffer = (uint8_t*)malloc(buffer_size);
|
||||
do
|
||||
{
|
||||
if (ret == Z_BUF_ERROR)
|
||||
{
|
||||
buffer_size *= 2;
|
||||
out_size = buffer_size;
|
||||
buffer = (uint8_t *)realloc(buffer, buffer_size);
|
||||
} else if (ret == Z_STREAM_ERROR) {
|
||||
buffer = (uint8_t*)realloc(buffer, buffer_size);
|
||||
}
|
||||
else if (ret == Z_STREAM_ERROR)
|
||||
{
|
||||
log_error("Your build is shipped with broken zlib. Please use the official build.");
|
||||
free(buffer);
|
||||
return nullptr;
|
||||
} else if (ret < 0) {
|
||||
}
|
||||
else if (ret < 0)
|
||||
{
|
||||
log_error("Error uncompressing data.");
|
||||
free(buffer);
|
||||
return nullptr;
|
||||
}
|
||||
ret = uncompress(buffer, &out_size, data, (uLong)data_in_size);
|
||||
} while (ret != Z_OK);
|
||||
buffer = (uint8_t *)realloc(buffer, out_size);
|
||||
buffer = (uint8_t*)realloc(buffer, out_size);
|
||||
*data_out_size = out_size;
|
||||
return buffer;
|
||||
}
|
||||
@@ -552,19 +599,22 @@ uint8_t *util_zlib_inflate(uint8_t *data, size_t data_in_size, size_t *data_out_
|
||||
* @return Returns a pointer to memory holding compressed data or NULL on failure.
|
||||
* @note It is caller's responsibility to free() the returned pointer once done with it.
|
||||
*/
|
||||
uint8_t *util_zlib_deflate(const uint8_t *data, size_t data_in_size, size_t *data_out_size)
|
||||
uint8_t* util_zlib_deflate(const uint8_t* data, size_t data_in_size, size_t* data_out_size)
|
||||
{
|
||||
int32_t ret = Z_OK;
|
||||
uLongf out_size = (uLongf)*data_out_size;
|
||||
uLong buffer_size = compressBound((uLong)data_in_size);
|
||||
uint8_t *buffer = (uint8_t *)malloc(buffer_size);
|
||||
do {
|
||||
uint8_t* buffer = (uint8_t*)malloc(buffer_size);
|
||||
do
|
||||
{
|
||||
if (ret == Z_BUF_ERROR)
|
||||
{
|
||||
buffer_size *= 2;
|
||||
out_size = buffer_size;
|
||||
buffer = (uint8_t *)realloc(buffer, buffer_size);
|
||||
} else if (ret == Z_STREAM_ERROR) {
|
||||
buffer = (uint8_t*)realloc(buffer, buffer_size);
|
||||
}
|
||||
else if (ret == Z_STREAM_ERROR)
|
||||
{
|
||||
log_error("Your build is shipped with broken zlib. Please use the official build.");
|
||||
free(buffer);
|
||||
return nullptr;
|
||||
@@ -572,20 +622,23 @@ uint8_t *util_zlib_deflate(const uint8_t *data, size_t data_in_size, size_t *dat
|
||||
ret = compress(buffer, &out_size, data, (uLong)data_in_size);
|
||||
} while (ret != Z_OK);
|
||||
*data_out_size = out_size;
|
||||
buffer = (uint8_t *)realloc(buffer, *data_out_size);
|
||||
buffer = (uint8_t*)realloc(buffer, *data_out_size);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// Type-independent code left as macro to reduce duplicate code.
|
||||
#define add_clamp_body(value, value_to_add, min_cap, max_cap) \
|
||||
if ((value_to_add > 0) && (value > (max_cap - (value_to_add)))) { \
|
||||
value = max_cap; \
|
||||
} \
|
||||
else if ((value_to_add < 0) && (value < (min_cap - (value_to_add)))) { \
|
||||
value = min_cap; \
|
||||
} \
|
||||
else { \
|
||||
value += value_to_add; \
|
||||
#define add_clamp_body(value, value_to_add, min_cap, max_cap) \
|
||||
if ((value_to_add > 0) && (value > (max_cap - (value_to_add)))) \
|
||||
{ \
|
||||
value = max_cap; \
|
||||
} \
|
||||
else if ((value_to_add < 0) && (value < (min_cap - (value_to_add)))) \
|
||||
{ \
|
||||
value = min_cap; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
value += value_to_add; \
|
||||
}
|
||||
|
||||
int8_t add_clamp_int8_t(int8_t value, int8_t value_to_add)
|
||||
@@ -623,15 +676,17 @@ uint8_t lerp(uint8_t a, uint8_t b, float t)
|
||||
if (t >= 1)
|
||||
return b;
|
||||
|
||||
int32_t range = b - a;
|
||||
int32_t range = b - a;
|
||||
int32_t amount = (int32_t)(range * t);
|
||||
return (uint8_t)(a + amount);
|
||||
}
|
||||
|
||||
float flerp(float a, float b, float t)
|
||||
{
|
||||
if (t <= 0) return a;
|
||||
if (t >= 1) return b;
|
||||
if (t <= 0)
|
||||
return a;
|
||||
if (t >= 1)
|
||||
return b;
|
||||
|
||||
float range = b - a;
|
||||
float amount = range * t;
|
||||
@@ -657,11 +712,12 @@ uint8_t soft_light(uint8_t a, uint8_t b)
|
||||
/**
|
||||
* strftime wrapper which appends to an existing string.
|
||||
*/
|
||||
size_t strcatftime(char * buffer, size_t bufferSize, const char * format, const struct tm * tp)
|
||||
size_t strcatftime(char* buffer, size_t bufferSize, const char* format, const struct tm* tp)
|
||||
{
|
||||
size_t stringLen = strnlen(buffer, bufferSize);
|
||||
if (stringLen < bufferSize) {
|
||||
char * dst = buffer + stringLen;
|
||||
if (stringLen < bufferSize)
|
||||
{
|
||||
char* dst = buffer + stringLen;
|
||||
size_t dstMaxSize = bufferSize - stringLen;
|
||||
return strftime(dst, dstMaxSize, format, tp);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user