diff --git a/src/nall/config.hpp b/src/nall/config.hpp index c713d0b0..1e1f8162 100644 --- a/src/nall/config.hpp +++ b/src/nall/config.hpp @@ -49,7 +49,7 @@ namespace nall { case signed_t: *(signed*)data = strsigned(s); break; case unsigned_t: *(unsigned*)data = strunsigned(s); break; case double_t: *(double*)data = strdouble(s); break; - case string_t: trim(s, "\""); *(string*)data = s; break; + case string_t: s.trim("\""); *(string*)data = s; break; } } }; @@ -83,8 +83,8 @@ namespace nall { lstring part; part.qsplit(" = ", line[i]); - trim(part[0]); - trim(part[1]); + part[0].trim(); + part[1].trim(); for(unsigned n = 0; n < list.size(); n++) { if(part[0] == list[n].name) { diff --git a/src/nall/dictionary.hpp b/src/nall/dictionary.hpp index 9e0a1620..1bdc87dc 100644 --- a/src/nall/dictionary.hpp +++ b/src/nall/dictionary.hpp @@ -27,7 +27,7 @@ namespace nall { bool import(const char *filename) { string data; if(data.readfile(filename) == false) return false; - ltrim_once(data, "\xef\xbb\xbf"); //remove UTF-8 marker, if it exists + data.ltrim_once("\xef\xbb\xbf"); //remove UTF-8 marker, if it exists data.replace("\r", ""); lstring line; @@ -39,12 +39,12 @@ namespace nall { if(part.size() != 2) continue; //remove whitespace - trim(part[0]); - trim(part[1]); + part[0].trim(); + part[1].trim(); //remove quotes - trim_once(part[0], "\""); - trim_once(part[1], "\""); + part[0].trim_once("\""); + part[1].trim_once("\""); unsigned n = index_input.size(); index_input[n] = part[0]; diff --git a/src/nall/file.hpp b/src/nall/file.hpp index 4c8ca8ee..6c73e544 100644 --- a/src/nall/file.hpp +++ b/src/nall/file.hpp @@ -11,6 +11,7 @@ #endif #include +#include #include #include @@ -83,9 +84,10 @@ namespace nall { while(length--) write(*buffer++); } - void print(const char *string) { - if(!string) return; - while(*string) write(*string++); + template void print(Args... args) { + string data(args...); + const char *p = data; + while(*p) write(*p++); } void flush() { diff --git a/src/nall/input.hpp b/src/nall/input.hpp index 83c4a484..28b10453 100644 --- a/src/nall/input.hpp +++ b/src/nall/input.hpp @@ -91,7 +91,7 @@ struct Keyboard { static uint16_t decode(const char *name) { string s(name); if(!strbegin(name, "KB")) return 0; - ltrim(s, "KB"); + s.ltrim("KB"); unsigned id = strunsigned(s); auto pos = strpos(s, "::"); if(!pos) return 0; @@ -188,7 +188,7 @@ struct Mouse { static uint16_t decode(const char *name) { string s(name); if(!strbegin(name, "MS")) return 0; - ltrim(s, "MS"); + s.ltrim("MS"); unsigned id = strunsigned(s); auto pos = strpos(s, "::"); if(!pos) return 0; @@ -312,7 +312,7 @@ struct Joypad { static uint16_t decode(const char *name) { string s(name); if(!strbegin(name, "JP")) return 0; - ltrim(s, "JP"); + s.ltrim("JP"); unsigned id = strunsigned(s); auto pos = strpos(s, "::"); if(!pos) return 0; diff --git a/src/nall/qt/file-dialog.moc.hpp b/src/nall/qt/file-dialog.moc.hpp index 6528289b..3cb8989e 100644 --- a/src/nall/qt/file-dialog.moc.hpp +++ b/src/nall/qt/file-dialog.moc.hpp @@ -212,8 +212,8 @@ inline void FileDialog::filterBoxChanged() { fileSystemModel->setNameFilters(QStringList() << "*"); } else { filters = substr(filters, strpos(filters, "(")()); - ltrim(filters, "("); - rtrim(filters, ")"); + filters.ltrim("("); + filters.rtrim(")"); lstring part; part.split(" ", filters); QStringList list; @@ -279,7 +279,7 @@ inline void FileDialog::setNameFilters(const string &filters) { inline void FileDialog::acceptAction() { string path = fileSystemModel->rootPath().toUtf8().constData(); path << "/" << notdir(fileNameEdit->text().toUtf8().constData()); - rtrim(path, "/"); + path.rtrim("/"); if(QDir(path).exists()) { emit accepted(path); setPath(path); diff --git a/src/nall/string/base.hpp b/src/nall/string/base.hpp index cc83e2bc..6feb51f6 100644 --- a/src/nall/string/base.hpp +++ b/src/nall/string/base.hpp @@ -52,6 +52,16 @@ namespace nall { inline string& replace (const char*, const char*); inline string& qreplace(const char*, const char*); + inline string& lower(); + inline string& upper(); + inline string& transform(const char *before, const char *after); + inline string& ltrim(const char *key = " "); + inline string& rtrim(const char *key = " "); + inline string& trim (const char *key = " "); + inline string& ltrim_once(const char *key = " "); + inline string& rtrim_once(const char *key = " "); + inline string& trim_once (const char *key = " "); + protected: char *data; unsigned size; @@ -66,7 +76,7 @@ namespace nall { public: template inline lstring& operator<<(T value); - inline int find(const char*); + inline optional find(const char*); inline void split (const char*, const char*, unsigned = 0); inline void qsplit(const char*, const char*, unsigned = 0); @@ -116,15 +126,7 @@ namespace nall { inline unsigned strlcpy(string &dest, const char *src, unsigned length); inline unsigned strlcat(string &dest, const char *src, unsigned length); inline string substr(const char *src, unsigned start = 0, unsigned length = 0); - inline string& strlower(string &str); - inline string& strupper(string &str); inline string& strtr(string &dest, const char *before, const char *after); - inline string& ltrim(string &str, const char *key = " "); - inline string& rtrim(string &str, const char *key = " "); - inline string& trim (string &str, const char *key = " "); - inline string& ltrim_once(string &str, const char *key = " "); - inline string& rtrim_once(string &str, const char *key = " "); - inline string& trim_once (string &str, const char *key = " "); template inline string strhex(uintmax_t value); template inline string strsigned(intmax_t value); template inline string strunsigned(uintmax_t value); diff --git a/src/nall/string/convert.hpp b/src/nall/string/convert.hpp index 12a6c1ff..3b8f155d 100644 --- a/src/nall/string/convert.hpp +++ b/src/nall/string/convert.hpp @@ -40,6 +40,10 @@ char* strtr(char *dest, const char *before, const char *after) { return dest; } +string& string::lower() { nall::strlower(data); return *this; } +string& string::upper() { nall::strupper(data); return *this; } +string& string::transform(const char *before, const char *after) { nall::strtr(data, before, after); return *this; } + uintmax_t strhex(const char *str) { if(!str) return 0; uintmax_t result = 0; diff --git a/src/nall/string/core.hpp b/src/nall/string/core.hpp index 3326691b..12245378 100644 --- a/src/nall/string/core.hpp +++ b/src/nall/string/core.hpp @@ -122,11 +122,11 @@ bool string::readfile(const char *filename) { return true; } -int lstring::find(const char *key) { +optional lstring::find(const char *key) { for(unsigned i = 0; i < size(); i++) { - if(operator[](i) == key) return i; + if(operator[](i) == key) return { true, i }; } - return -1; + return { false, 0 }; } inline lstring::lstring() { diff --git a/src/nall/string/strpos.hpp b/src/nall/string/strpos.hpp index 5d7e200a..8d880cce 100644 --- a/src/nall/string/strpos.hpp +++ b/src/nall/string/strpos.hpp @@ -7,7 +7,7 @@ namespace nall { -optional inline strpos(const char *str, const char *key) { +inline optional strpos(const char *str, const char *key) { unsigned ssl = strlen(str), ksl = strlen(key); if(ksl > ssl) return { false, 0 }; @@ -18,7 +18,7 @@ optional inline strpos(const char *str, const char *key) { return { false, 0 }; } -optional inline qstrpos(const char *str, const char *key) { +inline optional qstrpos(const char *str, const char *key) { unsigned ssl = strlen(str), ksl = strlen(key); if(ksl > ssl) return { false, 0 }; diff --git a/src/nall/string/trim.hpp b/src/nall/string/trim.hpp index b13ab9ba..4fda05ec 100644 --- a/src/nall/string/trim.hpp +++ b/src/nall/string/trim.hpp @@ -49,6 +49,13 @@ char* trim_once(char *str, const char *key) { return ltrim_once(rtrim_once(str, key), key); } +string& string::ltrim(const char *key) { nall::ltrim(data, key); return *this; } +string& string::rtrim(const char *key) { nall::rtrim(data, key); return *this; } +string& string::trim (const char *key) { nall::trim (data, key); return *this; } +string& string::ltrim_once(const char *key) { nall::ltrim_once(data, key); return *this; } +string& string::rtrim_once(const char *key) { nall::rtrim_once(data, key); return *this; } +string& string::trim_once (const char *key) { nall::trim_once (data, key); return *this; } + } #endif diff --git a/src/nall/string/utility.hpp b/src/nall/string/utility.hpp index 2da2762b..d2bad881 100644 --- a/src/nall/string/utility.hpp +++ b/src/nall/string/utility.hpp @@ -25,18 +25,6 @@ string substr(const char *src, unsigned start, unsigned length) { return dest; } -/* very simplistic wrappers to return string& instead of char* type */ - -string& strlower(string &str) { strlower(str()); return str; } -string& strupper(string &str) { strupper(str()); return str; } -string& strtr(string &dest, const char *before, const char *after) { strtr(dest(), before, after); return dest; } -string& ltrim(string &str, const char *key) { ltrim(str(), key); return str; } -string& rtrim(string &str, const char *key) { rtrim(str(), key); return str; } -string& trim (string &str, const char *key) { trim (str(), key); return str; } -string& ltrim_once(string &str, const char *key) { ltrim_once(str(), key); return str; } -string& rtrim_once(string &str, const char *key) { rtrim_once(str(), key); return str; } -string& trim_once (string &str, const char *key) { trim_once (str(), key); return str; } - /* arithmetic <> string */ template string strhex(uintmax_t value) { diff --git a/src/nall/string/xml.hpp b/src/nall/string/xml.hpp index 6a4c672d..411b477a 100644 --- a/src/nall/string/xml.hpp +++ b/src/nall/string/xml.hpp @@ -122,7 +122,7 @@ inline bool xml_element::parse_head(string data) { while(qstrpos(data, " ")) data.qreplace(" ", " "); data.qreplace(" =", "="); data.qreplace("= ", "="); - rtrim(data); + data.rtrim(); lstring part; part.qsplit(" ", data); @@ -138,8 +138,8 @@ inline bool xml_element::parse_head(string data) { xml_attribute attr; attr.name = side[0]; attr.content = side[1]; - if(strbegin(attr.content, "\"") && strend(attr.content, "\"")) trim_once(attr.content, "\""); - else if(strbegin(attr.content, "'") && strend(attr.content, "'")) trim_once(attr.content, "'"); + if(strbegin(attr.content, "\"") && strend(attr.content, "\"")) attr.content.trim_once("\""); + else if(strbegin(attr.content, "'") && strend(attr.content, "'")) attr.content.trim_once("'"); else throw "..."; attribute.append(attr); } @@ -185,10 +185,10 @@ inline bool xml_element::parse_body(const char *&data) { if(strend(tag, "?") == true) { self_terminating = true; - rtrim_once(tag, "?"); + tag.rtrim_once("?"); } else if(strend(tag, "/") == true) { self_terminating = true; - rtrim_once(tag, "/"); + tag.rtrim_once("/"); } parse_head(tag); @@ -213,7 +213,7 @@ inline bool xml_element::parse_body(const char *&data) { tag.replace("\r", " "); tag.replace("\n", " "); while(strpos(tag, " ")) tag.replace(" ", " "); - rtrim(tag); + tag.rtrim(); if(name != tag) throw "..."; return true; diff --git a/src/snes/cheat/cheat.cpp b/src/snes/cheat/cheat.cpp index f08e9561..6f954b95 100644 --- a/src/snes/cheat/cheat.cpp +++ b/src/snes/cheat/cheat.cpp @@ -73,7 +73,7 @@ Cheat::Cheat() { bool Cheat::decode(const char *s, unsigned &addr, uint8 &data, Type &type) { string t = s; - strlower(t); + t.lower(); #define ischr(n) ((n >= '0' && n <= '9') || (n >= 'a' && n <= 'f')) @@ -95,7 +95,7 @@ bool Cheat::decode(const char *s, unsigned &addr, uint8 &data, Type &type) { for(unsigned i = 0; i < 8; i++) if(!ischr(t[i])) return false; type = Type::GameGenie; - strtr(t, "df4709156bc8a23e", "0123456789abcdef"); + t.transform("df4709156bc8a23e", "0123456789abcdef"); unsigned r = strhex((const char*)t); //8421 8421 8421 8421 8421 8421 //abcd efgh ijkl mnop qrst uvwx @@ -142,7 +142,7 @@ bool Cheat::encode(string &s, unsigned addr, uint8 data, Type type) { | (!!(r & 0x020000) << 3) | (!!(r & 0x010000) << 2) | (!!(r & 0x000800) << 1) | (!!(r & 0x000400) << 0); s = string(strhex<2>(data), strhex<2>(addr >> 16), "-", strhex<4>(addr & 0xffff)); - strtr(s, "0123456789abcdef", "df4709156bc8a23e"); + s.transform("0123456789abcdef", "df4709156bc8a23e"); return true; } else { return false; diff --git a/src/snes/snes.hpp b/src/snes/snes.hpp index c6e4d9b6..8d141836 100644 --- a/src/snes/snes.hpp +++ b/src/snes/snes.hpp @@ -1,4 +1,4 @@ -static const char bsnesVersion[] = "065.03"; +static const char bsnesVersion[] = "065.04"; static const char bsnesTitle[] = "bsnes"; static const unsigned bsnesSerializerVersion = 10; diff --git a/src/ui_qt/tools/cheateditor.cpp b/src/ui_qt/tools/cheateditor.cpp index e2909293..a9348c74 100644 --- a/src/ui_qt/tools/cheateditor.cpp +++ b/src/ui_qt/tools/cheateditor.cpp @@ -102,10 +102,10 @@ void CheatEditorWindow::load(const char *filename) { for(unsigned i = 0; i < 128; i++) { lstring part; if(line.size() > i) part.qsplit(",", line[i]); - for(unsigned n = 0; n <= 2; n++) trim(part[n], " "); - trim(part[0], "\""); - trim(part[1], "\""); - trim(part[2], "\""); + for(unsigned n = 0; n <= 2; n++) { + part[n].trim(" "); + part[n].trim("\""); + } part[2].replace("\\q", "\""); auto item = new QTreeWidgetItem(list);