00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <fs/ut/fsStrUt.h>
00015
00016
00017 #if defined(FS_HAS_FSASSERT)
00018 # include <fs/sys/fsAssert.h>
00019 #else
00020 # include <cassert>
00021 # if !defined(FS_ASSERT)
00022 # define FS_ASSERT(exp) assert(exp)
00023 # endif
00024 # if !defined(FS_ASSERT_MSG)
00025 # define FS_ASSERT_MSG(exp, msg) assert(exp && msg)
00026 # endif
00027 # if !defined(FS_VERIFY)
00028 # define FS_VERIFY(exp) \
00029 { bool bExp = !!(exp); assert(bExp && #exp); bExp; }
00030 # endif
00031 # if !defined(FS_VERIFY_MSG)
00032 # define FS_VERIFY_MSG(exp, msg) \
00033 { bool bExp = !!(exp); assert(bExp && #exp && msg); bExp; }
00034 # endif
00035 # if !defined(FS_STATIC_ASSERT)
00036 # define FS_STATIC_ASSERT(exp) { char error[(exp) ? 1 : 0]; error; }
00037 # endif
00038 #endif
00039 #if !defined(FS_VERIFY_RETURN)
00040 # define FS_VERIFY_RETURN(exp) \
00041 if(!(exp)) { FS_ASSERT_MSG(0, #exp "<return>"); return; }
00042 #endif
00043 #if !defined(FS_VERIFY_RETURN_VAL)
00044 # define FS_VERIFY_RETURN_VAL(exp, ret) \
00045 if(!(exp)) { FS_ASSERT_MSG(0, #exp "<returns:>" #ret); return (ret); }
00046 #endif
00047
00048
00049 #include <string>
00050 #include <vector>
00051 #include <map>
00052 #include <algorithm>
00053
00054
00055 #if defined(FS_HAS_FSMEMMGR)
00056 # include <fs/sys/fsMemMgr.h>
00057 #endif
00058
00059 #if (_MSC_VER >= 1400) // MSVC8
00060 # pragma warning(disable : 4996) // function was marked as deprecated
00061 #endif
00062
00063 using namespace fs::ut::str;
00064
00065
00066
00067 char * fs::ut::str::Int2Str(int nVal, char *pszStr)
00068 {
00069 FS_ASSERT(pszStr);
00070
00071 #if defined(UNDER_CE)
00072 return _itoa(nVal, pszStr, 10);
00073 #else
00074 return ::itoa(nVal, pszStr, 10);
00075 #endif
00076 }
00077
00078 void fs::ut::str::WStr2Str(const wchar_t *pwszWStr, char *pszStr)
00079 {
00080 FS_VERIFY_RETURN(pwszWStr && pszStr);
00081
00082 for(size_t i = 0, n = ::wcslen(pwszWStr) + 1; i < n; ++i)
00083 pszStr[i] = static_cast<char>(pwszWStr[i]);
00084 }
00085
00086 void fs::ut::str::Str2WStr(const char *pszStr, wchar_t *pwszWStr)
00087 {
00088 FS_VERIFY_RETURN(pszStr && pwszWStr);
00089
00090 for(size_t i = 0, n = ::strlen(pszStr) + 1; i < n; ++i)
00091 pwszWStr[i] = pszStr[i];
00092 }
00093
00094
00095
00096 StrHldr_t::StrHldr_t(const char *pszStr):
00097 m_pszStr(0)
00098 {
00099 FS_VERIFY_RETURN(pszStr);
00100
00101 const size_t nSize = ::strlen(pszStr) + 1;
00102 m_pszStr = new char[nSize];
00103 ::strcpy(m_pszStr, pszStr);
00104 }
00105
00106 StrHldr_t::StrHldr_t(const wchar_t *pwszWStr):
00107 m_pszStr(0)
00108 {
00109 FS_VERIFY_RETURN(pwszWStr);
00110
00111 const size_t nSize = ::wcslen(pwszWStr) + 1;
00112 m_pszStr = new char[nSize];
00113 WStr2Str(pwszWStr, m_pszStr);
00114 }
00115
00116 StrHldr_t::~StrHldr_t()
00117 {
00118 delete [] m_pszStr;
00119 }
00120
00121 const char * StrHldr_t::GetStr() const
00122 {
00123 return m_pszStr;
00124 }
00125
00126
00127
00128 WStrHldr_t::WStrHldr_t(wchar_t *pwszWStr):
00129 m_pwszWStr(0)
00130 {
00131 FS_VERIFY_RETURN(pwszWStr);
00132
00133 const size_t nSize = ::wcslen(pwszWStr) + 1;
00134 m_pwszWStr = new wchar_t[nSize];
00135 ::wcscpy(m_pwszWStr, pwszWStr);
00136 }
00137
00138 WStrHldr_t::WStrHldr_t(const char *pszStr):
00139 m_pwszWStr(0)
00140 {
00141 FS_VERIFY_RETURN(pszStr);
00142
00143 const size_t nSize = ::strlen(pszStr) + 1;
00144 m_pwszWStr = new wchar_t[nSize];
00145 Str2WStr(pszStr, m_pwszWStr);
00146 }
00147
00148 WStrHldr_t::~WStrHldr_t()
00149 {
00150 delete [] m_pwszWStr;
00151 }
00152
00153 const wchar_t * WStrHldr_t::GetWStr() const
00154 {
00155 return m_pwszWStr;
00156 }
00157
00158
00159
00160 namespace {
00161
00162
00163
00164 class ToknzrImpl_t
00165 {
00166 public:
00167
00168 ToknzrImpl_t(const char *pszText, const char *pszSprs, char chQuote);
00169 const char * Next();
00170
00171 private:
00172
00173 ToknzrImpl_t();
00174 ToknzrImpl_t(const ToknzrImpl_t &);
00175 ToknzrImpl_t & operator = (const ToknzrImpl_t &);
00176
00177
00178
00179 const char *m_pszText;
00180 const char *m_pszSprs;
00181 const char m_chQuote;
00182 const size_t m_uLen;
00183 size_t m_uOff;
00184 std::vector<char> m_Tok;
00185 };
00186
00187 ToknzrImpl_t::ToknzrImpl_t(const char *pszText, const char *pszSprs,
00188 char chQuote):
00189 m_pszText(pszText),
00190 m_pszSprs(pszSprs),
00191 m_chQuote(chQuote),
00192 m_uLen(pszText ? ::strlen(pszText) : 0),
00193 m_uOff(0)
00194 {
00195 FS_VERIFY_RETURN(pszText && pszSprs);
00196 }
00197
00198 const char * ToknzrImpl_t::Next()
00199 {
00200 if(m_uOff >= m_uLen)
00201 return 0;
00202
00203
00204
00205 const char *pFrom = m_pszText + m_uOff;
00206 while(pFrom && ::strchr(m_pszSprs, *pFrom)) ++pFrom;
00207
00208 if(!pFrom)
00209 {
00210 m_uOff = m_uLen;
00211 return 0;
00212 }
00213
00214
00215
00216 const char *pTo = 0;
00217 if(pFrom < m_pszText + m_uLen)
00218 {
00219 if(*pFrom != m_chQuote)
00220 {
00221 pTo = pFrom + 1;
00222 while(pTo && !::strchr(m_pszSprs, *pTo)) ++pTo;
00223 }
00224 else
00225 {
00226 pTo = ::strchr(++pFrom, m_chQuote);
00227 }
00228 }
00229
00230 if(pTo)
00231 {
00232 const size_t uSize = pTo - pFrom;
00233 m_Tok.resize(uSize + 1);
00234 ::memcpy(&m_Tok[0], pFrom, uSize);
00235 m_Tok[uSize] = '\0';
00236 m_uOff = pTo - m_pszText + 1;
00237 }
00238 else
00239 {
00240 const size_t uSize = m_uLen - m_uOff + 1;
00241 m_Tok.resize(uSize);
00242 ::memcpy(&m_Tok[0], pFrom, uSize);
00243 m_uOff = m_uLen;
00244 }
00245
00246 FS_ASSERT(!m_Tok.empty());
00247 return &m_Tok[0];
00248 }
00249
00250 }
00251
00252
00253
00254 Toknzr_t::Toknzr_t(const char *pszText, const char *pszSprs, char chQuote):
00255 m_pImpl(new ToknzrImpl_t(pszText, pszSprs, chQuote))
00256 {
00257 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00258 }
00259
00260 Toknzr_t::~Toknzr_t()
00261 {
00262 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00263 delete static_cast<ToknzrImpl_t *>(m_pImpl);
00264 }
00265
00266 const char * Toknzr_t::Next()
00267 {
00268 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00269 return static_cast<ToknzrImpl_t *>(m_pImpl)->Next();
00270 }
00271
00272
00273
00274 namespace {
00275
00276
00277
00278 class CmdLnImpl_t
00279 {
00280 public:
00281
00282 explicit CmdLnImpl_t(const char *pszCmdLn);
00283 CmdLnImpl_t(int argc, char *argv[]);
00284 const char * GetVal(const char *pszKey) const;
00285 int GetNumToks() const;
00286 const char * GetTok(int nIdx) const;
00287 int FindTok(const char *pszTok) const;
00288
00289 private:
00290
00291 CmdLnImpl_t();
00292 CmdLnImpl_t(const CmdLnImpl_t &);
00293 CmdLnImpl_t & operator = (const CmdLnImpl_t &);
00294
00296 void MapValsKeys();
00297
00298
00299
00300 typedef std::vector<std::string> TToks;
00301 TToks m_Toks;
00302
00303 typedef std::pair<std::string, int> TKey2ValPair;
00304 typedef std::map<std::string, int> TKey2ValMap;
00305 TKey2ValMap m_Key2ValMap;
00306 };
00307
00309 CmdLnImpl_t::CmdLnImpl_t(const char *pszCmdLn)
00310 {
00311 FS_VERIFY_RETURN(pszCmdLn);
00312
00313 Toknzr_t Toknzr(pszCmdLn, " ");
00314 for(const char *pszTok = Toknzr.Next(); pszTok; pszTok = Toknzr.Next())
00315 {
00316 FS_ASSERT(pszTok);
00317 m_Toks.push_back(pszTok);
00318 }
00319
00320 MapValsKeys();
00321 }
00322
00323 CmdLnImpl_t::CmdLnImpl_t(int argc, char *argv[])
00324 {
00325 FS_VERIFY_RETURN(argc > 0 && argv);
00326
00327 for(int i = 0; i < argc; ++i)
00328 {
00329 FS_ASSERT(argv[i]);
00330 m_Toks.push_back(argv[i]);
00331 }
00332
00333 MapValsKeys();
00334 }
00335
00336 void CmdLnImpl_t::MapValsKeys()
00337 {
00338 std::string strCurKey;
00339
00340 for(int i = 0, n = static_cast<int>(m_Toks.size()); i < n; ++i)
00341 {
00342
00343 if(m_Toks[i].size() > 1 && m_Toks[i][0] == '-')
00344 {
00345 strCurKey = m_Toks[i].c_str() + 1;
00346 }
00347
00348 else if(!strCurKey.empty())
00349 {
00350 m_Key2ValMap.insert(TKey2ValPair(strCurKey, i));
00351 strCurKey.clear();
00352 }
00353 }
00354 }
00355
00356 const char * CmdLnImpl_t::GetVal(const char *pszKey) const
00357 {
00358 FS_VERIFY_RETURN_VAL(pszKey, 0);
00359
00360 const TKey2ValMap::const_iterator it = m_Key2ValMap.find(pszKey);
00361 return it != m_Key2ValMap.end() ? m_Toks[(*it).second].c_str() : 0;
00362 }
00363
00364 int CmdLnImpl_t::GetNumToks() const
00365 {
00366 return static_cast<int>(m_Toks.size());
00367 }
00368
00369 const char * CmdLnImpl_t::GetTok(int nIdx) const
00370 {
00371 FS_VERIFY_RETURN_VAL(nIdx >= 0 && nIdx < GetNumToks(), 0);
00372
00373 return m_Toks[nIdx].c_str();
00374 }
00375
00376 int CmdLnImpl_t::FindTok(const char *pszTok) const
00377 {
00378 FS_VERIFY_RETURN_VAL(pszTok, -1);
00379
00380 const TToks::const_iterator it =
00381 std::find(m_Toks.begin(), m_Toks.end(), pszTok);
00382
00383 return it != m_Toks.end() ? static_cast<int>(it - m_Toks.begin()) : -1;
00384 }
00385
00386 }
00387
00388
00389
00390 CmdLn_t::CmdLn_t(const char *pszCmdLn):
00391 m_pImpl(new CmdLnImpl_t(pszCmdLn))
00392 {
00393 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00394 }
00395
00396 CmdLn_t::CmdLn_t(int argc, char *argv[]):
00397 m_pImpl(new CmdLnImpl_t(argc, argv))
00398 {
00399 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00400 }
00401
00402 CmdLn_t::~CmdLn_t()
00403 {
00404 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00405 delete static_cast<CmdLnImpl_t *>(m_pImpl);
00406 }
00407
00408 const char * CmdLn_t::GetVal(const char *pszKey) const
00409 {
00410 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00411 return static_cast<CmdLnImpl_t *>(m_pImpl)->GetVal(pszKey);
00412 }
00413
00414 int CmdLn_t::GetNumToks() const
00415 {
00416 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00417 return static_cast<CmdLnImpl_t *>(m_pImpl)->GetNumToks();
00418 }
00419
00420 const char * CmdLn_t::GetTok(int nIdx) const
00421 {
00422 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00423 return static_cast<CmdLnImpl_t *>(m_pImpl)->GetTok(nIdx);
00424 }
00425
00426 int CmdLn_t::FindTok(const char *pszTok) const
00427 {
00428 FS_ASSERT_MSG(m_pImpl, "Invalid implementation pointer!");
00429 return static_cast<CmdLnImpl_t *>(m_pImpl)->FindTok(pszTok);
00430 }
00431