diff --git a/base/stringutil.cpp b/base/stringutil.cpp index 2dc4ccea9b..fa5f4a4c07 100644 --- a/base/stringutil.cpp +++ b/base/stringutil.cpp @@ -211,3 +211,14 @@ void SplitString(const std::string& str, const char delim, std::vector& output); +std::string ReplaceAll(std::string input, const std::string& src, const std::string& dest); template static std::string ValueToString(const N value) diff --git a/file/file_util.cpp b/file/file_util.cpp index 30666c86fd..52c2d0ae88 100644 --- a/file/file_util.cpp +++ b/file/file_util.cpp @@ -342,6 +342,14 @@ std::string getDir(const std::string &path) return cutpath; } +std::string getFilename(std::string path) { + size_t off = getDir(path).size() + 1; + if (off < path.size()) + return path.substr(off); + else + return path; +} + void mkDir(const std::string &path) { #ifdef _WIN32 diff --git a/file/file_util.h b/file/file_util.h index 867f1a9d3a..ed69d8cd86 100644 --- a/file/file_util.h +++ b/file/file_util.h @@ -34,6 +34,8 @@ struct FileInfo }; std::string getFileExtension(const std::string &fn); +std::string getDir(const std::string &path); +std::string getFilename(std::string path); bool getFileInfo(const char *path, FileInfo *fileInfo); size_t getFilesInDir(const char *directory, std::vector *files, const char *filter = 0); void deleteFile(const char *file); diff --git a/i18n/i18n.cpp b/i18n/i18n.cpp index 883fd58688..43a3db5626 100644 --- a/i18n/i18n.cpp +++ b/i18n/i18n.cpp @@ -31,7 +31,8 @@ const char *I18NCategory::T(const char *key, const char *def) { void I18NCategory::SetMap(const std::map &m) { for (auto iter = m.begin(); iter != m.end(); ++iter) { if (map_.find(iter->first) == map_.end()) { - map_[iter->first] = I18NEntry(iter->second); + std::string text = ReplaceAll(iter->second, "\\n", "\n"); + map_[iter->first] = I18NEntry(text); } } } diff --git a/net/url.cpp b/net/url.cpp index 7b788260ee..4b1c068f57 100644 --- a/net/url.cpp +++ b/net/url.cpp @@ -19,4 +19,129 @@ void Url::Split() { resource_ = url_.substr(sep); // include the slash! valid_ = protocol_.size() > 1 && host_.size() > 1; -} \ No newline at end of file +} + +// UriDecode and UriEncode are from http://www.codeguru.com/cpp/cpp/string/conversions/print.php/c12759 +// by jinq0123 (November 2, 2006) + +// Uri encode and decode. +// RFC1630, RFC1738, RFC2396 + +// Some compilers don't like to assume (int)-1 will safely cast to (char)-1 as +// the MSBs aren't 0's. Workaround the issue while maintaining table spacing. +#define N1 (char)-1 +const char HEX2DEC[256] = +{ + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 1 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 2 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,N1,N1, N1,N1,N1,N1, + + /* 4 */ N1,10,11,12, 13,14,15,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 5 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 6 */ N1,10,11,12, 13,14,15,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 7 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + + /* 8 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* 9 */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* A */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* B */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + + /* C */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* D */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* E */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, + /* F */ N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1, N1,N1,N1,N1 +}; + +std::string UriDecode(const std::string & sSrc) +{ + // Note from RFC1630: "Sequences which start with a percent sign + // but are not followed by two hexadecimal characters (0-9, A-F) are reserved + // for future extension" + + const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); + const size_t SRC_LEN = sSrc.length(); + const unsigned char * const SRC_END = pSrc + SRC_LEN; + const unsigned char * const SRC_LAST_DEC = SRC_END - 2; // last decodable '%' + + char * const pStart = new char[SRC_LEN]; + char * pEnd = pStart; + + while (pSrc < SRC_LAST_DEC) + { + if (*pSrc == '%') + { + char dec1, dec2; + if (-1 != (dec1 = HEX2DEC[*(pSrc + 1)]) + && -1 != (dec2 = HEX2DEC[*(pSrc + 2)])) + { + *pEnd++ = (dec1 << 4) + dec2; + pSrc += 3; + continue; + } + } + + *pEnd++ = *pSrc++; + } + + // the last 2- chars + while (pSrc < SRC_END) + *pEnd++ = *pSrc++; + + std::string sResult(pStart, pEnd); + delete [] pStart; + return sResult; +} + +// Only alphanum is safe. +const char SAFE[256] = +{ + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, + + /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, + /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, + /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, + /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, + + /* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + + /* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + /* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 +}; + +std::string UriEncode(const std::string & sSrc) +{ + const char DEC2HEX[16 + 1] = "0123456789ABCDEF"; + const unsigned char * pSrc = (const unsigned char *)sSrc.c_str(); + const size_t SRC_LEN = sSrc.length(); + unsigned char * const pStart = new unsigned char[SRC_LEN * 3]; + unsigned char * pEnd = pStart; + const unsigned char * const SRC_END = pSrc + SRC_LEN; + + for (; pSrc < SRC_END; ++pSrc) + { + if (SAFE[*pSrc]) + *pEnd++ = *pSrc; + else + { + // escape this char + *pEnd++ = '%'; + *pEnd++ = DEC2HEX[*pSrc >> 4]; + *pEnd++ = DEC2HEX[*pSrc & 0x0F]; + } + } + + std::string sResult((char *)pStart, (char *)pEnd); + delete [] pStart; + return sResult; +} diff --git a/net/url.h b/net/url.h index 2358dfb446..a5c3b51c35 100644 --- a/net/url.h +++ b/net/url.h @@ -123,4 +123,8 @@ private: std::string host_; std::string resource_; std::string protocol_; -}; \ No newline at end of file +}; + + +std::string UriDecode(const std::string & sSrc); +std::string UriEncode(const std::string & sSrc);