OpenMesh
|
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