endianness.hh
Go to the documentation of this file.
00001 #ifndef TYPELIB_ENDIANSWAP_HH
00002 #define TYPELIB_ENDIANSWAP_HH
00003 
00004 #include <typelib/value.hh>
00005 #include <utilmm/system/endian.hh>
00006 #include <limits>
00007 
00008 namespace Typelib
00009 {
00010     struct UnsupportedEndianSwap : public std::runtime_error
00011     { 
00012         UnsupportedEndianSwap(std::string const& what) : std::runtime_error("cannot swap " + what) { }
00013     };
00014 
00015     /* This visitor swaps the endianness of the given value in-place */
00016     class EndianSwapVisitor : public ValueVisitor
00017     {
00018     protected:
00019         bool visit_ (int8_t  & value) { value = utilmm::endian::swap(value); return true; }
00020         bool visit_ (uint8_t & value) { value = utilmm::endian::swap(value); return true; }
00021         bool visit_ (int16_t & value) { value = utilmm::endian::swap(value); return true; }
00022         bool visit_ (uint16_t& value) { value = utilmm::endian::swap(value); return true; }
00023         bool visit_ (int32_t & value) { value = utilmm::endian::swap(value); return true; }
00024         bool visit_ (uint32_t& value) { value = utilmm::endian::swap(value); return true; }
00025         bool visit_ (int64_t & value) { value = utilmm::endian::swap(value); return true; }
00026         bool visit_ (uint64_t& value) { value = utilmm::endian::swap(value); return true; }
00027         bool visit_ (float   & value) { value = utilmm::endian::swap(value); return true; }
00028         bool visit_ (double  & value) { value = utilmm::endian::swap(value); return true; }
00029         bool visit_ (Value const& v, Pointer const& t) { throw UnsupportedEndianSwap("pointers"); }
00030         bool visit_ (Enum::integral_type& v, Enum const& e) { v = utilmm::endian::swap(v); return true; }
00031     };
00032 
00034     void endian_swap(Value v)
00035     {
00036         EndianSwapVisitor swapper;
00037         swapper.apply(v);
00038     }
00039 
00040     class CompileEndianSwapVisitor : public TypeVisitor 
00041     {
00042         // The current place into the output: the next element which are to be
00043         // byte-swapped will be written at this index in the output data
00044         // buffer.
00045         size_t m_output_index;
00046 
00047     public:
00048         // The compiled-in description of the byte-swap operation
00049         //
00050         // Given an output index, an element of compiled is the absolute
00051         // index of the input byte which should be written at this output index:
00052         //   output_buffer[output_index] = input_buffer[*it_compiled]
00053         //
00054         // After a "normal" operation (i.e. neither a skip nor an array),
00055         // output index is incremented and we handle the next operation
00056         // found in compiled
00057         std::vector<size_t> m_compiled;
00058 
00063         static size_t const FLAG_SKIP  = ((size_t) -1);
00071         static size_t const FLAG_ARRAY = ((size_t) -2);
00072         static size_t const FLAG_END   = ((size_t) -3);
00073         static size_t const FLAG_SWAP_4 = ((size_t) -4);
00074         static size_t const FLAG_SWAP_8 = ((size_t) -5);
00075         static const size_t SizeOfEnum = sizeof(int);;
00076 
00077     protected:
00078         void skip(int skip_size);
00079         bool visit_ (OpaqueType const& type);
00080         bool visit_ (Numeric const& type);
00081         bool visit_ (Enum const& type);
00082         bool visit_ (Pointer const& type);
00083         bool visit_ (Array const& type);
00084         bool visit_ (Compound const& type);
00085         bool visit_ (Container const& type);
00086 
00087     public:
00088         ~CompileEndianSwapVisitor() { }
00089         void apply(Type const& type);
00090 
00091         void swap(Value in, Value out)
00092         {
00093             CompileEndianSwapVisitor::swap(0, 0,
00094                     m_compiled.begin(), m_compiled.end(),
00095                     in, out);
00096         }
00097 
00098         std::pair<size_t, std::vector<size_t>::const_iterator> 
00099             swap(size_t output_offset, size_t input_offset,
00100                 std::vector<size_t>::const_iterator it,
00101                 std::vector<size_t>::const_iterator end,
00102                 Value in, Value out);
00103 
00104         void display();
00105     };
00106 }
00107 
00108 #endif
00109 


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Thu Jan 2 2014 11:38:41