to_byte_array.hpp
Go to the documentation of this file.
00001 
00008 /*****************************************************************************
00009 ** Ifdefs
00010 *****************************************************************************/
00011 
00012 #ifndef ECL_CONVERTERS_TO_BYTE_ARRAY_HPP_
00013 #define ECL_CONVERTERS_TO_BYTE_ARRAY_HPP_
00014 
00015 /*****************************************************************************
00016 ** Includes
00017 *****************************************************************************/
00018 
00019 #include <vector>
00020 #include <ecl/concepts/containers.hpp>
00021 #include <ecl/errors/compile_time_assert.hpp>
00022 #include <ecl/exceptions/standard_exception.hpp>
00023 #include <ecl/exceptions/macros.hpp>
00024 #include <ecl/type_traits/fundamental_types.hpp>
00025 #include <ecl/type_traits/numeric_limits.hpp>
00026 #include "converter.hpp"
00027 
00028 /*****************************************************************************
00029 ** Namespaces
00030 *****************************************************************************/
00031 
00032 namespace ecl {
00033 
00037 namespace converters {
00038 
00039 /*****************************************************************************
00040 ** Interface
00041 *****************************************************************************/
00042 
00053 template <typename ByteArray, typename Integral>
00054 class IntegralToByteArray : public ConverterBase {
00055 public:
00075         const ByteArray& operator()( ByteArray &byte_array, const Integral &input ) ecl_debug_throw_decl(ecl::StandardException)  {
00076         /*********************
00077                 ** Checks
00078                 **********************/
00079         ecl_compile_time_concept_check(ecl::ContainerConcept<ByteArray>);
00080         ecl_compile_time_concept_check(ecl::ByteContainerConcept<ByteArray>);
00081         ecl_compile_time_assert(is_integral<Integral>::value);
00082         /*********************
00083                 ** Configuration
00084                 **********************/
00085         if ( byte_array.size() != ecl::numeric_limits<Integral>::bytes ) {
00086                 ecl_debug_throw(StandardException(LOC,ConversionError,"The specified byte array size does not match the byte size of the integral type."));
00087                 error_handler = ConversionError;
00088         }
00089 
00090         /*********************
00091                 ** Method
00092                 **********************/
00093         for (unsigned int i = 0; i < ecl::numeric_limits<Integral>::bytes; ++i ) {
00094             byte_array[i] = static_cast<typename ByteArray::value_type>( input >> 8*i);
00095         }
00096         return byte_array;
00097     }
00098 };
00099 
00100 } // namespace converters
00105 /*****************************************************************************
00106 ** Integral to Byte Array Converters
00107 *****************************************************************************/
00111 template <>
00112 class Converter< std::vector<char>, int > : public converters::IntegralToByteArray< std::vector<char>, int > {};
00113 
00117 template <>
00118 class Converter< std::vector<unsigned char>, int > : public converters::IntegralToByteArray< std::vector<unsigned char>, int > {};
00119 
00123 template <>
00124 class Converter< std::vector<signed char>, int > : public converters::IntegralToByteArray< std::vector<signed char>, int > {};
00125 
00129 template <>
00130 class Converter< std::vector<char>, unsigned int > : public converters::IntegralToByteArray< std::vector<char>, unsigned int > {};
00131 
00135 template <>
00136 class Converter< std::vector<unsigned char>, unsigned int > : public converters::IntegralToByteArray< std::vector<unsigned char>, unsigned int > {};
00137 
00141 template <>
00142 class Converter< std::vector<signed char>, unsigned int > : public converters::IntegralToByteArray< std::vector<signed char>, unsigned int > {};
00143 
00147 template <>
00148 class Converter< std::vector<char>, long > : public converters::IntegralToByteArray< std::vector<char>, long > {};
00149 
00153 template <>
00154 class Converter< std::vector<unsigned char>, long > : public converters::IntegralToByteArray< std::vector<unsigned char>, long > {};
00155 
00159 template <>
00160 class Converter< std::vector<signed char>, long > : public converters::IntegralToByteArray< std::vector<signed char>, long > {};
00161 
00165 template <>
00166 class Converter< std::vector<char>, unsigned long > : public converters::IntegralToByteArray< std::vector<char>, unsigned long > {};
00167 
00171 template <>
00172 class Converter< std::vector<unsigned char>, unsigned long > : public converters::IntegralToByteArray< std::vector<unsigned char>, unsigned long > {};
00173 
00177 template <>
00178 class Converter< std::vector<signed char>, unsigned long > : public converters::IntegralToByteArray< std::vector<signed char>, unsigned long > {};
00179 
00180 
00181 /*****************************************************************************
00182 ** Byte Converter Interface
00183 *****************************************************************************/
00191 template <>
00192 class Converter< std::vector<char>, char*> : public converters::ConverterBase {
00193 public:
00211         std::vector<char> operator ()(const char* input) ecl_debug_throw_decl(StandardException) {
00212 
00213                 std::vector<char> bytes;
00214                 state = waiting_zero;
00215 
00216                 while ( *input != '\0') {
00217                         switch (state) {
00218                                 case (waiting_zero) : {
00219                                         if ( *input == '0' ) {
00220                                                 state = waiting_x;
00221                                         } else if ( *input == ' ' ) {
00222                                                 // ignore whitespace
00223                                         } else {
00224                                                 ecl_debug_throw(StandardException(LOC,ConversionError));
00225                                                 error_handler = ConversionError;
00226                                                 bytes.clear();
00227                                                 return bytes;
00228                                         }
00229                                         break;
00230                                 }
00231                                 case (waiting_x) : {
00232                                         if ( *input == 'x' ) {
00233                                                 state = waiting_first_digit;
00234                                         } else {
00235                                                 ecl_debug_throw(StandardException(LOC,ConversionError));
00236                                                 error_handler = ConversionError;
00237                                                 bytes.clear();
00238                                                 return bytes;
00239                                         }
00240                                         break;
00241                                 }
00242                                 case (waiting_first_digit) : {
00243                                         if ( (*input >= '0' ) && (*input <= '9' ) ) {
00244                                                 byte = ( *input - '0' ) << 4;
00245                                                 state = waiting_second_digit;
00246                                         } else if ( (*input >= 'a' ) && (*input <= 'f' ) ) {
00247                                                 byte = ( ( *input - 'a' ) + 0x0A ) << 4;
00248                                                 state = waiting_second_digit;
00249                                         } else if ( (*input >= 'A' ) && (*input <= 'F' ) ) {
00250                                                 byte = ( ( *input - 'A' ) + 0x0A ) << 4;
00251                                                 state = waiting_second_digit;
00252                                         } else {
00253                                                 ecl_debug_throw(StandardException(LOC,ConversionError));
00254                                                 error_handler = ConversionError;
00255                                                 bytes.clear();
00256                                                 return bytes;
00257                                         }
00258                                         break;
00259                                 }
00260                                 case (waiting_second_digit) : {
00261                                         if ( (*input >= '0' ) && (*input <= '9' ) ) {
00262                                                 byte += *input - '0';
00263                                                 bytes.push_back(byte);
00264                                         } else if ( (*input >= 'a' ) && (*input <= 'f' ) ) {
00265                                                 byte += ( *input - 'a' ) + 0x0A;
00266                                                 bytes.push_back(byte);
00267                                         } else if ( (*input >= 'A' ) && (*input <= 'F' ) ) {
00268                                                 byte += ( *input - 'A' ) + 0x0A;
00269                                                 bytes.push_back(byte);
00270                                         } else {
00271                                                 ecl_debug_throw(StandardException(LOC,ConversionError));
00272                                                 error_handler = ConversionError;
00273                                                 bytes.clear();
00274                                                 return bytes;
00275                                         }
00276                                         state = waiting_zero;
00277                                         break;
00278                                 }
00279                                 default : {
00280                                         state = waiting_zero;
00281                                         break;
00282                                 }
00283                         }
00284                         ++input;
00285                 }
00286                 return bytes;
00287         };
00288     virtual ~Converter() {}
00289 
00290 private:
00291     unsigned int state;
00292     char byte;
00293     static const unsigned int waiting_zero = 0;
00294     static const unsigned int waiting_x = 1;
00295     static const unsigned int waiting_first_digit = 2;
00296     static const unsigned int waiting_second_digit = 3;
00297 };
00298 
00299 /*****************************************************************************
00300  * Byte Array Converter Family
00301  ****************************************************************************/
00305 template <>
00306 class Converter< std::vector<char>,void>  :
00307     public Converter< std::vector<char>, char* >,
00308     public Converter< std::vector<char>, int >,
00309     public Converter< std::vector<char>, unsigned int >,
00310     public Converter< std::vector<char>, long >,
00311     public Converter< std::vector<char>, unsigned long >
00312 {
00313 public:
00314         virtual ~Converter() {}
00315 
00316     using Converter< std::vector<char>, char* >::operator();
00317     using Converter< std::vector<char>, int >::operator();
00318     using Converter< std::vector<char>, unsigned int >::operator();
00319     using Converter< std::vector<char>, long >::operator();
00320     using Converter< std::vector<char>, unsigned long >::operator();
00321 };
00322 
00326 template <>
00327 class Converter< std::vector<unsigned char>,void>  :
00328     public Converter< std::vector<unsigned char>, int >,
00329     public Converter< std::vector<unsigned char>, unsigned int >,
00330     public Converter< std::vector<unsigned char>, long >,
00331     public Converter< std::vector<unsigned char>, unsigned long >
00332 {
00333 public:
00334         virtual ~Converter() {}
00335 
00336     using Converter< std::vector<unsigned char>, int >::operator();
00337     using Converter< std::vector<unsigned char>, unsigned int >::operator();
00338     using Converter< std::vector<unsigned char>, long >::operator();
00339     using Converter< std::vector<unsigned char>, unsigned long >::operator();
00340 };
00341 
00345 template <>
00346 class Converter< std::vector<signed char>,void>  :
00347     public Converter< std::vector<signed char>, int >,
00348     public Converter< std::vector<signed char>, unsigned int >,
00349     public Converter< std::vector<signed char>, long >,
00350     public Converter< std::vector<signed char>, unsigned long >
00351 {
00352 public:
00353         virtual ~Converter() {}
00354 
00355         using Converter< std::vector<signed char>, int >::operator();
00356     using Converter< std::vector<signed char>, unsigned int >::operator();
00357     using Converter< std::vector<signed char>, long >::operator();
00358     using Converter< std::vector<signed char>, unsigned long >::operator();
00359 };
00360 
00361 } // namespace ecl
00362 
00363 #endif /* ECL_CONVERTERS_TO_BYTE_ARRAY_HPP_ */


ecl_converters
Author(s): Daniel Stonier (d.stonier@gmail.com)
autogenerated on Thu Jan 2 2014 11:12:05