$search
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_ */