bsnes/higan/nall/string/utility.hpp

243 lines
5.3 KiB
C++
Raw Normal View History

#ifdef NALL_STRING_INTERNAL_HPP
namespace nall {
template<bool Insensitive>
bool chrequal(char x, char y) {
if(Insensitive) return chrlower(x) == chrlower(y);
return x == y;
}
template<bool Quoted, typename T>
bool quoteskip(T*& p) {
if(Quoted == false) return false;
if(*p != '\'' && *p != '\"') return false;
while(*p == '\'' || *p == '\"') {
char x = *p++;
while(*p && *p++ != x);
}
return true;
}
template<bool Quoted, typename T>
bool quotecopy(char*& t, T*& p) {
if(Quoted == false) return false;
if(*p != '\'' && *p != '\"') return false;
while(*p == '\'' || *p == '\"') {
char x = *p++;
*t++ = x;
while(*p && *p != x) *t++ = *p++;
*t++ = *p++;
}
return true;
}
string substr(const char* src, unsigned start, unsigned length) {
string dest;
if(length == ~0u) {
//copy entire string
dest.reserve(strlen(src + start) + 1);
strcpy(dest(), src + start);
} else {
//copy partial string
dest.reserve(length + 1);
strmcpy(dest(), src + start, length + 1);
}
return dest;
}
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;
}
/* cast.hpp arithmetic -> string */
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;
}
/* general-purpose arithmetic -> string */
template<unsigned length_, char padding> string integer(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 ? '-' : '+';
buffer[size] = 0;
unsigned length = (length_ == 0 ? size : length_);
char result[length + 1];
memset(result, padding, length);
result[length] = 0;
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
result[x] = buffer[y];
}
Update to v075r11 release. byuu says: Rewrote the way menus are attached, they act like layouts/widgets now. All three phoenix targets once again work with both radio menu items and radio widgets. Both GTK+ and Qt have built-in group controls right inside the widgets, so I don't have to keep my own groups around anymore. They do act screwy at widget creation though, have to jump through some hoops to get it to work right. All I can say is, definitely set all child widgets to the parent before trying to check any of them. My long-term goal for the main window is to honor the fullscreen video setting as a generic setting, and let the window scale auto-fit the best possible size that matches your scale preference into the output window, centered just like fullscreen. For now, I've just set it to a fixed window size until I finish working on phoenix. The scale X settings will just be to snap the window to an exact size in case you don't want any black borders, they won't be radio items and the bsnes-geometry.cfg file will save width/height information as well. Simplified the sizing requirements for creating layouts and updated all bsnes windows to support the new system. Layouts also expose their minimum width/height values, which I use to create perfectly sized windows on all three platforms. This will fix cut-off heights on the last Windows WIP. Qt is being annoying though and forcing a minimum window size of 300,100 despite me telling it to use a smaller window size. Always have to fight with Qt, I swear to god.
2011-02-10 10:08:12 +00:00
return (const char*)result;
}
template<unsigned length_, char padding> string linteger(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 ? '-' : '+';
buffer[size] = 0;
unsigned length = (length_ == 0 ? size : length_);
char result[length + 1];
memset(result, padding, length);
result[length] = 0;
for(signed x = 0, y = size - 1; x < length && y >= 0; x++, y--) {
result[x] = buffer[y];
}
Update to v075r11 release. byuu says: Rewrote the way menus are attached, they act like layouts/widgets now. All three phoenix targets once again work with both radio menu items and radio widgets. Both GTK+ and Qt have built-in group controls right inside the widgets, so I don't have to keep my own groups around anymore. They do act screwy at widget creation though, have to jump through some hoops to get it to work right. All I can say is, definitely set all child widgets to the parent before trying to check any of them. My long-term goal for the main window is to honor the fullscreen video setting as a generic setting, and let the window scale auto-fit the best possible size that matches your scale preference into the output window, centered just like fullscreen. For now, I've just set it to a fixed window size until I finish working on phoenix. The scale X settings will just be to snap the window to an exact size in case you don't want any black borders, they won't be radio items and the bsnes-geometry.cfg file will save width/height information as well. Simplified the sizing requirements for creating layouts and updated all bsnes windows to support the new system. Layouts also expose their minimum width/height values, which I use to create perfectly sized windows on all three platforms. This will fix cut-off heights on the last Windows WIP. Qt is being annoying though and forcing a minimum window size of 300,100 despite me telling it to use a smaller window size. Always have to fight with Qt, I swear to god.
2011-02-10 10:08:12 +00:00
return (const char*)result;
}
template<unsigned length_, char padding> string decimal(uintmax_t value) {
char buffer[64];
unsigned size = 0;
do {
unsigned n = value % 10;
buffer[size++] = '0' + n;
value /= 10;
} while(value);
buffer[size] = 0;
unsigned length = (length_ == 0 ? size : length_);
char result[length + 1];
memset(result, padding, length);
result[length] = 0;
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
result[x] = buffer[y];
}
Update to v075r11 release. byuu says: Rewrote the way menus are attached, they act like layouts/widgets now. All three phoenix targets once again work with both radio menu items and radio widgets. Both GTK+ and Qt have built-in group controls right inside the widgets, so I don't have to keep my own groups around anymore. They do act screwy at widget creation though, have to jump through some hoops to get it to work right. All I can say is, definitely set all child widgets to the parent before trying to check any of them. My long-term goal for the main window is to honor the fullscreen video setting as a generic setting, and let the window scale auto-fit the best possible size that matches your scale preference into the output window, centered just like fullscreen. For now, I've just set it to a fixed window size until I finish working on phoenix. The scale X settings will just be to snap the window to an exact size in case you don't want any black borders, they won't be radio items and the bsnes-geometry.cfg file will save width/height information as well. Simplified the sizing requirements for creating layouts and updated all bsnes windows to support the new system. Layouts also expose their minimum width/height values, which I use to create perfectly sized windows on all three platforms. This will fix cut-off heights on the last Windows WIP. Qt is being annoying though and forcing a minimum window size of 300,100 despite me telling it to use a smaller window size. Always have to fight with Qt, I swear to god.
2011-02-10 10:08:12 +00:00
return (const char*)result;
}
template<unsigned length_, char padding> string ldecimal(uintmax_t value) {
char buffer[64];
unsigned size = 0;
do {
unsigned n = value % 10;
buffer[size++] = '0' + n;
value /= 10;
} while(value);
buffer[size] = 0;
unsigned length = (length_ == 0 ? size : length_);
char result[length + 1];
memset(result, padding, length);
result[length] = 0;
for(signed x = 0, y = size - 1; x < length && y >= 0; x++, y--) {
result[x] = buffer[y];
}
Update to v075r11 release. byuu says: Rewrote the way menus are attached, they act like layouts/widgets now. All three phoenix targets once again work with both radio menu items and radio widgets. Both GTK+ and Qt have built-in group controls right inside the widgets, so I don't have to keep my own groups around anymore. They do act screwy at widget creation though, have to jump through some hoops to get it to work right. All I can say is, definitely set all child widgets to the parent before trying to check any of them. My long-term goal for the main window is to honor the fullscreen video setting as a generic setting, and let the window scale auto-fit the best possible size that matches your scale preference into the output window, centered just like fullscreen. For now, I've just set it to a fixed window size until I finish working on phoenix. The scale X settings will just be to snap the window to an exact size in case you don't want any black borders, they won't be radio items and the bsnes-geometry.cfg file will save width/height information as well. Simplified the sizing requirements for creating layouts and updated all bsnes windows to support the new system. Layouts also expose their minimum width/height values, which I use to create perfectly sized windows on all three platforms. This will fix cut-off heights on the last Windows WIP. Qt is being annoying though and forcing a minimum window size of 300,100 despite me telling it to use a smaller window size. Always have to fight with Qt, I swear to god.
2011-02-10 10:08:12 +00:00
return (const char*)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 fp(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 fp(long double value) {
string temp;
temp.reserve(fp(nullptr, value));
fp(temp(), value);
return temp;
}
}
#endif