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_BINARY_SPEC_HH 00050 #define OPENMESH_SR_BINARY_SPEC_HH 00051 00052 //== INCLUDES ================================================================= 00053 00054 #include <OpenMesh/Core/System/config.h> 00055 // -------------------- STL 00056 #include <iterator> 00057 #include <string> 00058 #if defined(OM_CC_GCC) && (OM_CC_VERSION < 30000) 00059 # include <OpenMesh/Tools/Utils/NumLimitsT.hh> 00060 #else 00061 # include <limits> 00062 #endif 00063 #include <vector> 00064 #include <stdexcept> // logic_error 00065 #include <numeric> // accumulate 00066 // -------------------- OpenMesh 00067 #include <OpenMesh/Core/Geometry/VectorT.hh> 00068 #include <OpenMesh/Core/Mesh/Status.hh> 00069 #include <OpenMesh/Core/IO/SR_types.hh> 00070 #include <OpenMesh/Core/IO/SR_rbo.hh> 00071 #include <OpenMesh/Core/IO/SR_binary.hh> 00072 00073 //== NAMESPACES =============================================================== 00074 00075 namespace OpenMesh { 00076 namespace IO { 00077 00078 00079 //============================================================================= 00080 00081 #ifndef DOXY_IGNORE_THIS 00082 00083 //----------------------------------------------------------------------------- 00084 // struct binary, helper for storing/restoring 00085 00086 #define SIMPLE_BINARY( T ) \ 00087 template <> struct binary< T > { \ 00088 typedef T value_type; \ 00089 static const bool is_streamable = true; \ 00090 static size_t size_of(const value_type&) { return sizeof(value_type); } \ 00091 static size_t size_of(void) { return sizeof(value_type); } \ 00092 static size_t store( std::ostream& _os, const value_type& _val, \ 00093 bool _swap=false) { \ 00094 value_type tmp = _val; \ 00095 if (_swap) reverse_byte_order(tmp); \ 00096 _os.write( (const char*)&tmp, sizeof(value_type) ); \ 00097 return _os.good() ? sizeof(value_type) : 0; \ 00098 } \ 00099 \ 00100 static size_t restore( std::istream& _is, value_type& _val, \ 00101 bool _swap=false) { \ 00102 _is.read( (char*)&_val, sizeof(value_type) ); \ 00103 if (_swap) reverse_byte_order(_val); \ 00104 return _is.good() ? sizeof(value_type) : 0; \ 00105 } \ 00106 } 00107 00108 SIMPLE_BINARY(bool); 00109 //SIMPLE_BINARY(int); 00110 00111 // Why is this needed? Should not be used as not 32 bit compatible 00112 //SIMPLE_BINARY(unsigned long); 00113 SIMPLE_BINARY(float); 00114 SIMPLE_BINARY(double); 00115 SIMPLE_BINARY(long double); 00116 00117 SIMPLE_BINARY(int8_t); 00118 SIMPLE_BINARY(int16_t); 00119 SIMPLE_BINARY(int32_t); 00120 SIMPLE_BINARY(int64_t); 00121 SIMPLE_BINARY(uint8_t); 00122 SIMPLE_BINARY(uint16_t); 00123 SIMPLE_BINARY(uint32_t); 00124 SIMPLE_BINARY(uint64_t); 00125 00126 #undef SIMPLE_BINARY 00127 00128 // For unsigned long which is of size 64 bit on 64 bit 00129 // architectures: convert into 32 bit unsigned integer value 00130 // in order to stay compatible between 32/64 bit architectures. 00131 // This allows cross reading BUT forbids storing unsigned longs 00132 // as data type since higher order word (4 bytes) will be truncated. 00133 // Does not work in case the data type that is to be stored 00134 // exceeds the value range of unsigned int in size, which is improbable... 00135 00136 #define SIMPLE_BINARY( T ) \ 00137 template <> struct binary< T > { \ 00138 typedef T value_type; \ 00139 static const bool is_streamable = true; \ 00140 static size_t size_of(const value_type&) { return sizeof(value_type); } \ 00141 static size_t size_of(void) { return sizeof(value_type); } \ 00142 static size_t store( std::ostream& _os, const value_type& _val, \ 00143 bool _swap=false) { \ 00144 value_type tmp = _val; \ 00145 if (_swap) reverse_byte_order(tmp); \ 00146 /* Convert unsigned long to unsigned int for compatibility reasons */ \ 00147 unsigned int t1 = static_cast<unsigned int>(tmp); \ 00148 _os.write( (const char*)&t1, sizeof(unsigned int) ); \ 00149 return _os.good() ? sizeof(unsigned int) : 0; \ 00150 } \ 00151 \ 00152 static size_t restore( std::istream& _is, value_type& _val, \ 00153 bool _swap=false) { \ 00154 unsigned int t1; \ 00155 _is.read( (char*)&t1, sizeof(unsigned int) ); \ 00156 _val = t1; \ 00157 if (_swap) reverse_byte_order(_val); \ 00158 return _is.good() ? sizeof(unsigned int) : 0; \ 00159 } \ 00160 } 00161 00162 SIMPLE_BINARY(unsigned long); 00163 00164 #undef SIMPLE_BINARY 00165 00166 #define VECTORT_BINARY( T ) \ 00167 template <> struct binary< T > { \ 00168 typedef T value_type; \ 00169 static const bool is_streamable = true; \ 00170 static size_t size_of(void) { return sizeof(value_type); } \ 00171 static size_t size_of(const value_type&) { return size_of(); } \ 00172 static size_t store( std::ostream& _os, const value_type& _val, \ 00173 bool _swap=false) { \ 00174 value_type tmp = _val; \ 00175 size_t i, b = size_of(_val), N = value_type::size_; \ 00176 if (_swap) for (i=0; i<N; ++i) \ 00177 reverse_byte_order( tmp[i] ); \ 00178 _os.write( (const char*)&tmp[0], b ); \ 00179 return _os.good() ? b : 0; \ 00180 } \ 00181 \ 00182 static size_t restore( std::istream& _is, value_type& _val, \ 00183 bool _swap=false) { \ 00184 size_t i, N=value_type::size_; \ 00185 size_t b = N * sizeof(value_type::value_type); \ 00186 _is.read( (char*)&_val[0], b ); \ 00187 if (_swap) for (i=0; i<N; ++i) \ 00188 reverse_byte_order( _val[i] ); \ 00189 return _is.good() ? b : 0; \ 00190 } \ 00191 } 00192 00193 #define VECTORTS_BINARY( N ) \ 00194 VECTORT_BINARY( Vec##N##c ); \ 00195 VECTORT_BINARY( Vec##N##uc ); \ 00196 VECTORT_BINARY( Vec##N##s ); \ 00197 VECTORT_BINARY( Vec##N##us ); \ 00198 VECTORT_BINARY( Vec##N##i ); \ 00199 VECTORT_BINARY( Vec##N##ui ); \ 00200 VECTORT_BINARY( Vec##N##f ); \ 00201 VECTORT_BINARY( Vec##N##d ); 00202 00203 VECTORTS_BINARY( 1 ) 00204 VECTORTS_BINARY( 2 ) 00205 VECTORTS_BINARY( 3 ) 00206 VECTORTS_BINARY( 4 ) 00207 VECTORTS_BINARY( 6 ) 00208 00209 #undef VECTORTS_BINARY 00210 #undef VECTORT_BINARY 00211 00212 template <> struct binary< std::string > { 00213 typedef std::string value_type; 00214 typedef uint16_t length_t; 00215 00216 static const bool is_streamable = true; 00217 00218 static size_t size_of() { return UnknownSize; } 00219 static size_t size_of(const value_type &_v) 00220 { return sizeof(length_t) + _v.size(); } 00221 00222 static 00223 size_t store(std::ostream& _os, const value_type& _v, bool _swap=false) 00224 { 00225 #if defined(OM_CC_GCC) && (OM_CC_VERSION < 30000) 00226 if (_v.size() < Utils::NumLimitsT<length_t>::max() ) 00227 #else 00228 if (_v.size() < std::numeric_limits<length_t>::max() ) 00229 #endif 00230 { 00231 length_t len = _v.size(); 00232 00233 if (_swap) reverse_byte_order(len); 00234 00235 size_t bytes = binary<length_t>::store( _os, len, _swap ); 00236 _os.write( _v.data(), len ); 00237 return _os.good() ? len+bytes : 0; 00238 } 00239 throw std::runtime_error("Cannot store string longer than 64Kb"); 00240 } 00241 00242 static 00243 size_t restore(std::istream& _is, value_type& _val, bool _swap=false) 00244 { 00245 length_t len; 00246 size_t bytes = binary<length_t>::restore( _is, len, _swap ); 00247 if (_swap) 00248 reverse_byte_order(len); 00249 _val.resize(len); 00250 _is.read( const_cast<char*>(_val.data()), len ); 00251 00252 return _is.good() ? (len+bytes) : 0; 00253 } 00254 }; 00255 00256 00257 template <> struct binary<OpenMesh::Attributes::StatusInfo> 00258 { 00259 typedef OpenMesh::Attributes::StatusInfo value_type; 00260 typedef value_type::value_type status_t; 00261 00262 static const bool is_streamable = true; 00263 00264 static size_t size_of() { return sizeof(status_t); } 00265 static size_t size_of(const value_type&) { return size_of(); } 00266 00267 static size_t n_bytes(size_t _n_elem) 00268 { return _n_elem*sizeof(status_t); } 00269 00270 static 00271 size_t store(std::ostream& _os, const value_type& _v, bool _swap=false) 00272 { 00273 status_t v=_v.bits(); 00274 return binary<status_t>::store(_os, v, _swap); 00275 } 00276 00277 static 00278 size_t restore( std::istream& _os, value_type& _v, bool _swap=false) 00279 { 00280 status_t v; 00281 size_t b = binary<status_t>::restore(_os, v, _swap); 00282 _v.set_bits(v); 00283 return b; 00284 } 00285 }; 00286 00287 00288 //----------------------------------------------------------------------------- 00289 // std::vector<T> specializations for struct binary<> 00290 00291 template <typename T> 00292 struct FunctorStore { 00293 FunctorStore( std::ostream& _os, bool _swap) : os_(_os), swap_(_swap) { } 00294 size_t operator () ( size_t _v1, const T& _s2 ) 00295 { return _v1+binary<T>::store(os_, _s2, swap_ ); } 00296 00297 std::ostream& os_; 00298 bool swap_; 00299 }; 00300 00301 00302 template <typename T> 00303 struct FunctorRestore { 00304 FunctorRestore( std::istream& _is, bool _swap) : is_(_is), swap_(_swap) { } 00305 size_t operator () ( size_t _v1, T& _s2 ) 00306 { return _v1+binary<T>::restore(is_, _s2, swap_ ); } 00307 std::istream& is_; 00308 bool swap_; 00309 }; 00310 00311 #include <OpenMesh/Core/IO/SR_binary_vector_of_fundamentals.inl> 00312 #include <OpenMesh/Core/IO/SR_binary_vector_of_string.inl> 00313 #include <OpenMesh/Core/IO/SR_binary_vector_of_bool.inl> 00314 00315 // ---------------------------------------------------------------------------- 00316 00317 #endif // DOXY_IGNORE_THIS 00318 00319 //============================================================================= 00320 } // namespace IO 00321 } // namespace OpenMesh 00322 //============================================================================= 00323 #endif // OPENMESH_SR_BINARY_SPEC_HH defined 00324 //============================================================================= 00325