You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							210 lines
						
					
					
						
							6.0 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							210 lines
						
					
					
						
							6.0 KiB
						
					
					
				| // -*- C++ -*- | |
| // Module:  Log4CPLUS | |
| // File:    stringhelper.h | |
| // Created: 3/2003 | |
| // Author:  Tad E. Smith | |
| // | |
| // | |
| // Copyright 2003-2010 Tad E. Smith | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| //     http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
|  | |
| /** @file */ | |
| 
 | |
| #ifndef LOG4CPLUS_HELPERS_STRINGHELPER_HEADER_ | |
| #define LOG4CPLUS_HELPERS_STRINGHELPER_HEADER_ | |
|  | |
| #include <log4cplus/config.hxx> | |
|  | |
| #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE) | |
| #pragma once | |
| #endif | |
|  | |
| #include <log4cplus/tstring.h> | |
|  | |
| #include <algorithm> | |
| #include <limits> | |
|  | |
| 
 | |
| namespace log4cplus { | |
|     namespace helpers { | |
| 
 | |
|         /** | |
|          * Returns <code>s</code> in upper case. | |
|          */ | |
|         LOG4CPLUS_EXPORT log4cplus::tstring toUpper(const log4cplus::tstring& s); | |
| 
 | |
| 
 | |
|         /** | |
|          * Returns <code>s</code> in lower case. | |
|          */ | |
|         LOG4CPLUS_EXPORT log4cplus::tstring toLower(const log4cplus::tstring& s); | |
| 
 | |
| 
 | |
|         /** | |
|          * Tokenize <code>s</code> using <code>c</code> as the delimiter and | |
|          * put the resulting tokens in <code>_result</code>.  If | |
|          * <code>collapseTokens</code> is false, multiple adjacent delimiters | |
|          * will result in zero length tokens. | |
|          * | |
|          * <b>Example:</b> | |
|          * <pre> | |
|          *   string s = // Set string with '.' as delimiters | |
|          *   list<log4cplus::tstring> tokens; | |
|          *   tokenize(s, '.', back_insert_iterator<list<string> >(tokens)); | |
|          * </pre> | |
|          */ | |
|         template <class StringType, class OutputIter> | |
|         inline | |
|         void | |
|         tokenize(const StringType& s, typename StringType::value_type c, | |
|             OutputIter result, bool collapseTokens = true) | |
|         { | |
|             typedef typename StringType::size_type size_type; | |
|             size_type const slen = s.length(); | |
|             size_type first = 0; | |
|             size_type i = 0; | |
|             for (i=0; i < slen; ++i) | |
|             { | |
|                 if (s[i] == c) | |
|                 { | |
|                     *result = StringType (s, first, i - first); | |
|                     ++result; | |
|                     if (collapseTokens) | |
|                         while (i+1 < slen && s[i+1] == c) | |
|                             ++i; | |
|                     first = i + 1; | |
|                 } | |
|             } | |
|             if (first != i) | |
|                 *result = StringType (s, first, i - first); | |
|         } | |
| 
 | |
| 
 | |
|         template <typename intType, bool isSigned> | |
|         struct ConvertIntegerToStringHelper; | |
| 
 | |
| 
 | |
|         template <typename intType> | |
|         struct ConvertIntegerToStringHelper<intType, true> | |
|         { | |
|             static inline | |
|             void | |
|             step1 (tchar * & it, intType & value) | |
|             { | |
|                 // The sign of the result of the modulo operator is | |
|                 // implementation defined. That's why we work with | |
|                 // positive counterpart instead.  Also, in twos | |
|                 // complement arithmetic the smallest negative number | |
|                 // does not have positive counterpart; the range is | |
|                 // asymetric.  That's why we handle the case of value | |
|                 // == min() specially here. | |
|                 if (value == (std::numeric_limits<intType>::min) ()) | |
|                 { | |
|                     intType const r = value / 10; | |
|                     intType const a = (-r) * 10; | |
|                     intType const mod = -(a + value); | |
|                     value = -r; | |
| 
 | |
|                     *(it - 1) = LOG4CPLUS_TEXT('0') + static_cast<tchar>(mod); | |
|                     --it; | |
|                 } | |
|                 else | |
|                     value = -value; | |
|             } | |
| 
 | |
|             static inline | |
|             bool | |
|             is_negative (intType val) | |
|             { | |
|                 return val < 0; | |
|             } | |
|         }; | |
| 
 | |
| 
 | |
|         template <typename intType> | |
|         struct ConvertIntegerToStringHelper<intType, false> | |
|         { | |
|             static inline | |
|             void | |
|             step1 (tchar * &, intType &) | |
|             { | |
|                 // This will never be called for unsigned types. | |
|             } | |
| 
 | |
|             static inline | |
|             bool | |
|             is_negative (intType) | |
|             { | |
|                 return false; | |
|             } | |
|         }; | |
| 
 | |
| 
 | |
|         template<class intType> | |
|         inline | |
|         void | |
|         convertIntegerToString (tstring & str, intType value) | |
|         { | |
|             typedef std::numeric_limits<intType> intTypeLimits; | |
|             typedef ConvertIntegerToStringHelper<intType, intTypeLimits::is_signed> | |
|                 HelperType; | |
| 
 | |
|             const std::size_t buffer_size | |
|                 = intTypeLimits::digits10 + 2; | |
|             tchar buffer[buffer_size]; | |
|             tchar * it = &buffer[buffer_size]; | |
|             tchar const * const buf_end = it; | |
| 
 | |
|             if (value == 0) | |
|             { | |
|                 --it; | |
|                 *it = LOG4CPLUS_TEXT('0'); | |
|             } | |
| 
 | |
|             bool const negative = HelperType::is_negative (value); | |
|             if (negative) | |
|                 HelperType::step1 (it, value); | |
| 
 | |
|             for (; value != 0; --it) | |
|             { | |
|                 intType mod = value % 10; | |
|                 value = value / 10; | |
|                 *(it - 1) = LOG4CPLUS_TEXT('0') + static_cast<tchar>(mod); | |
|             } | |
| 
 | |
|             if (negative) | |
|             { | |
|                 --it; | |
|                 *it = LOG4CPLUS_TEXT('-'); | |
|             } | |
| 
 | |
|             str.assign (static_cast<tchar const *>(it), buf_end); | |
|         } | |
| 
 | |
| 
 | |
|         template<class intType> | |
|         inline | |
|         tstring | |
|         convertIntegerToString (intType value) | |
|         { | |
|             tstring result; | |
|             convertIntegerToString (result, value); | |
|             return result; | |
|         } | |
| 
 | |
|     } // namespace helpers | |
|  | |
| } // namespace log4cplus | |
|  | |
| #endif // LOG4CPLUS_HELPERS_STRINGHELPER_HEADER_
 |