fs/ut/fsStrUt.cpp

Go to the documentation of this file.
00001 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
00002 /*                          _______      ______    ______          __      */
00003 /*  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~    / ____(_)___ / ___ /)  / ____/___  ____/ /__    */
00004 /*      [fsStrUt]         / /_  / / __ \\__ \|/  / /   / __ \/ __  / _ \   */
00005 /*       rev.  7         / __/ / / /_/ /__/ /   / /___/ /_/ / /_/ /  __/   */
00006 /*    10th Jan 2007     /_/   /_/ ,___/____/    \____/\____/\__,_/\___/    */
00007 /*     [x] stable              /_/ (c) 2006-7 Filip STOKLAS (FipS)         */
00008 /*  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~       http://HOLE.4FipS.com/fips_code.php          */
00009 /*                                                                         */
00010 /* This code is free for personal and commercial use. You may redistribute */
00011 /* it by any means. If you use the code for your own projects please give  */
00012 /* me credit. Please send a bug report. Don't alter or remove this header! */
00013 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
00014 #include <fs/ut/fsStrUt.h>
00015 
00016 // >>> COMMON SUPPORT BLOCK (rev. 6)
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 // <<< COMMON SUPPORT BLOCK (rev. 6)
00048 
00049 #include <string>
00050 #include <vector>
00051 #include <map>
00052 #include <algorithm>
00053 
00054 // provide detailed memory tracking information
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 //--- FUNCTIONS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
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 // --- CLASS StrHldr_t >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
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 // WStrHldr_t
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 //--- ANONYMOUS NAMESPACE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00159 //---------------------------------------------------------------------------
00160 namespace {
00161 //---------------------------------------------------------------------------
00162 //--- CLASS ToknzrImpl_t >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
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) // nothing more to parse
00201         return 0;
00202 
00203     // find the beginning of the next token
00204     // (the first non-separator character - text or left quote)
00205     const char *pFrom = m_pszText + m_uOff;
00206     while(pFrom && ::strchr(m_pszSprs, *pFrom)) ++pFrom;
00207         
00208     if(!pFrom) // nothing found, there are only separators in the text
00209     {
00210         m_uOff = m_uLen; // move to the end, stop parsing
00211         return 0;
00212     }
00213     
00214     // find the end of current token
00215     // (right quote, separator or \0)
00216     const char *pTo = 0;
00217     if(pFrom < m_pszText + m_uLen)
00218     {
00219         if(*pFrom != m_chQuote) // normal token, stop at the next separator
00220         {
00221             pTo = pFrom + 1;
00222             while(pTo && !::strchr(m_pszSprs, *pTo)) ++pTo;
00223         }
00224         else // quoted token, stop at the right quote
00225         {
00226             pTo = ::strchr(++pFrom, m_chQuote);
00227         }
00228     }
00229 
00230     if(pTo) // the end of current token found, copy the token
00231     {
00232         const size_t uSize = pTo - pFrom; // doesn't incl. \0
00233         m_Tok.resize(uSize + 1); // incl. \0
00234         ::memcpy(&m_Tok[0], pFrom, uSize); // doesn't incl. \0
00235         m_Tok[uSize] = '\0';
00236         m_uOff = pTo - m_pszText + 1;
00237     }
00238     else // token ending not found, copy the remaining text
00239     {
00240         const size_t uSize = m_uLen - m_uOff + 1; // incl. \0
00241         m_Tok.resize(uSize);
00242         ::memcpy(&m_Tok[0], pFrom, uSize); // incl. \0
00243         m_uOff = m_uLen; // move to the end, stop parsing
00244     }
00245 
00246     FS_ASSERT(!m_Tok.empty());
00247     return &m_Tok[0];
00248 }
00249 //---------------------------------------------------------------------------
00250 } // anonymous namespace
00251 //---------------------------------------------------------------------------
00252 //--- CLASS Toknzr_t >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
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 //--- ANONYMOUS NAMESPACE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00273 //---------------------------------------------------------------------------
00274 namespace {
00275 //---------------------------------------------------------------------------
00276 //--- CLASS CmdLnImpl_t >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
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         // key: check the key format
00343         if(m_Toks[i].size() > 1 && m_Toks[i][0] == '-')
00344         {
00345             strCurKey = m_Toks[i].c_str() + 1;
00346         }
00347         // value: assign the value to the current key
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 } // anonymous namespace
00387 //---------------------------------------------------------------------------
00388 //--- CLASS CmdLn_t >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
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 //---------------------------------------------------------------------------

FipS' Code (Thu Feb 15 22:43:35 2007) - (c) Filip STOKLAS (FipS) - [ www ] [ Guest Book ]