# str.hpp

Go to the documentation of this file.

    00001 /* $Id: str.hpp 10562 2007-07-14 20:30:35Z rubidium $ */
    00002
    00005 #ifndef  STR_HPP
    00006 #define  STR_HPP
    00007
    00008 #include <errno.h>
    00009 #include <stdarg.h>
    00010 #include "strapi.hpp"
    00011
    00013 template <typename Tchar, bool TcaseInsensitive>
    00014 struct CStrT : public CBlobT<Tchar>
    00015 {
    00016   typedef CBlobT<Tchar> base;
    00017   typedef CStrApiT<Tchar, TcaseInsensitive> Api;
    00018   typedef typename base::bsize_t bsize_t;
    00019   typedef typename base::OnTransfer OnTransfer;
    00020
    00022   FORCEINLINE CStrT(const Tchar* str = NULL)
    00023   {
    00024     AppendStr(str);
    00025   }
    00026
    00028   FORCEINLINE CStrT(const Tchar* str, bsize_t num_chars) : base(str, num_chars)
    00029   {
    00030     base::FixTail();
    00031   }
    00032
    00034   FORCEINLINE CStrT(const Tchar* str, const Tchar* end)
    00035     : base(str, end - str)
    00036   {
    00037     base::FixTail();
    00038   }
    00039
    00041   FORCEINLINE CStrT(const CBlobBaseSimple& src)
    00042     : base(src)
    00043   {
    00044     base::FixTail();
    00045   }
    00046
    00048   FORCEINLINE CStrT(const CStrT& src)
    00049     : base(src)
    00050   {
    00051     base::FixTail();
    00052   }
    00053
    00055   FORCEINLINE CStrT(const OnTransfer& ot)
    00056     : base(ot)
    00057   {
    00058   }
    00059
    00061   FORCEINLINE Tchar* GrowSizeNC(bsize_t count)
    00062   {
    00063     Tchar* ret = base::GrowSizeNC(count);
    00064     base::FixTail();
    00065     return ret;
    00066   }
    00067
    00069   FORCEINLINE void AppendStr(const Tchar* str)
    00070   {
    00071     if (str != NULL && str[0] != '\0') {
    00072       base::Append(str, (bsize_t)Api::StrLen(str));
    00073       base::FixTail();
    00074     }
    00075   }
    00076
    00078   FORCEINLINE void Append(const CBlobBaseSimple& src)
    00079   {
    00080     if (src.RawSize() > 0) {
    00081       base::AppendRaw(src);
    00082       base::FixTail();
    00083     }
    00084   }
    00085
    00087   FORCEINLINE CStrT& operator = (const Tchar* src)
    00088   {
    00089     base::Clear();
    00090     AppendStr(src);
    00091     return *this;
    00092   }
    00093
    00095   FORCEINLINE CStrT& operator = (const CBlobBaseSimple& src)
    00096   {
    00097     base::Clear();
    00098     base::AppendRaw(src);
    00099     base::FixTail();
    00100     return *this;
    00101   }
    00102
    00104   FORCEINLINE CStrT& operator = (const CStrT& src)
    00105   {
    00106     base::Clear();
    00107     base::AppendRaw(src);
    00108     base::FixTail();
    00109     return *this;
    00110   }
    00111
    00113   FORCEINLINE bool operator < (const CStrT &other) const
    00114   {
    00115     return (Api::StrCmp(base::Data(), other.Data()) < 0);
    00116   }
    00117
    00119   int AddFormatL(const Tchar *format, va_list args)
    00120   {
    00121     bsize_t addSize = Api::StrLen(format);
    00122     if (addSize < 16) addSize = 16;
    00123     addSize += addSize / 2;
    00124     int ret;
    00125     int err = 0;
    00126     for (;;) {
    00127       Tchar *buf = MakeFreeSpace(addSize);
    00128       ret = Api::SPrintFL(buf, base::GetReserve(), format, args);
    00129       if (ret >= base::GetReserve()) {
    00130         /* Greater return than given count means needed buffer size. */
    00131         addSize = ret + 1;
    00132         continue;
    00133       }
    00134       if (ret >= 0) {
    00135         /* success */
    00136         break;
    00137       }
    00138       err = errno;
    00139       if (err != ERANGE && err != ENOENT && err != 0) {
    00140         /* some strange failure */
    00141         break;
    00142       }
    00143       /* small buffer (M$ implementation) */
    00144       addSize *= 2;
    00145     }
    00146     if (ret > 0) {
    00147       GrowSizeNC(ret);
    00148     } else {
    00149       base::FixTail();
    00150     }
    00151     return ret;
    00152   }
    00153
    00155   int AddFormat(const Tchar *format, ...)
    00156   {
    00157     va_list args;
    00158     va_start(args, format);
    00159     int ret = AddFormatL(format, args);
    00160     va_end(args);
    00161     return ret;
    00162   }
    00163
    00165   int FormatL(const Tchar *format, va_list args)
    00166   {
    00167     base::Free();
    00168     int ret = AddFormatL(format, args);
    00169     return ret;
    00170   }
    00171
    00173   int Format(const Tchar *format, ...)
    00174   {
    00175     base::Free();
    00176     va_list args;
    00177     va_start(args, format);
    00178     int ret = AddFormatL(format, args);
    00179     va_end(args);
    00180     return ret;
    00181   }
    00182 };
    00183
    00184 typedef CStrT<char   , false> CStrA;
    00185 typedef CStrT<char   , true > CStrCiA;
    00186 #if defined(HAS_WCHAR)
    00187 typedef CStrT<wchar_t, false> CStrW;
    00188 typedef CStrT<wchar_t, true > CStrCiW;
    00189 #endif /* HAS_WCHAR */
    00190
    00191 #endif /* STR_HPP */