$search
00001 00012 /***************************************************************************** 00013 ** Ifdefs 00014 *****************************************************************************/ 00015 00016 #ifndef ECL_CONVERTERS_CONVERT_CHAR_STRINGS_HPP_ 00017 #define ECL_CONVERTERS_CONVERT_CHAR_STRINGS_HPP_ 00018 00019 /***************************************************************************** 00020 ** Includes 00021 *****************************************************************************/ 00022 00023 #include <cstdio> // vsnprintf 00024 #include <cstring> //strcat 00025 #include <new> 00026 #include "converter.hpp" 00027 #include <ecl/errors/handlers.hpp> 00028 #include <ecl/exceptions/standard_exception.hpp> 00029 #include <ecl/mpl/converters.hpp> 00030 00031 /***************************************************************************** 00032 ** Namespaces 00033 *****************************************************************************/ 00034 00035 namespace ecl { 00036 00040 namespace converters { 00041 00042 /***************************************************************************** 00043 ** Inheritable Buffer Interface 00044 *****************************************************************************/ 00053 class CharStringBuffer : public ConverterBase { 00054 protected: 00055 /****************************************** 00056 ** C&D's 00057 *******************************************/ 00063 CharStringBuffer(char* begin, char* end) : buffer_begin(begin),buffer_end(end),delete_buffer(false) {} 00073 CharStringBuffer(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : delete_buffer(true) { 00074 buffer_begin = new (std::nothrow) char[buffer_size]; 00075 buffer_end = buffer_begin + (buffer_size-1); 00076 if ( buffer_begin == NULL ) { 00077 ecl_debug_throw(ecl::StandardException(LOC,ecl::MemoryError,"Failed to allocate memory for the char string buffer.")); 00078 error_handler = ecl::MemoryError; 00079 } 00080 } 00084 virtual ~CharStringBuffer() { 00085 if(delete_buffer) { 00086 delete[] buffer_begin; 00087 delete_buffer = false; 00088 } 00089 } 00090 00091 char *buffer_begin; 00092 char *buffer_end; 00093 bool delete_buffer; 00094 }; 00095 00096 /***************************************************************************** 00097 ** Character String Converter Utilities 00098 *****************************************************************************/ 00107 template <typename Number> 00108 char* convertSignedIntegral(const Number &number, char* buffer_begin, char* buffer_end) 00109 { 00110 typedef typename Unsigned<Number>::type UnsignedNumber; 00111 00112 char *s; 00113 if ( number >= 0 ) { 00114 s = convertUnsignedIntegral(static_cast<UnsignedNumber>(number),buffer_begin,buffer_end); 00115 } else { 00116 s = convertUnsignedIntegral(static_cast<UnsignedNumber>(-1*number),buffer_begin+1,buffer_end); 00117 --s; 00118 *s = '-'; 00119 } 00120 return s; 00121 } 00122 00134 template <typename Number> 00135 char* convertUnsignedIntegral(Number number, char* buffer_begin, char* buffer_end) 00136 { 00137 *buffer_end = 0; // Set to the null terminator 00138 Number lsd; 00139 char* str_ptr = buffer_end; 00140 00141 do { 00142 lsd = static_cast<Number>(number % 10); // Determine the least significant digit. 00143 number = static_cast<Number>(number / 10); // Deal with next most significant. 00144 --str_ptr; 00145 if ( str_ptr < buffer_begin ) { return NULL; } 00146 *str_ptr = '0'+lsd; 00147 } while (number != 0); 00148 return str_ptr; 00149 }; 00150 00151 00152 00153 }; // namespace converters 00154 00159 /***************************************************************************** 00160 ** Char String Converters [char] 00161 *****************************************************************************/ 00176 template<> 00177 class Converter<char*,char> : public virtual converters::CharStringBuffer { 00178 public: 00179 /****************************************** 00180 ** C&D's 00181 *******************************************/ 00187 Converter(char* begin, char* end) : converters::CharStringBuffer(begin,end) {} 00193 Converter(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : 00194 converters::CharStringBuffer(buffer_size) {} 00195 00196 virtual ~Converter() {} 00197 00198 /****************************************** 00199 ** Converters 00200 *******************************************/ 00206 char* operator ()(const char &input) { 00207 return converters::convertUnsignedIntegral(input,this->buffer_begin,this->buffer_end); 00208 } 00209 }; 00210 /***************************************************************************** 00211 ** Char String Converters [unsigned char] 00212 *****************************************************************************/ 00227 template<> 00228 class Converter<char*,unsigned char> : public virtual converters::CharStringBuffer { 00229 public: 00230 /****************************************** 00231 ** C&D's 00232 *******************************************/ 00238 Converter(char* begin, char* end) : converters::CharStringBuffer(begin,end) {} 00244 Converter(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : converters::CharStringBuffer(buffer_size) {} 00245 00246 virtual ~Converter() {} 00247 00248 /****************************************** 00249 ** Converters 00250 *******************************************/ 00256 char* operator ()(const unsigned char &input){ return converters::convertUnsignedIntegral(input,this->buffer_begin,this->buffer_end); } 00257 }; 00258 /***************************************************************************** 00259 ** Char String Converters [short] 00260 *****************************************************************************/ 00275 template<> 00276 class Converter<char*,short> : public virtual converters::CharStringBuffer { 00277 public: 00278 /****************************************** 00279 ** C&D's 00280 *******************************************/ 00286 Converter(char* begin, char* end) : converters::CharStringBuffer(begin,end) {} 00292 Converter(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : converters::CharStringBuffer(buffer_size) {} 00293 00294 virtual ~Converter() {} 00295 00296 /****************************************** 00297 ** Converters 00298 *******************************************/ 00304 char* operator ()(const short &input){ return converters::convertSignedIntegral(input,this->buffer_begin,this->buffer_end); } 00305 }; 00306 /***************************************************************************** 00307 ** Char String Converters [unsigned short] 00308 *****************************************************************************/ 00323 template<> 00324 class Converter<char*,unsigned short> : public virtual converters::CharStringBuffer { 00325 public: 00326 /****************************************** 00327 ** C&D's 00328 *******************************************/ 00334 Converter(char* begin, char* end) : converters::CharStringBuffer(begin,end) {} 00340 Converter(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : converters::CharStringBuffer(buffer_size) {} 00341 00342 virtual ~Converter() {} 00343 00344 /****************************************** 00345 ** Converters 00346 *******************************************/ 00352 char* operator ()(const unsigned short &input){ return converters::convertUnsignedIntegral(input,this->buffer_begin,this->buffer_end); } 00353 }; 00354 00355 /***************************************************************************** 00356 ** Char String Converters [int] 00357 *****************************************************************************/ 00372 template<> 00373 class Converter<char*,int> : public virtual converters::CharStringBuffer { 00374 public: 00380 Converter(char* begin, char* end) : converters::CharStringBuffer(begin,end) {} 00386 Converter(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : converters::CharStringBuffer(buffer_size) {} 00387 00388 virtual ~Converter() {} 00389 00395 char* operator ()(const int &input){ return converters::convertSignedIntegral(input,this->buffer_begin,this->buffer_end); } 00396 }; 00397 /***************************************************************************** 00398 ** Char String Converters [unsigned int] 00399 *****************************************************************************/ 00414 template<> 00415 class Converter<char*,unsigned int> : public virtual converters::CharStringBuffer { 00416 public: 00417 /****************************************** 00418 ** C&D's 00419 *******************************************/ 00425 Converter(char* begin, char* end) : converters::CharStringBuffer(begin,end) {} 00431 Converter(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : converters::CharStringBuffer(buffer_size) {} 00432 00433 virtual ~Converter() {} 00434 00435 /****************************************** 00436 ** Converters 00437 *******************************************/ 00443 char* operator ()(const unsigned int &input){ return converters::convertUnsignedIntegral(input,this->buffer_begin,this->buffer_end); } 00444 }; 00445 00446 /***************************************************************************** 00447 ** Char String Converters [long] 00448 *****************************************************************************/ 00463 template<> 00464 class Converter<char*,long> : public virtual converters::CharStringBuffer { 00465 public: 00466 /****************************************** 00467 ** C&D's 00468 *******************************************/ 00474 Converter(char* begin, char* end) : converters::CharStringBuffer(begin,end) {} 00480 Converter(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : converters::CharStringBuffer(buffer_size) {} 00481 00482 virtual ~Converter() {} 00483 00484 /****************************************** 00485 ** Converters 00486 *******************************************/ 00492 char* operator ()(const long &input){ return converters::convertSignedIntegral(input,this->buffer_begin,this->buffer_end); } 00493 }; 00494 /***************************************************************************** 00495 ** Char String Converters [unsigned long] 00496 *****************************************************************************/ 00511 template<> 00512 class Converter<char*,unsigned long> : public virtual converters::CharStringBuffer { 00513 public: 00519 Converter(char* begin, char* end) : converters::CharStringBuffer(begin,end) {} 00525 Converter(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : converters::CharStringBuffer(buffer_size) {} 00526 00527 virtual ~Converter() {} 00528 00534 char* operator ()(const unsigned long &input){ return converters::convertUnsignedIntegral(input,this->buffer_begin,this->buffer_end); } 00535 }; 00536 /***************************************************************************** 00537 ** Char String Converters [long long] 00538 *****************************************************************************/ 00553 template<> 00554 class Converter<char*,long long> : public virtual converters::CharStringBuffer { 00555 public: 00561 Converter(char* begin, char* end) : converters::CharStringBuffer(begin,end) {} 00567 Converter(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : converters::CharStringBuffer(buffer_size) {} 00568 00569 virtual ~Converter() {} 00570 00576 char* operator ()(const long long &input){ return converters::convertSignedIntegral(input,this->buffer_begin,this->buffer_end); } 00577 }; 00578 /***************************************************************************** 00579 ** Char String Converters [unsigned long long] 00580 *****************************************************************************/ 00595 template<> 00596 class Converter<char*,unsigned long long> : public virtual converters::CharStringBuffer { 00597 public: 00603 Converter(char* begin, char* end) : converters::CharStringBuffer(begin,end) { 00604 } 00610 Converter(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : converters::CharStringBuffer(buffer_size) { 00611 } 00612 00613 virtual ~Converter() {} 00614 00620 char* operator ()(const unsigned long long &input){ return converters::convertUnsignedIntegral(input,this->buffer_begin,this->buffer_end); } 00621 }; 00622 /***************************************************************************** 00623 ** Char String Converters [float] 00624 *****************************************************************************/ 00634 template<> 00635 class Converter<char*,float> : public virtual converters::CharStringBuffer { 00636 public: 00637 /****************************************** 00638 ** C&D's 00639 *******************************************/ 00645 Converter(char* begin, char* end) : converters::CharStringBuffer(begin,end) { 00646 format_specifier[0] = '%'; 00647 format_specifier[1] = '.'; 00648 format_specifier[2] = 'x'; 00649 format_specifier[3] = 'f'; 00650 format_specifier[4] = 'f'; 00651 format_specifier[5] = '\0'; 00652 } 00658 Converter(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : converters::CharStringBuffer(buffer_size) { 00659 format_specifier[0] = '%'; 00660 format_specifier[1] = '.'; 00661 format_specifier[2] = 'x'; 00662 format_specifier[3] = 'f'; 00663 format_specifier[4] = 'f'; 00664 format_specifier[5] = '\0'; 00665 } 00666 00667 virtual ~Converter() {} 00668 00669 /****************************************** 00670 ** Converters 00671 *******************************************/ 00683 char* operator ()(const float &input, const int& precision = -1){ 00684 if ( precision < 0 ) { 00685 format_specifier[1] = 'f'; 00686 format_specifier[2] = '\0'; 00687 } else if ( precision < 10 ) { 00688 format_specifier[1] = '.'; 00689 format_specifier[2] = '0'+precision; 00690 format_specifier[3] = 'f'; 00691 format_specifier[4] = '\0'; 00692 } else if ( precision < 20 ) { 00693 format_specifier[1] = '.'; 00694 format_specifier[2] = '1'; 00695 format_specifier[3] = '0'+(precision - 10); 00696 format_specifier[4] = 'f'; 00697 } else { 00698 format_specifier[1] = '.'; 00699 format_specifier[2] = '2'; 00700 format_specifier[3] = '0'; 00701 format_specifier[4] = 'f'; 00702 } 00703 00704 snprintf(this->buffer_begin, this->buffer_end-this->buffer_begin, format_specifier, input); 00705 return this->buffer_begin; 00706 // return converters::convertDecimal<32>(input,this->buffer_begin,this->buffer_end); 00707 } 00708 private: 00709 char format_specifier[6]; 00710 }; 00711 /***************************************************************************** 00712 ** Char String Converters [double] 00713 *****************************************************************************/ 00723 template<> 00724 class Converter<char*,double> : public virtual converters::CharStringBuffer { 00725 public: 00726 /****************************************** 00727 ** C&D's 00728 *******************************************/ 00734 Converter(char* begin, char* end) : converters::CharStringBuffer(begin,end) { 00735 format_specifier[0] = '%'; 00736 format_specifier[1] = '.'; 00737 format_specifier[2] = 'x'; 00738 format_specifier[3] = 'f'; 00739 format_specifier[4] = 'f'; 00740 format_specifier[5] = '\0'; 00741 } 00747 Converter(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : converters::CharStringBuffer(buffer_size) { 00748 format_specifier[0] = '%'; 00749 format_specifier[1] = '.'; 00750 format_specifier[2] = 'x'; 00751 format_specifier[3] = 'f'; 00752 format_specifier[4] = 'f'; 00753 format_specifier[5] = '\0'; 00754 } 00755 00756 virtual ~Converter() {} 00757 00758 /****************************************** 00759 ** Converters 00760 *******************************************/ 00772 char* operator ()(const double &input, const int& precision = -1){ 00773 if ( precision < 0 ) { 00774 format_specifier[1] = 'f'; 00775 format_specifier[2] = '\0'; 00776 } else if ( precision < 10 ) { 00777 format_specifier[1] = '.'; 00778 format_specifier[2] = '0'+precision; 00779 format_specifier[3] = 'f'; 00780 format_specifier[4] = '\0'; 00781 } else if ( precision < 20 ) { 00782 format_specifier[1] = '.'; 00783 format_specifier[2] = '1'; 00784 format_specifier[3] = '0'+(precision - 10); 00785 format_specifier[4] = 'f'; 00786 } else { 00787 format_specifier[1] = '.'; 00788 format_specifier[2] = '2'; 00789 format_specifier[3] = '0'; 00790 format_specifier[4] = 'f'; 00791 } 00792 snprintf(this->buffer_begin, this->buffer_end-this->buffer_begin, format_specifier, input); 00793 return this->buffer_begin; 00794 // return converters::convertDecimal<64>(input,this->buffer_begin,this->buffer_end); 00795 } 00796 private: 00797 char format_specifier[6]; 00798 }; 00799 /***************************************************************************** 00800 ** Char String Converters [bool] 00801 *****************************************************************************/ 00815 template<> 00816 class Converter<char*,bool> : public virtual converters::CharStringBuffer { 00817 public: 00821 Converter() : converters::CharStringBuffer(6) {} 00822 00823 virtual ~Converter() {} 00824 00830 char* operator ()(const bool &input){ 00831 *buffer_begin = '\0'; 00832 input ? strcat(buffer_begin,"true") : strcat (buffer_begin,"false"); 00833 return buffer_begin; 00834 } 00835 }; 00836 00837 /***************************************************************************** 00838 * Char String Converter Family 00839 ****************************************************************************/ 00850 template <> 00851 class Converter<char*,void> : 00852 public Converter<char*,char>, 00853 public Converter<char*,short>, 00854 public Converter<char*,int>, 00855 public Converter<char*,long>, 00856 public Converter<char*,unsigned char>, 00857 public Converter<char*,unsigned short>, 00858 public Converter<char*,unsigned int>, 00859 public Converter<char*,unsigned long>, 00860 public Converter<char*,float>, 00861 public Converter<char*,double>, 00862 public Converter<char*,long long>, 00863 public Converter<char*,unsigned long long>, 00864 public Converter<char*,bool> 00865 { 00866 public: 00872 Converter(char* begin, char* end) : converters::CharStringBuffer(begin,end) { 00873 } 00880 Converter(int buffer_size = 250) ecl_debug_throw_decl(StandardException) : converters::CharStringBuffer(buffer_size) { 00881 } 00882 00883 virtual ~Converter() {} 00884 00885 using Converter<char*,char>::operator(); 00886 using Converter<char*,short>::operator(); 00887 using Converter<char*,int>::operator(); 00888 using Converter<char*,long>::operator(); 00889 using Converter<char*,unsigned char>::operator(); 00890 using Converter<char*,unsigned short>::operator(); 00891 using Converter<char*,unsigned int>::operator(); 00892 using Converter<char*,unsigned long>::operator(); 00893 using Converter<char*,float>::operator(); 00894 using Converter<char*,double>::operator(); 00895 using Converter<char*,long long>::operator(); 00896 using Converter<char*,unsigned long long>::operator(); 00897 using Converter<char*,bool>::operator(); 00898 }; 00899 00900 }; // Namespace ecl 00901 00902 #endif /*ECL_CONVERTERS_CONVERT_CHAR_STRINGS_HPP_*/