00001
00012
00013
00014
00015
00016 #ifndef ECL_CONVERTERS_CONVERT_CHAR_STRINGS_HPP_
00017 #define ECL_CONVERTERS_CONVERT_CHAR_STRINGS_HPP_
00018
00019
00020
00021
00022
00023 #include <cstdio>
00024 #include <cstring>
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
00033
00034
00035 namespace ecl {
00036
00040 namespace converters {
00041
00042
00043
00044
00053 class CharStringBuffer : public ConverterBase {
00054 protected:
00055
00056
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
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;
00138 Number lsd;
00139 char* str_ptr = buffer_end;
00140
00141 do {
00142 lsd = static_cast<Number>(number % 10);
00143 number = static_cast<Number>(number / 10);
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 };
00154
00159
00160
00161
00176 template<>
00177 class Converter<char*,char> : public virtual converters::CharStringBuffer {
00178 public:
00179
00180
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
00200
00206 char* operator ()(const char &input) {
00207 return converters::convertUnsignedIntegral(input,this->buffer_begin,this->buffer_end);
00208 }
00209 };
00210
00211
00212
00227 template<>
00228 class Converter<char*,unsigned char> : public virtual converters::CharStringBuffer {
00229 public:
00230
00231
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
00250
00256 char* operator ()(const unsigned char &input){ return converters::convertUnsignedIntegral(input,this->buffer_begin,this->buffer_end); }
00257 };
00258
00259
00260
00275 template<>
00276 class Converter<char*,short> : public virtual converters::CharStringBuffer {
00277 public:
00278
00279
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
00298
00304 char* operator ()(const short &input){ return converters::convertSignedIntegral(input,this->buffer_begin,this->buffer_end); }
00305 };
00306
00307
00308
00323 template<>
00324 class Converter<char*,unsigned short> : public virtual converters::CharStringBuffer {
00325 public:
00326
00327
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
00346
00352 char* operator ()(const unsigned short &input){ return converters::convertUnsignedIntegral(input,this->buffer_begin,this->buffer_end); }
00353 };
00354
00355
00356
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
00399
00414 template<>
00415 class Converter<char*,unsigned int> : public virtual converters::CharStringBuffer {
00416 public:
00417
00418
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
00437
00443 char* operator ()(const unsigned int &input){ return converters::convertUnsignedIntegral(input,this->buffer_begin,this->buffer_end); }
00444 };
00445
00446
00447
00448
00463 template<>
00464 class Converter<char*,long> : public virtual converters::CharStringBuffer {
00465 public:
00466
00467
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
00486
00492 char* operator ()(const long &input){ return converters::convertSignedIntegral(input,this->buffer_begin,this->buffer_end); }
00493 };
00494
00495
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
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
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
00624
00634 template<>
00635 class Converter<char*,float> : public virtual converters::CharStringBuffer {
00636 public:
00637
00638
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
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
00707 }
00708 private:
00709 char format_specifier[6];
00710 };
00711
00712
00713
00723 template<>
00724 class Converter<char*,double> : public virtual converters::CharStringBuffer {
00725 public:
00726
00727
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
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
00795 }
00796 private:
00797 char format_specifier[6];
00798 };
00799
00800
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
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 };
00901
00902 #endif