Add string formatting function with named params.

In addition to the formatting function, a matching Escape type is added.
This commit is contained in:
Stéphan Kochen
2011-10-16 17:27:43 +02:00
parent f7e5b41ab1
commit 2fdf54d43d
2 changed files with 77 additions and 1 deletions
+13 -1
View File
@@ -27,6 +27,7 @@ using std::pair;
#define _SQL(s) CString("'" + CString(s).Escape_n(CString::ESQL) + "'")
#define _URL(s) CString(s).Escape_n(CString::EURL)
#define _HTML(s) CString(s).Escape_n(CString::EHTML)
#define _NAMEDFMT(s) CString(s).Escape_n(CString::ENAMEDFMT)
class CString;
class MCString;
@@ -68,7 +69,8 @@ public:
EASCII,
EURL,
EHTML,
ESQL
ESQL,
ENAMEDFMT
} EEscape;
explicit CString(bool b) : string(b ? "true" : "false") {}
@@ -282,6 +284,16 @@ public:
const CString& sLeft = "", const CString& sRight = "", bool bTrimQuotes = true,
bool bTrimWhiteSpace = false) const;
/** Build a string from a format string, replacing values from a map.
* The format specification can contain simple named parameters that match
* keys in the given map. For example in the string "a {b} c", the key "b"
* is looked up in the map, and inserted for "{b}".
* @param sFormat The format specification.
* @param msValues A map of named parameters to their values.
* @return The string with named parameters replaced.
*/
static CString NamedFormat(const CString& sFormat, const MCString& msValues);
/** Produces a random string.
* @param uLength The length of the resulting string.
* @return A random string.
+64
View File
@@ -171,6 +171,8 @@ CString::EEscape CString::ToEscape(const CString& sEsc) {
return EURL;
} else if (sEsc.Equals("SQL")) {
return ESQL;
} else if (sEsc.Equals("NAMEDFMT")) {
return ENAMEDFMT;
}
return EASCII;
@@ -276,6 +278,16 @@ CString CString::Escape_n(EEscape eFrom, EEscape eTo) const {
}
}
break;
case ENAMEDFMT:
if (*p != '\\' || iLength < (a +1)) {
ch = *p;
} else {
a++;
p++;
ch = *p;
}
break;
}
@@ -316,6 +328,13 @@ CString CString::Escape_n(EEscape eFrom, EEscape eTo) const {
} else if (ch == '\\') { sRet += '\\'; sRet += '\\';
} else { sRet += ch; }
break;
case ENAMEDFMT:
if (ch == '\\') { sRet += '\\'; sRet += '\\';
} else if (ch == '{') { sRet += '\\'; sRet += '{';
} else if (ch == '}') { sRet += '\\'; sRet += '}';
} else { sRet += ch; }
break;
}
}
@@ -639,6 +658,51 @@ unsigned int CString::Split(const CString& sDelim, SCString& ssRet, bool bAllowE
return ssRet.size();
}
CString CString::NamedFormat(const CString& sFormat, const MCString& msValues) {
CString sRet;
CString sKey;
bool bEscape = false;
bool bParam = false;
const char* p = sFormat.c_str();
while (*p) {
if (!bParam) {
if (bEscape) {
sRet += *p;
bEscape = false;
} else if (*p == '\\') {
bEscape = true;
} else if (*p == '{') {
bParam = true;
sKey.clear();
} else {
sRet += *p;
}
} else {
if (bEscape) {
sKey += *p;
bEscape = false;
} else if (*p == '\\') {
bEscape = true;
} else if (*p == '}') {
bParam = false;
MCString::const_iterator it = msValues.find(sKey);
if (it != msValues.end()) {
sRet += (*it).second;
}
} else {
sKey += *p;
}
}
p++;
}
return sRet;
}
CString CString::RandomString(unsigned int uLength) {
const char chars[] = "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"