OpenMesh
OpenMesh/Core/IO/SR_rbo.hh
00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                               OpenMesh                                    *
00004  *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openmesh.org                                *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------* 
00008  *  This file is part of OpenMesh.                                           *
00009  *                                                                           *
00010  *  OpenMesh is free software: you can redistribute it and/or modify         * 
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenMesh is distributed in the hope that it will be useful,              *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenMesh.  If not,                                    *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/ 
00034 
00035 /*===========================================================================*\
00036  *                                                                           *             
00037  *   $Revision: 393 $                                                         *
00038  *   $Date: 2011-05-24 12:22:17 +0200 (Di, 24 Mai 2011) $                   *
00039  *                                                                           *
00040 \*===========================================================================*/
00041 
00042 
00043 //=============================================================================
00044 //
00045 //  Helper Functions for binary reading / writing
00046 //
00047 //=============================================================================
00048 
00049 #ifndef OPENMESH_SR_RBO_HH
00050 #define OPENMESH_SR_RBO_HH
00051 
00052 
00053 //== INCLUDES =================================================================
00054 
00055 #include <OpenMesh/Core/System/config.h>
00056 // -------------------- STL
00057 #if defined(OM_CC_MIPS)
00058 #  include <stdio.h> // size_t
00059 #else
00060 #  include <cstdio>  // size_t
00061 #endif
00062 #include <algorithm>
00063 #include <typeinfo>
00064 // -------------------- OpenMesh
00065 #include <OpenMesh/Core/System/omstream.hh>
00066 #include <OpenMesh/Core/IO/SR_types.hh>
00067 #include <OpenMesh/Core/Utils/GenProg.hh>
00068 
00069 //== NAMESPACES ===============================================================
00070 
00071 namespace OpenMesh {
00072 namespace IO {
00073 
00074 
00075 //=============================================================================
00076 
00077 
00082 
00083 
00084 //-----------------------------------------------------------------------------
00085 
00089 template < size_t N > inline
00090 void _reverse_byte_order_N(uint8_t* _val)
00091 {
00092   assert_compile(false);
00093 //   compile_time_error__only_for_fundamental_types(_val);
00094 }
00095 
00096 
00097 template <> inline
00098 void _reverse_byte_order_N<1>(uint8_t* /*_val*/) { }
00099 
00100 
00101 template <> inline
00102 void _reverse_byte_order_N<2>(uint8_t* _val)
00103 {
00104    _val[0] ^= _val[1]; _val[1] ^= _val[0]; _val[0] ^= _val[1];
00105 }
00106 
00107 
00108 template <> inline
00109 void _reverse_byte_order_N<4>(uint8_t* _val)
00110 {
00111    _val[0] ^= _val[3]; _val[3] ^= _val[0]; _val[0] ^= _val[3]; // 0 <-> 3
00112    _val[1] ^= _val[2]; _val[2] ^= _val[1]; _val[1] ^= _val[2]; // 1 <-> 2
00113 }
00114 
00115 
00116 template <> inline
00117 void _reverse_byte_order_N<8>(uint8_t* _val)
00118 {
00119    _val[0] ^= _val[7]; _val[7] ^= _val[0]; _val[0] ^= _val[7]; // 0 <-> 7
00120    _val[1] ^= _val[6]; _val[6] ^= _val[1]; _val[1] ^= _val[6]; // 1 <-> 6
00121    _val[2] ^= _val[5]; _val[5] ^= _val[2]; _val[2] ^= _val[5]; // 2 <-> 5
00122    _val[3] ^= _val[4]; _val[4] ^= _val[3]; _val[3] ^= _val[4]; // 3 <-> 4
00123 }
00124 
00125 
00126 template <> inline
00127 void _reverse_byte_order_N<12>(uint8_t* _val)
00128 {
00129    _val[0] ^= _val[11]; _val[11] ^= _val[0]; _val[0] ^= _val[11]; // 0 <-> 11
00130    _val[1] ^= _val[10]; _val[10] ^= _val[1]; _val[1] ^= _val[10]; // 1 <-> 10
00131    _val[2] ^= _val[ 9]; _val[ 9] ^= _val[2]; _val[2] ^= _val[ 9]; // 2 <->  9
00132    _val[3] ^= _val[ 8]; _val[ 8] ^= _val[3]; _val[3] ^= _val[ 8]; // 3 <->  8
00133    _val[4] ^= _val[ 7]; _val[ 7] ^= _val[4]; _val[4] ^= _val[ 7]; // 4 <->  7
00134    _val[5] ^= _val[ 6]; _val[ 6] ^= _val[5]; _val[5] ^= _val[ 6]; // 5 <->  6
00135 }
00136 
00137 
00138 template <> inline
00139 void _reverse_byte_order_N<16>(uint8_t* _val)
00140 {
00141    _reverse_byte_order_N<8>(_val);
00142    _reverse_byte_order_N<8>(_val+8);
00143    std::swap(*(uint64_t*)_val, *(((uint64_t*)_val)+1));
00144 }
00145 
00146 
00147 //-----------------------------------------------------------------------------
00148 // wrapper for byte reordering
00149 
00150 // reverting pointers makes no sense, hence forbid it.
00153 template <typename T> inline T* reverse_byte_order(T* t)
00154 {
00155   // Should never reach this point. If so, then some operator were not
00156   // overloaded. Especially check for IO::binary<> specialization on
00157   // custom data types.
00158 //   compile_time_error__cannot_do_that(a);
00159   assert_compile(false);
00160   return t;
00161 }
00162 
00163 inline void compile_time_error__no_fundamental_type()
00164 {
00165   // we should never reach this point
00166   assert(false);
00167 }
00168 
00169 // default action for byte reversal: cause an error to avoid
00170 // surprising behaviour!
00171 template <typename T> T& reverse_byte_order(  T& _t )
00172 {
00173   omerr() << "Not defined for type " << typeid(T).name() << std::endl;
00174   compile_time_error__no_fundamental_type();
00175   return _t;
00176 }
00177 
00178 template <> inline bool&  reverse_byte_order(bool & _t) { return _t; }
00179 template <> inline char&  reverse_byte_order(char & _t) { return _t; }
00180 #if defined(OM_CC_GCC)
00181 template <> inline signed char&  reverse_byte_order(signed char & _t) { return _t; }
00182 #endif
00183 template <> inline uchar& reverse_byte_order(uchar& _t) { return _t; }
00184 
00185 // Instead do specializations for the necessary types
00186 #define REVERSE_FUNDAMENTAL_TYPE( T ) \
00187   template <> inline T& reverse_byte_order( T&  _t ) {\
00188    _reverse_byte_order_N<sizeof(T)>( reinterpret_cast<uint8_t*>(&_t) ); \
00189    return _t; \
00190   }
00191 
00192 // REVERSE_FUNDAMENTAL_TYPE(bool)
00193 // REVERSE_FUNDAMENTAL_TYPE(char)
00194 // REVERSE_FUNDAMENTAL_TYPE(uchar)
00195 REVERSE_FUNDAMENTAL_TYPE(int16_t)
00196 REVERSE_FUNDAMENTAL_TYPE(uint16_t)
00197 // REVERSE_FUNDAMENTAL_TYPE(int)
00198 // REVERSE_FUNDAMENTAL_TYPE(uint)
00199 
00200 REVERSE_FUNDAMENTAL_TYPE(unsigned long)
00201 REVERSE_FUNDAMENTAL_TYPE(int32_t)
00202 REVERSE_FUNDAMENTAL_TYPE(uint32_t)
00203 REVERSE_FUNDAMENTAL_TYPE(int64_t)
00204 REVERSE_FUNDAMENTAL_TYPE(uint64_t)
00205 REVERSE_FUNDAMENTAL_TYPE(float)
00206 REVERSE_FUNDAMENTAL_TYPE(double)
00207 REVERSE_FUNDAMENTAL_TYPE(long double)
00208 
00209 #undef REVERSE_FUNDAMENTAL_TYPE
00210 
00211 #if 0
00212 
00213 #define REVERSE_VECTORT_TYPE( T ) \
00214   template <> inline T& reverse_byte_order(T& _v) {\
00215     for (size_t i; i< T::size_; ++i) \
00216       _reverse_byte_order_N< sizeof(T::value_type) >( reinterpret_cast<uint8_t*>(&_v[i])); \
00217     return _v; \
00218   }
00219 
00220 #define REVERSE_VECTORT_TYPES( N )  \
00221   REVERSE_VECTORT_TYPE( Vec##N##c )  \
00222   REVERSE_VECTORT_TYPE( Vec##N##uc ) \
00223   REVERSE_VECTORT_TYPE( Vec##N##s )  \
00224   REVERSE_VECTORT_TYPE( Vec##N##us ) \
00225   REVERSE_VECTORT_TYPE( Vec##N##i )  \
00226   REVERSE_VECTORT_TYPE( Vec##N##ui ) \
00227   REVERSE_VECTORT_TYPE( Vec##N##f )  \
00228   REVERSE_VECTORT_TYPE( Vec##N##d )  \
00229 
00230 REVERSE_VECTORT_TYPES(1)
00231 REVERSE_VECTORT_TYPES(2)
00232 REVERSE_VECTORT_TYPES(3)
00233 REVERSE_VECTORT_TYPES(4)
00234 REVERSE_VECTORT_TYPES(6)
00235 
00236 #undef REVERSE_VECTORT_TYPES
00237 #undef REVERSE_VECTORT_TYPE
00238 
00239 #endif
00240 
00241 template <typename T> inline
00242 T reverse_byte_order(const T& a)
00243 {
00244   compile_timer_error__const_means_const(a);
00245   return a;
00246 }
00247 
00248 
00250 
00251 
00252 //=============================================================================
00253 } // namespace IO
00254 } // namespace OpenMesh
00255 //=============================================================================
00256 #endif // OPENMESH_SR_RBO_HH defined
00257 //=============================================================================
00258 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines