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
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
00043
00044
00045 size_t m_output_index;
00046
00047 public:
00048
00049
00050
00051
00052
00053
00054
00055
00056
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