diff options
Diffstat (limited to 'Source/Core/Common/Src/StringUtil.cpp')
| -rw-r--r-- | Source/Core/Common/Src/StringUtil.cpp | 413 |
1 files changed, 82 insertions, 331 deletions
diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp index 7926939f2f..7264085ac7 100644 --- a/Source/Core/Common/Src/StringUtil.cpp +++ b/Source/Core/Common/Src/StringUtil.cpp @@ -26,45 +26,15 @@ bool AsciiToHex(const char* _szValue, u32& result) { char *endptr = NULL; - u32 value = strtoul(_szValue,&endptr,16); - if (!endptr || *endptr != '\0') + const u32 value = strtoul(_szValue, &endptr, 16); + + if (!endptr || *endptr) return false; + result = value; return true; } -// Convert AB to it's ascii table entry numbers 0x4142 -u32 Ascii2Hex(std::string _Text) -{ - // Reset the return value zero - u32 Result = 0; - - // Max 32-bit values are supported - size_t Length = _Text.length(); - if (Length > 4) - Length = 4; - - for (int i = 0; i < (int)Length; i++) - { - // Add up the values, for example RSPE becomes, 0x52000000, then 0x52530000 and so on - Result += _Text.c_str()[i] << ((Length - 1 - i) * 8); - } - // Return the value - return Result; -} - -// Convert it back again -std::string Hex2Ascii(u32 _Text) -{ - // Create temporary storate - char Result[5]; // need space for the final \0 - // Go through the four characters - sprintf(Result, "%c%c%c%c", _Text >> 24, _Text >> 16, _Text >> 8, _Text); - // Return the string - std::string StrResult = Result; - return StrResult; -} - bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args) { int writtenCount = vsnprintf(out, outsize, format, args); @@ -81,84 +51,24 @@ bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list ar } } -// Expensive! -void ToStringFromFormat(std::string* out, const char* format, ...) +std::string StringFromFormat(const char* format, ...) { int writtenCount = -1; - int newSize = (int)strlen(format) + 4; - char *buf = 0; + size_t newSize = strlen(format) + 4; + char *buf = NULL; va_list args; while (writtenCount < 0) { - delete [] buf; + delete[] buf; buf = new char[newSize + 1]; va_start(args, format); writtenCount = vsnprintf(buf, newSize, format, args); va_end(args); - if (writtenCount >= (int)newSize) { - writtenCount = -1; - } - // ARGH! vsnprintf does no longer return -1 on truncation in newer libc! - // WORKAROUND! let's fake the old behaviour (even though it's less efficient). - // TODO: figure out why the fix causes an invalid read in strlen called from vsnprintf :( -// if (writtenCount >= (int)newSize) -// writtenCount = -1; - newSize *= 2; - } - - buf[writtenCount] = '\0'; - *out = buf; - delete[] buf; -} -std::wstring StringFromFormat(const wchar_t* format, ...) -{ - int writtenCount = -1; - int newSize = (int)wcslen(format) + 4; - wchar_t *buf = 0; - va_list args; - while (writtenCount < 0) - { - delete [] buf; - buf = new wchar_t[newSize + 1]; - - va_start(args, format); - writtenCount = vswprintf(buf, newSize, format, args); - va_end(args); - if (writtenCount >= (int)newSize) { + if (writtenCount >= (int)newSize) writtenCount = -1; - } - // ARGH! vsnprintf does no longer return -1 on truncation in newer libc! - // WORKAROUND! let's fake the old behaviour (even though it's less efficient). - // TODO: figure out why the fix causes an invalid read in strlen called from vsnprintf :( -// if (writtenCount >= (int)newSize) -// writtenCount = -1; - newSize *= 2; - } - buf[writtenCount] = '\0'; - std::wstring temp = buf; - delete[] buf; - return temp; -} -std::string StringFromFormat(const char* format, ...) -{ - int writtenCount = -1; - int newSize = (int)strlen(format) + 4; - char *buf = 0; - va_list args; - while (writtenCount < 0) - { - delete [] buf; - buf = new char[newSize + 1]; - - va_start(args, format); - writtenCount = vsnprintf(buf, newSize, format, args); - va_end(args); - if (writtenCount >= (int)newSize) { - writtenCount = -1; - } // ARGH! vsnprintf does no longer return -1 on truncation in newer libc! // WORKAROUND! let's fake the old behaviour (even though it's less efficient). // TODO: figure out why the fix causes an invalid read in strlen called from vsnprintf :( @@ -174,42 +84,36 @@ std::string StringFromFormat(const char* format, ...) } // For Debugging. Read out an u8 array. -std::string ArrayToString(const u8 *data, u32 size, u32 offset, int line_len, bool Spaces) -{ - std::string Tmp, Spc; - if (Spaces) Spc = " "; else Spc = ""; - for (u32 i = 0; i < size; i++) - { - Tmp += StringFromFormat("%02x%s", data[i + offset], Spc.c_str()); - if(i > 1 && (i + 1) % line_len == 0) Tmp.append("\n"); // break long lines - } - return Tmp; -} - -// Turns " hej " into "hej". Also handles tabs. -std::string StripSpaces(const std::string &str) +std::string ArrayToString(const u8 *data, u32 size, int line_len, bool spaces) { - std::string s = str; - int i; - for (i = 0; i < (int)s.size(); i++) + std::ostringstream oss; + oss << std::setfill('0') << std::hex; + + for (int line = 0; size; ++data, --size) { - if ((s[i] != ' ') && (s[i] != 9)) + oss << std::setw(2) << (int)*data; + + if (line_len == ++line) { - break; + oss << '\n'; + line = 0; } + else if (spaces) + oss << ' '; } - s = s.substr(i); + return oss.str(); +} - for (i = (int)s.size() - 1; i > 0; i--) - { - if ((s[i] != ' ') && (s[i] != 9)) - { - break; - } - } +// Turns " hej " into "hej". Also handles tabs. +std::string StripSpaces(const std::string &str) +{ + const size_t s = str.find_first_not_of(" \t\r\n"); - return s.substr(0, i + 1); + if (str.npos != s) + return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1); + else + return ""; } // "\"hello\"" is turned to "hello" @@ -217,7 +121,7 @@ std::string StripSpaces(const std::string &str) // ends, as done by StripSpaces above, for example. std::string StripQuotes(const std::string& s) { - if ((s[0] == '\"') && (s[s.size() - 1] == '\"')) + if (s.size() && '\"' == s[0] && '\"' == *s.rbegin()) return s.substr(1, s.size() - 2); else return s; @@ -228,63 +132,41 @@ std::string StripQuotes(const std::string& s) // ends, as done by StripSpaces above, for example. std::string StripNewline(const std::string& s) { - if (!s.size()) - return s; - else if (s[s.size() - 1] == '\n') + if (s.size() && '\n' == *s.rbegin()) return s.substr(0, s.size() - 1); else return s; } -bool TryParseInt(const char* str, int* outVal) +bool TryParse(const std::string &str, u32 *const output) { char *endptr = NULL; - int value = strtol(str,&endptr,10); - if (!endptr || *endptr != '\0') + u32 value = strtoul(str.c_str(), &endptr, 0); + + if (!endptr || *endptr) return false; - *outVal = value; + + *output = value; return true; } -bool TryParseBool(const char* str, bool* output) +bool TryParse(const std::string &str, bool *const output) { - if ((str[0] == '1') || !strcasecmp(str, "true")) - { + if ('1' == str[0] || !stricmp("true", str.c_str())) *output = true; - return true; - } - else if (str[0] == '0' || !strcasecmp(str, "false")) - { + else if ('0' == str[0] || !stricmp("false", str.c_str())) *output = false; - return true; - } - return false; -} - -bool TryParseFloat(const char* str, float *output) -{ - float d_val; - if (sscanf(str, "%f", &d_val) == 1) - { - *output = (float)d_val; - return true; - } else - { return false; - } -} -bool TryParseDouble(const char* str, double *output) -{ - return sscanf(str, "%lf", output) == 1; + return true; } std::string StringFromInt(int value) { char temp[16]; sprintf(temp, "%i", value); - return std::string(temp); + return temp; } std::string StringFromBool(bool value) @@ -292,207 +174,76 @@ std::string StringFromBool(bool value) return value ? "True" : "False"; } -#ifdef _WIN32 -bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension) -{ - char drive[_MAX_DRIVE]; - char dir[_MAX_DIR]; - char fname[_MAX_FNAME]; - char ext[_MAX_EXT]; - - if (_splitpath_s(full_path.c_str(), drive, _MAX_DRIVE, dir, _MAX_DIR, fname, _MAX_FNAME, ext, _MAX_EXT) == 0) - { - if (_pPath) - { - *_pPath = std::string(drive) + std::string(dir); - } - - if (_pFilename != 0) - { - *_pFilename = fname; - } - - if (_pExtension != 0) - { - *_pExtension = ext; - } - - return true; - } - - return false; -} - - -#else bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension) { - size_t last_slash = full_path.rfind('/'); - - if (last_slash == std::string::npos) - { - return false; // FIXME return the filename - } + if (full_path.empty()) + return false; - size_t last_dot = full_path.rfind('.'); + size_t dir_end = full_path.find_last_of("/" + // windows needs the : included for something like just "C:" to be considered a directory +#ifdef _WIN32 + ":" +#endif + ); + if (std::string::npos == dir_end) + dir_end = 0; + else + dir_end += 1; - if ((last_dot == std::string::npos) || (last_dot < last_slash)) - { - return false; // FIXME why missing . is critical? - } + size_t fname_end = full_path.rfind('.'); + if (fname_end < dir_end || std::string::npos == fname_end) + fname_end = full_path.size(); if (_pPath) - { - *_pPath = full_path.substr(0, last_slash + 1); - } + *_pPath = full_path.substr(0, dir_end); if (_pFilename) - { - *_pFilename = full_path.substr(last_slash + 1, last_dot - (last_slash + 1)); - } + *_pFilename = full_path.substr(dir_end, fname_end - dir_end); if (_pExtension) - { - *_pExtension = full_path.substr(last_dot + 1); - _pExtension->insert(0, "."); - } - else if (_pFilename) - { - *_pFilename += full_path.substr(last_dot); - } + *_pExtension = full_path.substr(fname_end); return true; } -#endif +std::string PathToFilename(const std::string &Path) +{ + std::string Name, Ending; + SplitPath(Path, 0, &Name, &Ending); + return Name + Ending; +} void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _Path, const std::string& _Filename) { _CompleteFilename = _Path; // check for seperator - if (_CompleteFilename[_CompleteFilename.size() - 1] != DIR_SEP_CHR) - { -#ifdef _WIN32 - if (_CompleteFilename[_CompleteFilename.size() - 1] != '\\') -#endif - _CompleteFilename += DIR_SEP_CHR; - } + if (DIR_SEP_CHR != *_CompleteFilename.rbegin()) + _CompleteFilename += DIR_SEP_CHR; // add the filename _CompleteFilename += _Filename; } - -void SplitString(const std::string& str, const std::string& delim, std::vector<std::string>& output) +void SplitString(const std::string& str, const char delim, std::vector<std::string>& output) { - output.clear(); - - size_t offset = 0; - size_t delimIndex = 0; - - delimIndex = str.find(delim, offset); - - while (delimIndex != std::string::npos) - { - output.push_back(str.substr(offset, delimIndex - offset)); - offset += delimIndex - offset + delim.length(); - delimIndex = str.find(delim, offset); - } + std::istringstream iss(str); + output.resize(1); - output.push_back(str.substr(offset)); -} - - -bool TryParseUInt(const std::string& str, u32* output) -{ - char *endptr = NULL; - u32 value = strtoul(str.c_str(),&endptr,0); - if (!endptr || *endptr != '\0') - return false; - *output = value; - return true; -} + while (std::getline(iss, *output.rbegin(), delim)) + output.push_back(""); -int ChooseStringFrom(const char* str, const char* * items) -{ - int i = 0; - while (items[i] != 0) - { - if (!strcmp(str, items[i])) - return i; - i++; - } - return -1; + output.pop_back(); } - -// Thousand separator. Turns 12345678 into 12,345,678 -std::string ThS(int Integer, bool Unsigned, int Spaces) +std::string TabsToSpaces(int tab_size, const std::string &in) { - // Create storage space - char cbuf[20]; - // Determine treatment of signed or unsigned - if(Unsigned) sprintf(cbuf, "%u", Integer); else sprintf(cbuf, "%i", Integer); - - std::string Sbuf = cbuf; - for (u32 i = 0; i < Sbuf.length(); ++i) - { - if((i & 3) == 3) - { - Sbuf.insert(Sbuf.length() - i, ","); - } - } - - // Spaces - std::string Spc = ""; - for (int i = 0; i < (int)(Spaces - Sbuf.length()); i++) Spc += " "; - return Spc + Sbuf; -} + const std::string spaces(tab_size, ' '); + std::string out(in); -void NormalizeDirSep(std::string* str) -{ -#ifdef _WIN32 - int i; - while ((i = (int)str->find_first_of('\\')) >= 0) - { - str->replace(i, 1, DIR_SEP); - } -#endif -} + size_t i = 0; + while (out.npos != (i = out.find('\t'))) + out.replace(i, 1, spaces); -std::string TabsToSpaces(int tab_size, const std::string &in) -{ - std::string out; - int len = 0; - // First, compute the size of the new string. - for (unsigned i = 0; i < in.size(); i++) - { - if (in[i] == '\t') - len += tab_size; - else - len += 1; - } - out.resize(len); - int out_ctr = 0; - for (unsigned i = 0; i < in.size(); i++) - { - if (in[i] == '\t') - { - for (int j = 0; j < tab_size; j++) - out[out_ctr++] = ' '; - } - else - { - out[out_ctr++] = in[i]; - } - } return out; } - -std::string PathToFilename(std::string Path) -{ - std::string Name, Ending; - SplitPath(Path, 0, &Name, &Ending); - return Name + Ending; -} |
