mirror of https://github.com/bsnes-emu/bsnes.git
118 lines
2.6 KiB
C++
118 lines
2.6 KiB
C++
#ifdef NALL_STRING_INTERNAL_HPP
|
|
|
|
namespace nall {
|
|
|
|
string substr(rstring source, unsigned offset, unsigned length) {
|
|
string result;
|
|
if(length == ~0u) length = source.size() - offset;
|
|
result.resize(length);
|
|
memcpy(result.data(), source.data() + offset, length);
|
|
return result;
|
|
}
|
|
|
|
string sha256(const uint8_t* data, unsigned size) {
|
|
sha256_ctx sha;
|
|
uint8_t hash[32];
|
|
sha256_init(&sha);
|
|
sha256_chunk(&sha, data, size);
|
|
sha256_final(&sha);
|
|
sha256_hash(&sha, hash);
|
|
string result;
|
|
for(auto& byte : hash) result.append(hex<2>(byte));
|
|
return result;
|
|
}
|
|
|
|
bool tokenize(lstring& list, const char* s, const char* p) {
|
|
while(*s) {
|
|
if(*p == '*') {
|
|
const char* b = s;
|
|
while(*s) {
|
|
if(tokenize(list, s++, p + 1)) {
|
|
list.prepend(substr(b, 0, --s - b));
|
|
return true;
|
|
}
|
|
}
|
|
list.prepend(b);
|
|
return !*++p;
|
|
}
|
|
if(*s++ != *p++) return false;
|
|
}
|
|
while(*p == '*') { list.prepend(s); p++; }
|
|
return !*p;
|
|
}
|
|
|
|
char* integer(char* result, intmax_t value) {
|
|
bool negative = value < 0;
|
|
if(negative) value = -value;
|
|
|
|
char buffer[64];
|
|
unsigned size = 0;
|
|
|
|
do {
|
|
unsigned n = value % 10;
|
|
buffer[size++] = '0' + n;
|
|
value /= 10;
|
|
} while(value);
|
|
if(negative) buffer[size++] = '-';
|
|
//buffer[size++] = negative ? '-' : '+';
|
|
|
|
for(signed x = size - 1, y = 0; x >= 0 && y < size; x--, y++) result[x] = buffer[y];
|
|
result[size] = 0;
|
|
return result;
|
|
}
|
|
|
|
char* decimal(char* result, uintmax_t value) {
|
|
char buffer[64];
|
|
unsigned size = 0;
|
|
|
|
do {
|
|
unsigned n = value % 10;
|
|
buffer[size++] = '0' + n;
|
|
value /= 10;
|
|
} while(value);
|
|
|
|
for(signed x = size - 1, y = 0; x >= 0 && y < size; x--, y++) result[x] = buffer[y];
|
|
result[size] = 0;
|
|
return result;
|
|
}
|
|
|
|
//using sprintf is certainly not the most ideal method to convert
|
|
//a double to a string ... but attempting to parse a double by
|
|
//hand, digit-by-digit, results in subtle rounding errors.
|
|
unsigned real(char* str, long double value) {
|
|
char buffer[256];
|
|
#ifdef _WIN32
|
|
//Windows C-runtime does not support long double via sprintf()
|
|
sprintf(buffer, "%f", (double)value);
|
|
#else
|
|
sprintf(buffer, "%Lf", value);
|
|
#endif
|
|
|
|
//remove excess 0's in fraction (2.500000 -> 2.5)
|
|
for(char* p = buffer; *p; p++) {
|
|
if(*p == '.') {
|
|
char* p = buffer + strlen(buffer) - 1;
|
|
while(*p == '0') {
|
|
if(*(p - 1) != '.') *p = 0; //... but not for eg 1.0 -> 1.
|
|
p--;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
unsigned length = strlen(buffer);
|
|
if(str) strcpy(str, buffer);
|
|
return length + 1;
|
|
}
|
|
|
|
string real(long double value) {
|
|
string temp;
|
|
temp.resize(real(nullptr, value));
|
|
real(temp.data(), value);
|
|
return temp;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|