00001 // Module: Log4CPLUS 00002 // File: stringhelper.h 00003 // Created: 3/2003 00004 // Author: Tad E. Smith 00005 // 00006 // 00007 // Copyright 2003-2010 Tad E. Smith 00008 // 00009 // Licensed under the Apache License, Version 2.0 (the "License"); 00010 // you may not use this file except in compliance with the License. 00011 // You may obtain a copy of the License at 00012 // 00013 // http://www.apache.org/licenses/LICENSE-2.0 00014 // 00015 // Unless required by applicable law or agreed to in writing, software 00016 // distributed under the License is distributed on an "AS IS" BASIS, 00017 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00018 // See the License for the specific language governing permissions and 00019 // limitations under the License. 00020 00023 #ifndef LOG4CPLUS_HELPERS_STRINGHELPER_HEADER_ 00024 #define LOG4CPLUS_HELPERS_STRINGHELPER_HEADER_ 00025 00026 #include "dcmtk/oflog/config.h" 00027 #include "dcmtk/oflog/tstring.h" 00028 #include "dcmtk/ofstd/oflist.h" 00029 00030 //#include <algorithm> 00031 //#include <limits> 00032 //#include <iterator> 00033 00034 00035 namespace log4cplus { 00036 namespace helpers { 00037 00041 LOG4CPLUS_EXPORT log4cplus::tstring toUpper(const log4cplus::tstring& s); 00042 00043 00047 LOG4CPLUS_EXPORT log4cplus::tstring toLower(const log4cplus::tstring& s); 00048 00049 00063 template <class StringType> 00064 inline 00065 void 00066 tokenize(const StringType& s, typename StringType::value_type c, 00067 OFList<StringType>& result, bool collapseTokens = true) 00068 { 00069 typedef typename StringType::size_type size_type; 00070 size_type const slen = s.length(); 00071 size_type first = 0; 00072 size_type i = 0; 00073 for (i=0; i < slen; ++i) 00074 { 00075 if (s[i] == c) 00076 { 00077 result.push_back(StringType (s, first, i - first)); 00078 if (collapseTokens) 00079 while (i+1 < slen && s[i+1] == c) 00080 ++i; 00081 first = i + 1; 00082 } 00083 } 00084 if (first != i) 00085 result.push_back(StringType (s, first, i - first)); 00086 } 00087 00088 00089 template <typename intType> 00090 struct ConvertIntegerToStringHelper 00091 { 00092 static inline 00093 void 00094 step1 (tchar * & it, intType & value) 00095 { 00096 // This code assumes two-compliments'. The problem here is that 00097 // integer overflow of an signed type is undefined behavior :( 00098 // This code is based upon http://www.fefe.de/intof.html 00099 00100 // True if intType is unsigned 00101 const OFBool isUnsigned = (OFstatic_cast(intType, -1) < 0) ? OFFalse : OFTrue; 00102 00103 // If intType is a signed type, halfMaxSigned is intType_MAX / 2 00104 const intType halfMaxSigned = OFstatic_cast(intType, 1) << (sizeof(intType) * 8 - 2); 00105 00106 // if intType is a signed type, MaxSigned is its intType_MAX 00107 const intType maxSigned = halfMaxSigned - 1 + halfMaxSigned; 00108 00109 // if intType is a signed type, MinSigned is its intType_MIN 00110 const intType minSigned = OFstatic_cast(intType, -1) - maxSigned; 00111 00112 // This is the minimum value that intType can represent; 00113 const intType minVal = isUnsigned ? 0 : minSigned; 00114 00115 //if (value == (STD_NAMESPACE numeric_limits<intType>::min) ()) 00116 if (value == minVal) 00117 { 00118 intType const r = value / 10; 00119 intType const a = (0-r) * 10; 00120 intType const mod = 0-(a + value); 00121 value = 0-r; 00122 00123 *(it - 1) = OFstatic_cast(tchar, LOG4CPLUS_TEXT('0') + mod); 00124 --it; 00125 } 00126 else 00127 value = 0-value; 00128 } 00129 }; 00130 00131 00132 template<class intType> 00133 inline 00134 void 00135 convertIntegerToString (tstring & str, intType value) 00136 { 00137 if (value == 0) 00138 str = LOG4CPLUS_TEXT("0"); 00139 // We can't use (value < 0) because that could cause a compiler 00140 // warning for unsigned types. 00141 bool const negative = !(value > 0 || value == 0); 00142 00143 const size_t buffer_size = 30; // More than enough space, even for 64 bit integers 00144 // = intTypeLimits::digits10 + 2; 00145 tchar buffer[buffer_size]; 00146 tchar * it = &buffer[buffer_size]; 00147 tchar const * const buf_end = it; 00148 00149 if (negative) 00150 ConvertIntegerToStringHelper<intType>::step1(it, value); 00151 00152 for (; value != 0; --it) 00153 { 00154 intType mod = value % 10; 00155 value = value / 10; 00156 *(it - 1) = OFstatic_cast(tchar, LOG4CPLUS_TEXT('0') + mod); 00157 } 00158 00159 if (negative) 00160 { 00161 --it; 00162 *it = LOG4CPLUS_TEXT('-'); 00163 } 00164 00165 str.assign (OFstatic_cast(tchar const *, it), buf_end - it); 00166 } 00167 00168 00169 template<class intType> 00170 inline 00171 tstring 00172 convertIntegerToString (intType value) 00173 { 00174 tstring result; 00175 convertIntegerToString (result, value); 00176 return result; 00177 } 00178 00179 } // namespace helpers 00180 00181 } // namespace log4cplus 00182 00183 #endif // LOG4CPLUS_HELPERS_STRINGHELPER_HEADER_