diff --git a/stepmania/src/RageUtil.cpp b/stepmania/src/RageUtil.cpp index 1820d1ca44..5c6c317b65 100644 --- a/stepmania/src/RageUtil.cpp +++ b/stepmania/src/RageUtil.cpp @@ -20,6 +20,7 @@ #include #include #include "regex.h" +#include unsigned long randseed = time(NULL); @@ -962,3 +963,67 @@ CString LcharToUTF8( longchar c ) int cnt = unichar_to_utf8(c, buf); return CString(buf, cnt); } + + +/* Replace &#nnnn; (decimal) &xnnnn; (hex) with corresponding UTF-8 characters. */ +void Replace_Unicode_Markers( CString &Text ) +{ + unsigned start = 0; + while(start < Text.size()) + { + /* Look for &#digits; */ + bool hex = false; + unsigned pos = Text.find("&#", start); + if(pos == Text.npos) { + hex = true; + pos = Text.find("&x", start); + } + + if(pos == Text.npos) break; + start = pos+1; + + unsigned p = pos; + p += 2; + + /* Found &# or &x. Is it followed by digits and a semicolon? */ + if(p >= Text.size()) continue; + + int numdigits = 0; + while(p < Text.size() && + (hex && isxdigit(Text[p])) || (!hex && isdigit(Text[p]))) + { + p++; + numdigits++; + } + if(!numdigits) continue; /* must have at least one digit */ + if(p >= Text.size() || Text[p] != ';') continue; + p++; + + int num; + if(hex) sscanf(Text.c_str()+pos, "&x%x;", &num); + else sscanf(Text.c_str()+pos, "&#%i;", &num); + + Text.replace(pos, p-pos, LcharToUTF8(num)); + } +} + +void ReplaceText( CString &Text, const map &m ) +{ + for(map::const_iterator it = m.begin(); it != m.end(); ++it) + { + unsigned start = 0; + while(1) + { + /* This is stupidly inefficient. If it becomes a bottleneck, write + * a case-insensitive char_traits and just do the copy twice. */ + CString txt = Text; + txt.MakeUpper(); + + unsigned pos = txt.find(it->first, start); + if(pos == txt.npos) + break; + Text.replace(pos, it->first.size(), it->second); + start = pos+it->second.size(); + } + } +} diff --git a/stepmania/src/RageUtil.h b/stepmania/src/RageUtil.h index 6189a262fb..4f80238b4c 100644 --- a/stepmania/src/RageUtil.h +++ b/stepmania/src/RageUtil.h @@ -12,6 +12,7 @@ ----------------------------------------------------------------------------- */ +#include //----------------------------------------------------------------------------- // SAFE_ Macros @@ -205,6 +206,9 @@ bool regex(CString str, CString pattern, vector &matches); bool regex(CString str, CString pattern); void regex_flags(int flags); +void Replace_Unicode_Markers( CString &Text ); +void ReplaceText( CString &Text, const map &m ); + #ifndef WIN32 #include /* correct place with correct definitions */ #endif