rtoss - Diff between revs 181 and 182

Subversion Repositories:
Rev:
Show entire file - Ignore whitespace
Rev 181 Rev 182
Line 320... Line 320...
320 //      Please don't blame me if it causes your $30 billion dollar satellite 320 //      Please don't blame me if it causes your $30 billion dollar satellite
321 //      explode in orbit.  If you redistribute it in any form, I'd appreciate it 321 //      explode in orbit.  If you redistribute it in any form, I'd appreciate it
322 //      if you would leave this notice here. 322 //      if you would leave this notice here.
323 // ============================================================================= 323 // =============================================================================
324 324
325 // Avoid multiple inclusion the VC++ way, -  
326 // Turn off browser references -  
-   325 // Avoid multiple inclusion
-   326
-   327 #ifndef STDSTRING_H
-   328 #define STDSTRING_H
-   329
-   330 // When using VC, turn off browser references
327 // Turn off unavoidable compiler warnings 331 // Turn off unavoidable compiler warnings
328 332
329 #if defined(_MSC_VER) && (_MSC_VER > 1100) 333 #if defined(_MSC_VER) && (_MSC_VER > 1100)
330         #pragma once -  
331         #pragma component(browser, off, references, "CStdString") 334         #pragma component(browser, off, references, "CStdString")
332         #pragma warning (disable : 4290) // C++ Exception Specification ignored 335         #pragma warning (disable : 4290) // C++ Exception Specification ignored
333         #pragma warning (disable : 4127) // Conditional expression is constant 336         #pragma warning (disable : 4127) // Conditional expression is constant
334         #pragma warning (disable : 4097) // typedef name used as synonym for class name 337         #pragma warning (disable : 4097) // typedef name used as synonym for class name
335 #endif 338 #endif
Line 338... Line 341...
338 341
339 #ifdef __BORLANDC__ 342 #ifdef __BORLANDC__
340     #pragma option push -w-inl 343     #pragma option push -w-inl
341 //      #pragma warn -inl   // Turn off inline function warnings 344 //      #pragma warn -inl   // Turn off inline function warnings
342 #endif 345 #endif
343 -  
344 #ifndef STDSTRING_H -  
345 #define STDSTRING_H -  
346 346
347 // SS_IS_INTRESOURCE 347 // SS_IS_INTRESOURCE
348 // ----------------- 348 // -----------------
349 //              A copy of IS_INTRESOURCE from VC7.  Because old VC6 version of winuser.h 349 //              A copy of IS_INTRESOURCE from VC7.  Because old VC6 version of winuser.h
350 //              doesn't have this. 350 //              doesn't have this.
Line 486... Line 486...
486 //              is not defined as appropriate and you control this feature. 486 //              is not defined as appropriate and you control this feature.
487 487
488 #if defined(_MSC_VER) && !defined(SS_ANSI) 488 #if defined(_MSC_VER) && !defined(SS_ANSI)
489         #define SS_ALLOCA 489         #define SS_ALLOCA
490 #endif 490 #endif
-   491
491 492
492 // MACRO: SS_MBCS 493 // MACRO: SS_MBCS
493 // -------------- 494 // --------------
494 //              Setting this macro means you are using MBCS characters.  In MSVC -  
495 //              builds, this macro gets set automatically by detection of the -  
496 //              preprocessor flag _MBCS.  For other platforms you may set it manually -  
497 //              if you wish.  The only effect it currently has is to cause the -  
498 //              allocation of more space for wchar_t --> char conversions. -  
-   495 //              Setting this macro means you are using MBCS characters.  In MSVC builds,
-   496 //              this macro gets set automatically by detection of the preprocessor flag
-   497 //              _MBCS.  For other platforms you may set it manually if you wish.  The
-   498 //              only effect it currently has is to cause the allocation of more space
-   499 //              for wchar_t --> char conversions.
499 //              Note that MBCS does not mean UNICODE. 500 //              Note that MBCS does not mean UNICODE.
500 // 501 //
501 //      #define SS_MBCS 502 //      #define SS_MBCS
502 // 503 //
-   504
503 #ifdef _MBCS 505 #ifdef _MBCS
504         #define SS_MBCS 506         #define SS_MBCS
505 #endif 507 #endif
506 508
-   509
-   510 // MACRO SS_NO_LOCALE
-   511 // ------------------
-   512 // If your implementation of the Standard C++ Library lacks the <locale> header,
-   513 // you can #define this macro to make your code build properly.  Note that this
-   514 // is some of my newest code and frankly I'm not very sure of it, though it does
-   515 // pass my unit tests.
-   516
-   517 // #define SS_NO_LOCALE
507 518
508 519
509 // Compiler Error regarding _UNICODE and UNICODE 520 // Compiler Error regarding _UNICODE and UNICODE
510 // ----------------------------------------------- 521 // -----------------------------------------------
511 // Microsoft header files are screwy.  Sometimes they depend on a preprocessor 522 // Microsoft header files are screwy.  Sometimes they depend on a preprocessor
Line 644... Line 655...
644 // Standard headers needed 655 // Standard headers needed
645 656
646 #include <string>                       // basic_string 657 #include <string>                       // basic_string
647 #include <algorithm>            // for_each, etc. 658 #include <algorithm>            // for_each, etc.
648 #include <functional>           // for StdStringLessNoCase, et al 659 #include <functional>           // for StdStringLessNoCase, et al
649 #include <locale>                       // for various facets -  
-   660 #ifndef SS_NO_LOCALE
-   661         #include <locale>                       // for various facets
-   662 #endif
650 663
651 // If this is a recent enough version of VC include comdef.h, so we can write 664 // If this is a recent enough version of VC include comdef.h, so we can write
652 // member functions to deal with COM types & compiler support classes e.g. 665 // member functions to deal with COM types & compiler support classes e.g.
653 // _bstr_t 666 // _bstr_t
654 667
Line 776... Line 789...
776 #include <stdlib.h> 789 #include <stdlib.h>
777 #ifndef va_start 790 #ifndef va_start
778         #include <varargs.h> 791         #include <varargs.h>
779 #endif 792 #endif
780 793
781 // StdCodeCvt - made to look like Win32 functions WideCharToMultiByte -  
782 //                              and MultiByteToWideChar but uses locales in SS_ANSI -  
783 //                              builds.  There are a number of overloads. -  
784 //              First argument is the destination buffer. -  
785 //              Second argument is the source buffer -  
786 //#if defined (SS_ANSI) || !defined (SS_WIN32) -  
787 794
788 // 'SSCodeCvt' - shorthand name for the codecvt facet we use -  
-   795 #ifdef SS_NO_LOCALE
789 796
790 typedef std::codecvt<wchar_t, char, mbstate_t> SSCodeCvt; -  
-   797         #if defined(_WIN32) || defined (_WIN32_WCE)
791 798
792 inline PWSTR StdCodeCvt(PWSTR pDstW, int nDst, PCSTR pSrcA, int nSrc, -  
793     const std::locale& loc=std::locale()) -  
794 { -  
795     ASSERT(0 != pSrcA); -  
796     ASSERT(0 != pDstW); -  
-   799                 inline PWSTR StdCodeCvt(PWSTR pDstW, int nDst, PCSTR pSrcA, int nSrc,
-   800                         UINT acp=CP_ACP)
-   801                 {
-   802                         ASSERT(0 != pSrcA);
-   803                         ASSERT(0 != pDstW);
-   804                         pDstW[0] = '\0';
-   805                         MultiByteToWideChar(acp, 0, pSrcA, nSrc, pDstW, nDst);
-   806                         return pDstW;
-   807                 }
-   808                 inline PWSTR StdCodeCvt(PWSTR pDstW, int nDst, PCUSTR pSrcA, int nSrc,
-   809                         UINT acp=CP_ACP)
-   810                 {
-   811                         return StdCodeCvt(pDstW, nDst, (PCSTR)pSrcA, nSrc, acp);
-   812                 }
797 813
798         pDstW[0]                                        = '\0'; -  
-   814                 inline PSTR StdCodeCvt(PSTR pDstA, int nDst, PCWSTR pSrcW, int nSrc,
-   815                         UINT acp=CP_ACP)
-   816                 {
-   817                         ASSERT(0 != pDstA);
-   818                         ASSERT(0 != pSrcW);
-   819                         pDstA[0] = '\0';
-   820                         WideCharToMultiByte(acp, 0, pSrcW, nSrc, pDstA, nDst, 0, 0);
-   821                         return pDstA;
-   822                 }
-   823                 inline PUSTR StdCodeCvt(PUSTR pDstA, int nDst, PCWSTR pSrcW, int nSrc,
-   824                         UINT acp=CP_ACP)
-   825                 {
-   826                         return (PUSTR)StdCodeCvt((PSTR)pDstA, nDst, pSrcW, nSrc, acp);
-   827                 }
-   828         #else
-   829         #endif
799 830
800         if ( nSrc > 0 ) -  
801         { -  
802                 PCSTR pNextSrcA                 = pSrcA; -  
803                 PWSTR pNextDstW                 = pDstW; -  
804                 SSCodeCvt::result res   = SSCodeCvt::ok; -  
805                 const SSCodeCvt& conv   = SS_USE_FACET(loc, SSCodeCvt); -  
806                 SSCodeCvt::state_type st= { 0 }; -  
807                 res                                             = conv.in(st, -  
808                                                                         pSrcA, pSrcA + nSrc, pNextSrcA, -  
809                                                                         pDstW, pDstW + nDst, pNextDstW); -  
-   831 #else
810 832
811                 ASSERT(SSCodeCvt::ok == res); -  
812                 ASSERT(SSCodeCvt::error != res); -  
813                 ASSERT(pNextDstW >= pDstW); -  
814                 ASSERT(pNextSrcA >= pSrcA); -  
-   833         // StdCodeCvt - made to look like Win32 functions WideCharToMultiByte
-   834         //                              and MultiByteToWideChar but uses locales in SS_ANSI
-   835         //                              builds.  There are a number of overloads.
-   836         //              First argument is the destination buffer.
-   837         //              Second argument is the source buffer
-   838         //#if defined (SS_ANSI) || !defined (SS_WIN32)
815 839
816                 // Null terminate the converted string -  
-   840         // 'SSCodeCvt' - shorthand name for the codecvt facet we use
817 841
818                 if ( pNextDstW - pDstW > nDst ) -  
819                         *(pDstW + nDst) = '\0'; -  
820                 else -  
821                         *pNextDstW = '\0'; -  
822         } -  
823     return pDstW; -  
824 } -  
825 inline PWSTR StdCodeCvt(PWSTR pDstW, int nDst, PCUSTR pSrcA, int nSrc, -  
826     const std::locale& loc=std::locale()) -  
827 { -  
828     return StdCodeCvt(pDstW, nDst, (PCSTR)pSrcA, nSrc, loc); -  
829 } -  
-   842         typedef std::codecvt<wchar_t, char, mbstate_t> SSCodeCvt;
830 843
831 inline PSTR StdCodeCvt(PSTR pDstA, int nDst, PCWSTR pSrcW, int nSrc, -  
832     const std::locale& loc=std::locale()) -  
833 { -  
834     ASSERT(0 != pDstA); -  
835     ASSERT(0 != pSrcW); -  
-   844         inline PWSTR StdCodeCvt(PWSTR pDstW, int nDst, PCSTR pSrcA, int nSrc,
-   845                 const std::locale& loc=std::locale())
-   846         {
-   847                 ASSERT(0 != pSrcA);
-   848                 ASSERT(0 != pDstW);
836 849
837         pDstA[0]                                        = '\0'; -  
-   850                 pDstW[0]                                        = '\0';
838 851
839         if ( nSrc > 0 ) -  
840         { -  
841                 PSTR pNextDstA                  = pDstA; -  
842                 PCWSTR pNextSrcW                = pSrcW; -  
843                 SSCodeCvt::result res   = SSCodeCvt::ok; -  
844                 const SSCodeCvt& conv   = SS_USE_FACET(loc, SSCodeCvt); -  
845                 SSCodeCvt::state_type st= { 0 }; -  
846                 res                                             = conv.out(st, -  
847                                                                         pSrcW, pSrcW + nSrc, pNextSrcW, -  
848                                                                         pDstA, pDstA + nDst, pNextDstA); -  
-   852                 if ( nSrc > 0 )
-   853                 {
-   854                         PCSTR pNextSrcA                 = pSrcA;
-   855                         PWSTR pNextDstW                 = pDstW;
-   856                         SSCodeCvt::result res   = SSCodeCvt::ok;
-   857                         const SSCodeCvt& conv   = SS_USE_FACET(loc, SSCodeCvt);
-   858                         SSCodeCvt::state_type st= { 0 };
-   859                         res                                             = conv.in(st,
-   860                                                                                 pSrcA, pSrcA + nSrc, pNextSrcA,
-   861                                                                                 pDstW, pDstW + nDst, pNextDstW);
849 862
850                 ASSERT(SSCodeCvt::error != res); -  
851                 ASSERT(SSCodeCvt::ok == res);   // strict, comment out for sanity -  
852                 ASSERT(pNextDstA >= pDstA); -  
853                 ASSERT(pNextSrcW >= pSrcW); -  
-   863                         ASSERT(SSCodeCvt::ok == res);
-   864                         ASSERT(SSCodeCvt::error != res);
-   865                         ASSERT(pNextDstW >= pDstW);
-   866                         ASSERT(pNextSrcA >= pSrcA);
854 867
855                 // Null terminate the converted string -  
-   868                         // Null terminate the converted string
856 869
857                 if ( pNextDstA - pDstA > nDst ) -  
858                         *(pDstA + nDst) = '\0'; -  
859                 else -  
860                         *pNextDstA = '\0'; -  
-   870                         if ( pNextDstW - pDstW > nDst )
-   871                                 *(pDstW + nDst) = '\0';
-   872                         else
-   873                                 *pNextDstW = '\0';
-   874                 }
-   875                 return pDstW;
861         } 876         }
862     return pDstA; -  
863 } -  
864 inline PUSTR StdCodeCvt(PUSTR pDstA, int nDst, PCWSTR pSrcW, int nSrc, -  
865     const std::locale& loc=std::locale()) -  
866 { -  
867     return (PUSTR)StdCodeCvt((PSTR)pDstA, nDst, pSrcW, nSrc, loc); -  
868 } -  
869 /* -  
870 #else   // ...or are we doing things assuming win32 and Visual C++? -  
871 -  
872         inline PWSTR StdCodeCvt(PWSTR pDstW, int nDst, PCSTR pSrcA, int nSrc, UINT acp=CP_ACP) -  
-   877         inline PWSTR StdCodeCvt(PWSTR pDstW, int nDst, PCUSTR pSrcA, int nSrc,
-   878                 const std::locale& loc=std::locale())
873         { 879         {
874                 ASSERT(0 != pSrcA); -  
875                 ASSERT(0 != pDstW); -  
876                 pW[0] = '\0'; -  
877                 MultiByteToWideChar(acp, 0, pSrcA, nSrc, pDstW, nDst); -  
878                 return pW; -  
879         } -  
880         inline PWSTR StdCodeCvt(PWSTR pDstW, nDst, PCUSTR pSrcA, int nSrc, UINT acp=CP_ACP) -  
881         { -  
882                 return StdCodeCvt(pDstW, nDst, (PCSTR)pSrcA, nSrc, acp); -  
-   880                 return StdCodeCvt(pDstW, nDst, (PCSTR)pSrcA, nSrc, loc);
883         } 881         }
884 882
885         inline PSTR StdCodeCvt(PSTR pDstA, nDst PCWSTR pSrcW, int nSrc, UINT acp=CP_ACP) -  
-   883         inline PSTR StdCodeCvt(PSTR pDstA, int nDst, PCWSTR pSrcW, int nSrc,
-   884                 const std::locale& loc=std::locale())
886         { 885         {
887                 ASSERT(0 != pDstA); 886                 ASSERT(0 != pDstA);
888                 ASSERT(0 != pSrcW); 887                 ASSERT(0 != pSrcW);
889                 pA[0] = '\0'; -  
890                 WideCharToMultiByte(acp, 0, pSrcW, nSrc, pDstA, nDst, 0, 0); -  
891                 return pA; -  
-   888
-   889                 pDstA[0]                                        = '\0';
-   890
-   891                 if ( nSrc > 0 )
-   892                 {
-   893                         PSTR pNextDstA                  = pDstA;
-   894                         PCWSTR pNextSrcW                = pSrcW;
-   895                         SSCodeCvt::result res   = SSCodeCvt::ok;
-   896                         const SSCodeCvt& conv   = SS_USE_FACET(loc, SSCodeCvt);
-   897                         SSCodeCvt::state_type st= { 0 };
-   898                         res                                             = conv.out(st,
-   899                                                                                 pSrcW, pSrcW + nSrc, pNextSrcW,
-   900                                                                                 pDstA, pDstA + nDst, pNextDstA);
-   901
-   902                         ASSERT(SSCodeCvt::error != res);
-   903                         ASSERT(SSCodeCvt::ok == res);   // strict, comment out for sanity
-   904                         ASSERT(pNextDstA >= pDstA);
-   905                         ASSERT(pNextSrcW >= pSrcW);
-   906
-   907                         // Null terminate the converted string
-   908
-   909                         if ( pNextDstA - pDstA > nDst )
-   910                                 *(pDstA + nDst) = '\0';
-   911                         else
-   912                                 *pNextDstA = '\0';
-   913                 }
-   914                 return pDstA;
892         } 915         }
893         inline PUSTR StdCodeCvt(PUSTR pDstA, nDst, PCWSTR pSrcW, int nSrc, UINT acp=CP_ACP) -  
-   916
-   917         inline PUSTR StdCodeCvt(PUSTR pDstA, int nDst, PCWSTR pSrcW, int nSrc,
-   918                 const std::locale& loc=std::locale())
894         { 919         {
895                 return (PUSTR)StdCodeCvt((PSTR)pDstA, nDst, pSrcW, nSrc, acp); -  
-   920                 return (PUSTR)StdCodeCvt((PSTR)pDstA, nDst, pSrcW, nSrc, loc);
896         } 921         }
897 922
898 #endif 923 #endif
899 */ -  
-   924
-   925
900 926
901 // Unicode/MBCS conversion macros are only available on implementations of 927 // Unicode/MBCS conversion macros are only available on implementations of
902 // the "C" library that have the non-standard _alloca function.  As far as I 928 // the "C" library that have the non-standard _alloca function.  As far as I
903 // know that's only Microsoft's though I've heard that the function exists 929 // know that's only Microsoft's though I've heard that the function exists
904 // elsewhere.   930 // elsewhere.  
Line 1143... Line 1169...
1143 // 1169 //
1144 // Without these functions, the CStdStr<> template would probably have to broken 1170 // Without these functions, the CStdStr<> template would probably have to broken
1145 // out into two, almost identical classes.  Either that or it would be a huge, 1171 // out into two, almost identical classes.  Either that or it would be a huge,
1146 // convoluted mess, with tons of "if" statements all over the place checking the 1172 // convoluted mess, with tons of "if" statements all over the place checking the
1147 // size of template parameter CT. 1173 // size of template parameter CT.
1148 // -  
1149 // In several cases, you will see two versions of each function.  One version is -  
1150 // the more portable, standard way of doing things, while the other is the -  
1151 // non-standard, but often significantly faster Visual C++ way. -  
1152 // ============================================================================= 1174 // =============================================================================
-   1175
-   1176 #ifdef SS_NO_LOCALE
-   1177
-   1178         // --------------------------------------------------------------------------
-   1179         // Win32 GetStringTypeEx wrappers
-   1180         // --------------------------------------------------------------------------
-   1181         inline bool wsGetStringType(LCID lc, DWORD dwT, PCSTR pS, int nSize,
-   1182                 WORD* pWd)
-   1183         {
-   1184                 return FALSE != GetStringTypeExA(lc, dwT, pS, nSize, pWd);
-   1185         }
-   1186         inline bool wsGetStringType(LCID lc, DWORD dwT, PCWSTR pS, int nSize,
-   1187                 WORD* pWd)
-   1188         {
-   1189                 return FALSE != GetStringTypeExW(lc, dwT, pS, nSize, pWd);
-   1190         }
-   1191
-   1192
-   1193         template<typename CT>
-   1194                 inline bool ssisspace (CT t)
-   1195         {
-   1196                 WORD toYourMother;
-   1197                 return  wsGetStringType(GetThreadLocale(), CT_CTYPE1, &t, 1, &toYourMother)
-   1198                         && 0 != (C1_BLANK & toYourMother);
-   1199         }
-   1200
-   1201 #endif
1153 1202
1154 // If they defined SS_NO_REFCOUNT, then we must convert all assignments 1203 // If they defined SS_NO_REFCOUNT, then we must convert all assignments
1155 1204
1156 #ifdef SS_NO_REFCOUNT -  
1157         #define SSREF(x) (x).c_str() -  
-   1205 #if defined (_MSC_VER) && (_MSC_VER < 1300)
-   1206         #ifdef SS_NO_REFCOUNT
-   1207                 #define SSREF(x) (x).c_str()
-   1208         #else
-   1209                 #define SSREF(x) (x)
-   1210         #endif
1158 #else 1211 #else
1159         #define SSREF(x) (x) 1212         #define SSREF(x) (x)
1160 #endif 1213 #endif
1161 1214
1162 // ----------------------------------------------------------------------------- 1215 // -----------------------------------------------------------------------------
Line 1177... Line 1230...
1177 } 1230 }
1178 1231
1179 // ----------------------------------------------------------------------------- 1232 // -----------------------------------------------------------------------------
1180 // sstolower/sstoupper -- convert characters to upper/lower case 1233 // sstolower/sstoupper -- convert characters to upper/lower case
1181 // ----------------------------------------------------------------------------- 1234 // -----------------------------------------------------------------------------
1182 template<typename CT> -  
1183 inline CT sstolower(const CT& t, const std::locale& loc = std::locale()) -  
1184 { -  
1185         return std::tolower<CT>(t, loc); -  
1186 } -  
1187 template<typename CT> -  
1188 inline CT sstoupper(const CT& t, const std::locale& loc = std::locale()) -  
1189 { -  
1190         return std::toupper<CT>(t, loc); -  
1191 } -  
-   1235
-   1236 #ifdef SS_NO_LOCALE
-   1237         inline char sstoupper(char ch)          { return (char)::toupper(ch); }
-   1238         inline wchar_t sstoupper(wchar_t ch){ return (wchar_t)::towupper(ch); }
-   1239         inline char sstolower(char ch)          { return (char)::tolower(ch); }
-   1240         inline wchar_t sstolower(wchar_t ch){ return (wchar_t)::tolower(ch); }
-   1241 #else
-   1242         template<typename CT>
-   1243         inline CT sstolower(const CT& t, const std::locale& loc = std::locale())
-   1244         {
-   1245                 return std::tolower<CT>(t, loc);
-   1246         }
-   1247         template<typename CT>
-   1248         inline CT sstoupper(const CT& t, const std::locale& loc = std::locale())
-   1249         {
-   1250                 return std::toupper<CT>(t, loc);
-   1251         }
-   1252 #endif
1192 1253
1193 // ----------------------------------------------------------------------------- 1254 // -----------------------------------------------------------------------------
1194 // ssasn: assignment functions -- assign "sSrc" to "sDst" 1255 // ssasn: assignment functions -- assign "sSrc" to "sDst"
1195 // ----------------------------------------------------------------------------- 1256 // -----------------------------------------------------------------------------
1196 typedef std::string::size_type          SS_SIZETYPE; // just for shorthand, really 1257 typedef std::string::size_type          SS_SIZETYPE; // just for shorthand, really
Line 1609... Line 1670...
1609         inline int ssvsprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl) 1670         inline int ssvsprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl)
1610         { 1671         {
1611                 return vswprintf(pW, nCount, pFmtW, vl); 1672                 return vswprintf(pW, nCount, pFmtW, vl);
1612         } 1673         }
1613 1674
1614         // Microsofties can use -  
-   1675         // Else if this is VC++ in a regular (non-ANSI) build
1615 #elif defined(_MSC_VER) && !defined(SS_ANSI) 1676 #elif defined(_MSC_VER) && !defined(SS_ANSI)
1616 1677
1617         inline int      ssnprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl) -  
-   1678         inline int      ssvsprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl)
1618         { 1679         {
1619                 return _vsnprintf(pA, nCount, pFmtA, vl); 1680                 return _vsnprintf(pA, nCount, pFmtA, vl);
1620         } 1681         }
1621         inline int      ssnprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl) -  
-   1682         inline int      ssvsprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl)
1622         { 1683         {
1623                 return _vsnwprintf(pW, nCount, pFmtW, vl); 1684                 return _vsnwprintf(pW, nCount, pFmtW, vl);
1624         } 1685         }
1625 1686
1626 #elif !defined (SS_DANGEROUS_FORMAT) -  
1627 -  
1628         // GOT COMPILER PROBLEMS HERE? -  
1629         // --------------------------- -  
1630         // Does your compiler choke on one or more of the following 2 functions?  It -  
1631         // probably means that you don't have have either vsnprintf or vsnwprintf in -  
1632         // your version of the CRT.  This is understandable since neither is an ANSI -  
1633         // "C" function.  However it still leaves you in a dilemma.  In order to make -  
1634         // this code build, you're going to have to to use some non-length-checked -  
1635         // formatting functions that every CRT has:  vsprintf and vswprintf.   -  
1636         // -  
1637         // This is very dangerous.  With the proper erroneous (or malicious) code, it -  
1638         // can lead to buffer overlows and crashing your PC.  Use at your own risk -  
1639         // In order to use them, just #define SS_DANGEROUS_FORMAT at the top of -  
1640         // this file. -  
1641         // -  
1642         // Even THEN you might not be all the way home due to some non-conforming -  
1643         // distributions.  More on this in the comments below. -  
1644 -  
1645         inline int      ssnprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl) -  
1646         { -  
1647                 return vsnprintf(pA, nCount, pFmtA, vl); -  
1648         } -  
1649         inline int      ssnprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl) -  
1650         { -  
1651                 return vsnwprintf(pW, nCount, pFmtW, vl); -  
1652         } -  
1653 -  
1654 #else -  
-   1687         // Else (an ANSI build) if they want to allow "dangerous" (i.e. non-length-
-   1688         // checked) formatting
-   1689 #elif defined (SS_DANGEROUS_FORMAT)  // ignore buffer size parameter if needed?
1655 1690
1656         inline int ssvsprintf(PSTR pA, size_t /*nCount*/, PCSTR pFmtA, va_list vl) 1691         inline int ssvsprintf(PSTR pA, size_t /*nCount*/, PCSTR pFmtA, va_list vl)
1657         { 1692         {
1658                 return vsprintf(pA, pFmtA, vl); 1693                 return vsprintf(pA, pFmtA, vl);
1659         } 1694         }
Line 1698... Line 1733...
1698         nCount; 1733         nCount;
1699         return vswprintf(pW, pFmtW, vl); 1734         return vswprintf(pW, pFmtW, vl);
1700 1735
1701     #endif 1736     #endif
1702 1737
-   1738         }
-   1739
-   1740         // OK, it's some kind of ANSI build but no "dangerous" formatting allowed
-   1741 #else
-   1742
-   1743         // GOT COMPILER PROBLEMS HERE?
-   1744         // ---------------------------
-   1745         // Does your compiler choke on one or more of the following 2 functions?  It
-   1746         // probably means that you don't have have either vsnprintf or vsnwprintf in
-   1747         // your version of the CRT.  This is understandable since neither is an ANSI
-   1748         // "C" function.  However it still leaves you in a dilemma.  In order to make
-   1749         // this code build, you're going to have to to use some non-length-checked
-   1750         // formatting functions that every CRT has:  vsprintf and vswprintf.  
-   1751         //
-   1752         // This is very dangerous.  With the proper erroneous (or malicious) code, it
-   1753         // can lead to buffer overlows and crashing your PC.  Use at your own risk
-   1754         // In order to use them, just #define SS_DANGEROUS_FORMAT at the top of
-   1755         // this file.
-   1756         //
-   1757         // Even THEN you might not be all the way home due to some non-conforming
-   1758         // distributions.  More on this in the comments below.
-   1759
-   1760         inline int      ssvsprintf(PSTR pA, size_t nCount, PCSTR pFmtA, va_list vl)
-   1761         {
-   1762         #ifdef _MSC_VER
-   1763                         return _vsnprintf(pA, nCount, pFmtA, vl);
-   1764         #else
-   1765                         return vsnprintf(pA, nCount, pFmtA, vl);
-   1766         #endif
-   1767         }
-   1768         inline int      ssvsprintf(PWSTR pW, size_t nCount, PCWSTR pFmtW, va_list vl)
-   1769         {
-   1770         #ifdef _MSC_VER
-   1771                         return _vsnwprintf(pW, nCount, pFmtW, vl);
-   1772         #else
-   1773                         return vsnwprintf(pW, nCount, pFmtW, vl);
-   1774         #endif
1703         } 1775         }
1704 1776
1705 #endif 1777 #endif
-   1778
1706 1779
1707 1780
1708 1781
1709 // ----------------------------------------------------------------------------- 1782 // -----------------------------------------------------------------------------
1710 // ssload: Type safe, overloaded ::LoadString wrappers 1783 // ssload: Type safe, overloaded ::LoadString wrappers
Line 1726... Line 1799...
1726 // ----------------------------------------------------------------------------- 1799 // -----------------------------------------------------------------------------
1727 // sscoll/ssicoll: Collation wrappers 1800 // sscoll/ssicoll: Collation wrappers
1728 //              Note -- with MSVC I have reversed the arguments order here because the 1801 //              Note -- with MSVC I have reversed the arguments order here because the
1729 //              functions appear to return the opposite of what they should 1802 //              functions appear to return the opposite of what they should
1730 // ----------------------------------------------------------------------------- 1803 // -----------------------------------------------------------------------------
-   1804 #ifndef SS_NO_LOCALE
1731 template <typename CT> 1805 template <typename CT>
1732 inline int sscoll(const CT* sz1, int nLen1, const CT* sz2, int nLen2) 1806 inline int sscoll(const CT* sz1, int nLen1, const CT* sz2, int nLen2)
1733 { 1807 {
1734         const std::collate<CT>& coll = 1808         const std::collate<CT>& coll =
1735                 SS_USE_FACET(std::locale(), std::collate<CT>); 1809                 SS_USE_FACET(std::locale(), std::collate<CT>);
Line 1755... Line 1829...
1755         sslwr(const_cast<CT*>(s1.c_str()), nLen1, loc); 1829         sslwr(const_cast<CT*>(s1.c_str()), nLen1, loc);
1756         sslwr(const_cast<CT*>(s2.c_str()), nLen2, loc); 1830         sslwr(const_cast<CT*>(s2.c_str()), nLen2, loc);
1757         return coll.compare(s2.c_str(), s2.c_str()+nLen2, 1831         return coll.compare(s2.c_str(), s2.c_str()+nLen2,
1758                                                 s1.c_str(), s1.c_str()+nLen1); 1832                                                 s1.c_str(), s1.c_str()+nLen1);
1759 } 1833 }
1760 -  
-   1834 #endif
1761 1835
1762 1836
1763 // ----------------------------------------------------------------------------- 1837 // -----------------------------------------------------------------------------
1764 // ssfmtmsg: FormatMessage equivalents.  Needed because I added a CString facade 1838 // ssfmtmsg: FormatMessage equivalents.  Needed because I added a CString facade
1765 // Again -- no equivalent of these on non-Win32 builds but their might one day 1839 // Again -- no equivalent of these on non-Win32 builds but their might one day
Line 1912... Line 1986...
1912 1986
1913 // ----------------------------------------------------------------------------- 1987 // -----------------------------------------------------------------------------
1914 // Functional objects for changing case.  They also let you pass locales 1988 // Functional objects for changing case.  They also let you pass locales
1915 // ----------------------------------------------------------------------------- 1989 // -----------------------------------------------------------------------------
1916 1990
1917 template<typename CT> -  
1918 struct SSToUpper : public std::binary_function<CT, std::locale, CT> -  
1919 { -  
1920     inline CT operator()(const CT& t, const std::locale& loc) const -  
1921     { -  
1922             return sstoupper<CT>(t, loc); -  
1923     } -  
1924 }; -  
1925 template<typename CT> -  
1926 struct SSToLower : public std::binary_function<CT, std::locale, CT> -  
1927 { -  
1928     inline CT operator()(const CT& t, const std::locale& loc) const -  
1929     { -  
1930             return sstolower<CT>(t, loc); -  
1931     } -  
1932 }; -  
-   1991 #ifdef SS_NO_LOCALE
-   1992         template<typename CT>
-   1993         struct SSToUpper : public std::unary_function<CT, CT>
-   1994         {
-   1995                 inline CT operator()(const CT& t) const
-   1996                 {
-   1997                         return sstoupper(t);
-   1998                 }
-   1999         };
-   2000         template<typename CT>
-   2001         struct SSToLower : public std::unary_function<CT, CT>
-   2002         {
-   2003                 inline CT operator()(const CT& t) const
-   2004                 {
-   2005                         return sstolower(t);
-   2006                 }
-   2007         };
-   2008 #else
-   2009         template<typename CT>
-   2010         struct SSToUpper : public std::binary_function<CT, std::locale, CT>
-   2011         {
-   2012                 inline CT operator()(const CT& t, const std::locale& loc) const
-   2013                 {
-   2014                         return sstoupper<CT>(t, loc);
-   2015                 }
-   2016         };
-   2017         template<typename CT>
-   2018         struct SSToLower : public std::binary_function<CT, std::locale, CT>
-   2019         {
-   2020                 inline CT operator()(const CT& t, const std::locale& loc) const
-   2021                 {
-   2022                         return sstolower<CT>(t, loc);
-   2023                 }
-   2024         };
-   2025 #endif
1933 2026
1934 // This struct is used for TrimRight() and TrimLeft() function implementations. 2027 // This struct is used for TrimRight() and TrimLeft() function implementations.
1935 //template<typename CT> 2028 //template<typename CT>
1936 //struct NotSpace : public std::unary_function<CT, bool> 2029 //struct NotSpace : public std::unary_function<CT, bool>
1937 //{ 2030 //{
Line 1952... Line 2045...
1952         // tries to call the long-gone function. 2045         // tries to call the long-gone function.
1953         // This is DinkumWare's implementation problem.  If you encounter this 2046         // This is DinkumWare's implementation problem.  If you encounter this
1954         // problem, you may replace the calls here with good old isspace() and 2047         // problem, you may replace the calls here with good old isspace() and
1955         // iswspace() from the CRT unless they specify SS_ANSI 2048         // iswspace() from the CRT unless they specify SS_ANSI
1956     2049    
-   2050 #ifdef SS_NO_LOCALE
-   2051        
-   2052         bool operator() (CT t) const { return !ssisspace(t); }
-   2053
-   2054 #else
1957         const std::locale loc; 2055         const std::locale loc;
1958         NotSpace(const std::locale& locArg=std::locale()) : loc(locArg) {} 2056         NotSpace(const std::locale& locArg=std::locale()) : loc(locArg) {}
1959         bool operator() (CT t) const { return !std::isspace(t, loc); } 2057         bool operator() (CT t) const { return !std::isspace(t, loc); }
-   2058 #endif
1960 }; 2059 };
1961 2060
1962 2061
1963 2062
1964 2063
Line 2329... Line 2428...
2329                 // uppercase form, this would probably not work... 2428                 // uppercase form, this would probably not work...
2330 2429
2331                 std::transform(this->begin(), 2430                 std::transform(this->begin(),
2332                                            this->end(), 2431                                            this->end(),
2333                                            this->begin(), 2432                                            this->begin(),
-   2433 #ifdef SS_NO_LOCALE
-   2434                                            SSToUpper<CT>());
-   2435 #else
2334                                            std::bind2nd(SSToUpper<CT>(), loc)); 2436                                            std::bind2nd(SSToUpper<CT>(), loc));
-   2437 #endif
2335 2438
2336                 // ...but if it were, this would probably work better.  Also, this way 2439                 // ...but if it were, this would probably work better.  Also, this way
2337                 // seems to be a bit faster when anything other then the "C" locale is 2440                 // seems to be a bit faster when anything other then the "C" locale is
2338                 // used... 2441                 // used...
2339 2442
Line 2353... Line 2456...
2353                 // uppercase form, this would probably not work... 2456                 // uppercase form, this would probably not work...
2354 2457
2355                 std::transform(this->begin(), 2458                 std::transform(this->begin(),
2356                                            this->end(), 2459                                            this->end(),
2357                                            this->begin(), 2460                                            this->begin(),
-   2461 #ifdef SS_NO_LOCALE
-   2462                                            SSToLower<CT>());
-   2463 #else
2358                                            std::bind2nd(SSToLower<CT>(), loc)); 2464                                            std::bind2nd(SSToLower<CT>(), loc));
-   2465 #endif
2359 2466
2360                 // ...but if it were, this would probably work better.  Also, this way 2467                 // ...but if it were, this would probably work better.  Also, this way
2361                 // seems to be a bit faster when anything other then the "C" locale is 2468                 // seems to be a bit faster when anything other then the "C" locale is
2362                 // used... 2469                 // used...
2363 2470
Line 3033... Line 3140...
3033         // an efficient way to add formatted characters to the string.  You may only 3140         // an efficient way to add formatted characters to the string.  You may only
3034         // add up to STD_BUF_SIZE characters at a time, though 3141         // add up to STD_BUF_SIZE characters at a time, though
3035         void AppendFormatV(const CT* szFmt, va_list argList) 3142         void AppendFormatV(const CT* szFmt, va_list argList)
3036         { 3143         {
3037                 CT szBuf[STD_BUF_SIZE]; 3144                 CT szBuf[STD_BUF_SIZE];
3038         #ifdef SS_ANSI -  
3039                 int nLen = ssvsprintf(szBuf, STD_BUF_SIZE-1, szFmt, argList); 3145                 int nLen = ssvsprintf(szBuf, STD_BUF_SIZE-1, szFmt, argList);
3040         #else -  
3041                 int nLen = ssnprintf(szBuf, STD_BUF_SIZE-1, szFmt, argList); -  
3042         #endif -  
-   3146
3043                 if ( 0 < nLen ) 3147                 if ( 0 < nLen )
3044                         this->append(szBuf, nLen); 3148                         this->append(szBuf, nLen);
3045         } 3149         }
3046 3150
3047         // ------------------------------------------------------------------------- 3151         // -------------------------------------------------------------------------
Line 3062... Line 3166...
3062         // ------------------------------------------------------------------------- 3166         // -------------------------------------------------------------------------
3063 3167
3064         void FormatV(const CT* szFormat, va_list argList) 3168         void FormatV(const CT* szFormat, va_list argList)
3065         { 3169         {
3066         #ifdef SS_ANSI 3170         #ifdef SS_ANSI
3067 -  
-   3171                 MYTYPE str;
3068                 int nLen        = sslen(szFormat) + STD_BUF_SIZE; 3172                 int nLen        = sslen(szFormat) + STD_BUF_SIZE;
3069                 ssvsprintf(GetBuffer(nLen), nLen-1, szFormat, argList); -  
3070                 ReleaseBuffer(); -  
-   3173                 ssvsprintf(str.GetBuffer(nLen), nLen-1, szFormat, argList);
-   3174                 str.ReleaseBuffer();
-   3175                 *this = str;
3071 3176
3072         #else 3177         #else
3073 3178
3074                 CT* pBuf                        = NULL; 3179                 CT* pBuf                        = NULL;
3075                 int nChars                      = 1; 3180                 int nChars                      = 1;
Line 3081... Line 3186...
3081                 { 3186                 {
3082                         // Grow more than linearly (e.g. 512, 1536, 3072, etc) 3187                         // Grow more than linearly (e.g. 512, 1536, 3072, etc)
3083 3188
3084                         nChars                  += ((nTry+1) * FMT_BLOCK_SIZE); 3189                         nChars                  += ((nTry+1) * FMT_BLOCK_SIZE);
3085                         pBuf                    = reinterpret_cast<CT*>(_alloca(sizeof(CT)*nChars)); 3190                         pBuf                    = reinterpret_cast<CT*>(_alloca(sizeof(CT)*nChars));
3086                         nUsed                   = ssnprintf(pBuf, nChars-1, szFormat, argList); -  
-   3191                         nUsed                   = ssvsprintf(pBuf, nChars-1, szFormat, argList);
3087 3192
3088                         // Ensure proper NULL termination. 3193                         // Ensure proper NULL termination.
3089 3194
3090                         nActual                 = nUsed == -1 ? nChars-1 : SSMIN(nUsed, nChars-1); 3195                         nActual                 = nUsed == -1 ? nChars-1 : SSMIN(nUsed, nChars-1);
3091                         pBuf[nActual]= '\0'; 3196                         pBuf[nActual]= '\0';
Line 3113... Line 3218...
3113                         ssasn(os, *this); 3218                         ssasn(os, *this);
3114                         return ::SysAllocString(os.c_str()); 3219                         return ::SysAllocString(os.c_str());
3115                 } 3220                 }
3116         #endif 3221         #endif
3117 3222
-   3223 #ifndef SS_NO_LOCALE
3118         int Collate(PCMYSTR szThat) const 3224         int Collate(PCMYSTR szThat) const
3119         { 3225         {
3120                 return sscoll(this->c_str(), this->length(), szThat, sslen(szThat)); 3226                 return sscoll(this->c_str(), this->length(), szThat, sslen(szThat));
3121         } 3227         }
3122 3228
3123         int CollateNoCase(PCMYSTR szThat) const 3229         int CollateNoCase(PCMYSTR szThat) const
3124         { 3230         {
3125                 return ssicoll(this->c_str(), this->length(), szThat, sslen(szThat)); 3231                 return ssicoll(this->c_str(), this->length(), szThat, sslen(szThat));
3126         } 3232         }
3127 -  
-   3233 #endif
3128         int Compare(PCMYSTR szThat) const 3234         int Compare(PCMYSTR szThat) const
3129         { 3235         {
3130                 return this->compare(szThat);   3236                 return this->compare(szThat);  
3131         } 3237         }
3132 3238