647 lines
16 KiB
C++
647 lines
16 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2006-2010 - Frictional Games
|
|
*
|
|
* This file is part of HPL1 Engine.
|
|
*/
|
|
|
|
#include "hpl1/engine/system/String.h"
|
|
|
|
#include "hpl1/engine/system/low_level_system.h"
|
|
|
|
namespace hpl {
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// PUBLIC METHODS
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tWString cString::To16Char(const tString &asString) {
|
|
return asString;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tString cString::To8Char(const tWString &awsString) {
|
|
return awsString;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tWString cString::Get16BitFromArray(const tString &asArray) {
|
|
// TODOD: needs to be rewritten to be more portal as wchar_t is not ALWAYS 2 bytes. (it's 4 on linux and os x)
|
|
tIntVec vVals;
|
|
GetIntVec(asArray, vVals, NULL);
|
|
|
|
tWString wsString;
|
|
for (auto v : vVals) {
|
|
wsString += static_cast<Common::U32String::value_type>(v);
|
|
}
|
|
return wsString;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tString cString::Sub(const tString &asString, int alStart, int alCount) {
|
|
int lStringSize = (int)asString.size();
|
|
if (alStart >= lStringSize)
|
|
return "";
|
|
if (alStart + alCount > lStringSize)
|
|
alCount = lStringSize - alStart;
|
|
|
|
if (alCount < 0)
|
|
return asString.substr(alStart);
|
|
else
|
|
return asString.substr(alStart, alCount);
|
|
}
|
|
tWString cString::SubW(const tWString &asString, int alStart, int alCount) {
|
|
int lStringSize = (int)asString.size();
|
|
if (lStringSize == 0)
|
|
return Common::U32String("");
|
|
if (alStart >= lStringSize)
|
|
return Common::U32String("");
|
|
if (alStart + alCount > lStringSize)
|
|
alCount = lStringSize - alStart;
|
|
|
|
if (alCount < 0)
|
|
return asString.substr(alStart);
|
|
else
|
|
return asString.substr(alStart, alCount);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
// Get the file extension of a string
|
|
tString cString::GetFileExt(const tString &aString) {
|
|
int pos = GetLastStringPos(aString, ".");
|
|
|
|
if (pos < 0)
|
|
return "";
|
|
else
|
|
return aString.substr(pos + 1);
|
|
}
|
|
|
|
tWString cString::GetFileExtW(const tWString &aString) {
|
|
int pos = GetLastStringPosW(aString, Common::U32String("."));
|
|
|
|
if (pos < 0)
|
|
return Common::U32String("");
|
|
else
|
|
return aString.substr(pos + 1);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tString cString::ToLowerCase(tString aString) {
|
|
aString.toLowercase();
|
|
return aString;
|
|
}
|
|
|
|
tWString cString::ToLowerCaseW(tWString aString) {
|
|
aString.toLowercase();
|
|
return aString;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Set the file extension
|
|
tString cString::SetFileExt(tString aString, tString aExt) {
|
|
if (aExt.substr(0, 1) == ".")
|
|
aExt = aExt.substr(1);
|
|
if (GetFileExt(aString) != "") {
|
|
aString = aString.substr(0, GetLastStringPos(aString, "."));
|
|
}
|
|
|
|
if (aExt != "")
|
|
aString = aString + "." + aExt;
|
|
|
|
return aString;
|
|
}
|
|
|
|
tWString cString::SetFileExtW(tWString aString, tWString aExt) {
|
|
if (aExt.substr(0, 1) == Common::U32String("."))
|
|
aExt = aExt.substr(1);
|
|
if (GetFileExtW(aString) != Common::U32String("")) {
|
|
aString = aString.substr(0, GetLastStringPosW(aString, Common::U32String(".")));
|
|
}
|
|
|
|
if (aExt != Common::U32String(""))
|
|
aString = aString + _W(".") + aExt;
|
|
|
|
return aString;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tString cString::SetFilePath(const tString &aString, tString aPath) {
|
|
if (GetLastChar(aPath) != "/" && GetLastChar(aPath) != "\\")
|
|
aPath += "/";
|
|
|
|
auto fileName = GetFileName(aString);
|
|
|
|
return aPath + fileName;
|
|
}
|
|
|
|
tWString cString::SetFilePathW(tWString aString, tWString aPath) {
|
|
if (GetLastCharW(aPath) != _W("/") && GetLastCharW(aPath) != _W("\\"))
|
|
aPath += _W("/");
|
|
|
|
aString = GetFileNameW(aString);
|
|
|
|
return aPath + aString;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
// Gets the filename in a path
|
|
tString cString::GetFileName(const tString &aString) {
|
|
int pos1 = GetLastStringPos(aString, "\\");
|
|
int pos2 = GetLastStringPos(aString, "/");
|
|
int pos = pos1 > pos2 ? pos1 : pos2;
|
|
|
|
if (pos < 0)
|
|
return aString;
|
|
else
|
|
return aString.substr(pos + 1);
|
|
}
|
|
tWString cString::GetFileNameW(const tWString &aString) {
|
|
int pos1 = GetLastStringPosW(aString, _W("\\"));
|
|
int pos2 = GetLastStringPosW(aString, _W("/"));
|
|
int pos = pos1 > pos2 ? pos1 : pos2;
|
|
|
|
if (pos < 0)
|
|
return aString;
|
|
else
|
|
return aString.substr(pos + 1);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tString cString::GetFilePath(const tString &aString) {
|
|
if (GetLastStringPos(aString, ".") < 0)
|
|
return aString;
|
|
|
|
int pos1 = GetLastStringPos(aString, "\\");
|
|
int pos2 = GetLastStringPos(aString, "/");
|
|
int pos = pos1 > pos2 ? pos1 : pos2;
|
|
|
|
if (pos < 0)
|
|
return "";
|
|
else
|
|
return aString.substr(0, pos + 1);
|
|
}
|
|
|
|
tWString cString::GetFilePathW(const tWString &aString) {
|
|
if (GetLastStringPosW(aString, _W(".")) < 0)
|
|
return aString;
|
|
|
|
int pos1 = GetLastStringPosW(aString, _W("\\"));
|
|
int pos2 = GetLastStringPosW(aString, _W("/"));
|
|
int pos = pos1 > pos2 ? pos1 : pos2;
|
|
|
|
if (pos < 0)
|
|
return _W("");
|
|
else
|
|
return aString.substr(0, pos + 1);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tString cString::ReplaceCharTo(tString aString, const tString &asOldChar, const tString &asNewChar) {
|
|
if (asNewChar != "") {
|
|
for (int i = 0; i < (int)aString.size(); i++) {
|
|
if (aString[i] == asOldChar[0])
|
|
aString.setChar(asNewChar[0], i);
|
|
}
|
|
return aString;
|
|
} else {
|
|
tString sNewString;
|
|
|
|
for (int i = 0; i < (int)aString.size(); i++) {
|
|
if (aString[i] != asOldChar[0])
|
|
sNewString += aString[i];
|
|
}
|
|
return sNewString;
|
|
}
|
|
}
|
|
|
|
tWString cString::ReplaceCharToW(tWString aString, const tWString &asOldChar, const tWString &asNewChar) {
|
|
if (asNewChar != _W("")) {
|
|
for (int i = 0; i < (int)aString.size(); i++) {
|
|
if (aString[i] == asOldChar[0])
|
|
aString.setChar(asNewChar[0], i);
|
|
}
|
|
return aString;
|
|
} else {
|
|
tWString sNewString;
|
|
|
|
for (int i = 0; i < (int)aString.size(); i++) {
|
|
if (aString[i] != asOldChar[0])
|
|
sNewString += aString[i];
|
|
}
|
|
return sNewString;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tString cString::ReplaceStringTo(const tString &aString, const tString &asOldString, const tString &asNewString) {
|
|
tString sNewString = "";
|
|
|
|
for (size_t i = 0; i < aString.size(); i++) {
|
|
bool bFound = true;
|
|
// Search for old string
|
|
if (aString.size() >= i + asOldString.size()) {
|
|
for (size_t j = 0; j < asOldString.size(); ++j) {
|
|
if (aString[i + j] != asOldString[j]) {
|
|
bFound = false;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
bFound = false;
|
|
}
|
|
|
|
// Insert new string
|
|
if (bFound) {
|
|
sNewString += asNewString;
|
|
i += asOldString.size() - 1;
|
|
}
|
|
// Just add the character
|
|
else {
|
|
sNewString += aString[i];
|
|
}
|
|
}
|
|
return sNewString;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
// gets the last char in the string
|
|
tString cString::GetLastChar(const tString &aString) {
|
|
if (aString.size() == 0)
|
|
return "";
|
|
return aString.substr(aString.size() - 1);
|
|
}
|
|
|
|
tWString cString::GetLastCharW(const tWString &aString) {
|
|
if (aString.size() == 0)
|
|
return _W("");
|
|
return aString.substr(aString.size() - 1);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
tString cString::ToString(const char *asString, const tString &asDefault) {
|
|
if (asString == NULL)
|
|
return asDefault;
|
|
|
|
return asString;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
int cString::ToInt(const char *asString, int alDefault) {
|
|
if (asString == NULL)
|
|
return alDefault;
|
|
|
|
return atoi(asString);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
float cString::ToFloat(const char *asString, float afDefault) {
|
|
if (asString == NULL)
|
|
return afDefault;
|
|
|
|
return (float)atof(asString);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
bool cString::ToBool(const char *asString, bool abDefault) {
|
|
if (asString == NULL)
|
|
return abDefault;
|
|
|
|
tString asTempString = ToLowerCase(asString);
|
|
return asTempString == "true" ? true : false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cColor cString::ToColor(const char *asString, const cColor &aDefault) {
|
|
if (asString == NULL)
|
|
return aDefault;
|
|
|
|
tFloatVec vValues;
|
|
|
|
GetFloatVec(asString, vValues, NULL);
|
|
|
|
if (vValues.size() != 4)
|
|
return aDefault;
|
|
|
|
return cColor(vValues[0], vValues[1], vValues[2], vValues[3]);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cVector2f cString::ToVector2f(const char *asString, const cVector2f &avDefault) {
|
|
if (asString == NULL)
|
|
return avDefault;
|
|
|
|
tFloatVec vValues;
|
|
|
|
GetFloatVec(asString, vValues, NULL);
|
|
|
|
if (vValues.size() != 2)
|
|
return avDefault;
|
|
|
|
return cVector2f(vValues[0], vValues[1]);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cVector3f cString::ToVector3f(const char *asString, const cVector3f &avDefault) {
|
|
if (asString == NULL)
|
|
return avDefault;
|
|
|
|
tFloatVec vValues;
|
|
|
|
GetFloatVec(asString, vValues, NULL);
|
|
|
|
if (vValues.size() != 3)
|
|
return avDefault;
|
|
|
|
return cVector3f(vValues[0], vValues[1], vValues[2]);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cVector2l cString::ToVector2l(const char *asString, const cVector2l &avDefault) {
|
|
if (asString == NULL)
|
|
return avDefault;
|
|
|
|
tIntVec vValues;
|
|
|
|
GetIntVec(asString, vValues, NULL);
|
|
|
|
if (vValues.size() != 2)
|
|
return avDefault;
|
|
|
|
return cVector2l(vValues[0], vValues[1]);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cVector3l cString::ToVector3l(const char *asString, const cVector3l &avDefault) {
|
|
if (asString == NULL)
|
|
return avDefault;
|
|
|
|
tIntVec vValues;
|
|
|
|
GetIntVec(asString, vValues, NULL);
|
|
|
|
if (vValues.size() != 3)
|
|
return avDefault;
|
|
|
|
return cVector3l(vValues[0], vValues[1], vValues[2]);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
cMatrixf cString::ToMatrixf(const char *asString, const cMatrixf &a_mtxDefault) {
|
|
if (asString == NULL)
|
|
return a_mtxDefault;
|
|
|
|
tFloatVec vValues;
|
|
|
|
GetFloatVec(asString, vValues, NULL);
|
|
|
|
if (vValues.size() != 16)
|
|
return a_mtxDefault;
|
|
|
|
return cMatrixf(vValues[0], vValues[1], vValues[2], vValues[3],
|
|
vValues[4], vValues[5], vValues[6], vValues[7],
|
|
vValues[8], vValues[9], vValues[10], vValues[11],
|
|
vValues[12], vValues[13], vValues[14], vValues[15]);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tIntVec &cString::GetIntVec(const tString &asData, tIntVec &avVec, tString *apSeparators) {
|
|
tStringVec mvStr;
|
|
GetStringVec(asData, mvStr, apSeparators);
|
|
|
|
for (int i = 0; i < (int)mvStr.size(); i++) {
|
|
avVec.push_back(ToInt(mvStr[i].c_str(), 0));
|
|
}
|
|
|
|
return avVec;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tUIntVec &cString::GetUIntVec(const tString &asData, tUIntVec &avVec, tString *apSeparators) {
|
|
tStringVec mvStr;
|
|
GetStringVec(asData, mvStr, apSeparators);
|
|
|
|
for (int i = 0; i < (int)mvStr.size(); i++) {
|
|
avVec.push_back(ToInt(mvStr[i].c_str(), 0));
|
|
}
|
|
|
|
return avVec;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tFloatVec &cString::GetFloatVec(const tString &asData, tFloatVec &avVec, tString *apSeparators) {
|
|
tStringVec mvStr;
|
|
GetStringVec(asData, mvStr, apSeparators);
|
|
|
|
for (int i = 0; i < (int)mvStr.size(); i++) {
|
|
avVec.push_back(ToFloat(mvStr[i].c_str(), 0));
|
|
}
|
|
|
|
return avVec;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tString cString::ToString(int alX) {
|
|
char buff[256];
|
|
|
|
snprintf(buff, 256, "%d", alX);
|
|
|
|
return buff;
|
|
}
|
|
|
|
tString cString::ToString(float afX) {
|
|
char buff[256];
|
|
|
|
snprintf(buff, 256, "%f", afX);
|
|
|
|
return buff;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tWString cString::ToStringW(int alX) {
|
|
return Common::U32String::format("%d", alX);
|
|
}
|
|
|
|
tWString cString::ToStringW(float afX) {
|
|
return Common::U32String::format("%f", afX);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
tStringVec &cString::GetStringVec(const tString &asData, tStringVec &avVec, tString *apSeparators) {
|
|
tString str = "";
|
|
bool start = false;
|
|
tString c = "";
|
|
|
|
for (int i = 0; i < (int)asData.size(); i++) {
|
|
c = asData.substr(i, 1);
|
|
bool bNewWord = false;
|
|
|
|
// Check if the current char is a separator
|
|
if (apSeparators) {
|
|
for (size_t j = 0; j < apSeparators->size(); j++) {
|
|
if ((*apSeparators)[j] == c[0]) {
|
|
bNewWord = true;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
if (c[0] == ' ' || c[0] == '\n' || c[0] == '\t' || c[0] == ',') {
|
|
bNewWord = true;
|
|
}
|
|
}
|
|
|
|
if (bNewWord) {
|
|
if (start) {
|
|
start = false;
|
|
avVec.push_back(str);
|
|
str = "";
|
|
}
|
|
} else {
|
|
start = true;
|
|
str += c;
|
|
if (i == (int)asData.size() - 1)
|
|
avVec.push_back(str);
|
|
}
|
|
}
|
|
|
|
return avVec;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
/// Helper
|
|
// returns last char in a string
|
|
int cString::GetLastStringPos(const tString &aString, const tString &aChar) {
|
|
int pos = -1;
|
|
for (int i = 0; i < (int)aString.size(); i++) {
|
|
if (aString.substr(i, aChar.size()) == aChar)
|
|
pos = i;
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
/// Helper
|
|
// returns last char in a string
|
|
int cString::GetLastStringPosW(const tWString &aString, const tWString &aChar) {
|
|
int pos = -1;
|
|
for (int i = 0; i < (int)aString.size(); i++) {
|
|
if (aString.substr(i, aChar.size()) == aChar)
|
|
pos = i;
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cString::UIntStringToArray(unsigned int *apArray, const char *apString, int alSize) {
|
|
char vTempChar[20];
|
|
int lTempCharCount = 0;
|
|
|
|
int lArrayCount = 0;
|
|
int lStringCount = 0;
|
|
|
|
while (lArrayCount < alSize) {
|
|
char c = apString[lStringCount];
|
|
|
|
// if a space is found, convert the previous characters to a float.
|
|
if (c == ' ' || c == 0) {
|
|
if (lTempCharCount > 0) {
|
|
vTempChar[lTempCharCount] = 0;
|
|
apArray[lArrayCount] = (unsigned int)atoi(vTempChar);
|
|
|
|
lTempCharCount = 0;
|
|
lArrayCount++;
|
|
}
|
|
}
|
|
// If character is not a space, add to temp char.
|
|
else {
|
|
vTempChar[lTempCharCount] = c;
|
|
lTempCharCount++;
|
|
}
|
|
|
|
lStringCount++;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
void cString::FloatStringToArray(float *apArray, const char *apString, int alSize) {
|
|
char vTempChar[20];
|
|
int lTempCharCount = 0;
|
|
|
|
int lArrayCount = 0;
|
|
int lStringCount = 0;
|
|
|
|
while (lArrayCount < alSize) {
|
|
char c = apString[lStringCount];
|
|
// if a space is found, convert the previous characters to a float.
|
|
if (c == ' ' || c == 0) {
|
|
if (lTempCharCount > 0) {
|
|
vTempChar[lTempCharCount] = 0;
|
|
apArray[lArrayCount] = (float)atof(vTempChar);
|
|
|
|
lTempCharCount = 0;
|
|
lArrayCount++;
|
|
}
|
|
}
|
|
// If character is not a space, add to temp char.
|
|
else {
|
|
vTempChar[lTempCharCount] = apString[lStringCount];
|
|
lTempCharCount++;
|
|
}
|
|
|
|
lStringCount++;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
} // namespace hpl
|