00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef OPENMESH_SR_BINARY_SPEC_HH
00039 #define OPENMESH_SR_BINARY_SPEC_HH
00040
00041
00042
00043 #include <OpenMesh/Core/System/config.hh>
00044
00045 #include <iterator>
00046 #include <string>
00047 #if defined(OM_CC_GCC) && (OM_CC_VERSION < 30000)
00048 # include <OpenMesh/Tools/Utils/NumLimitsT.hh>
00049 #else
00050 # include <limits>
00051 #endif
00052 #include <vector>
00053 #include <stdexcept>
00054 #include <numeric>
00055
00056 #include <OpenMesh/Core/Math/VectorT.hh>
00057 #include <OpenMesh/Core/Attributes/Status.hh>
00058 #include <OpenMesh/Core/IO/SR_types.hh>
00059 #include <OpenMesh/Core/IO/SR_rbo.hh>
00060 #include <OpenMesh/Core/IO/SR_binary.hh>
00061
00062
00063
00064 namespace OpenMesh {
00065 namespace IO {
00066
00067
00068
00069
00070 #ifndef DOXY_IGNORE_THIS
00071
00072
00073
00074
00075 #define SIMPLE_BINARY( T ) \
00076 template <> struct binary< T > { \
00077 typedef T value_type; \
00078 static const bool is_streamable = true; \
00079 static size_t size_of(const value_type&) { return sizeof(value_type); } \
00080 static size_t size_of(void) { return sizeof(value_type); } \
00081 static size_t store( std::ostream& _os, const value_type& _val, \
00082 bool _swap=false) { \
00083 value_type tmp = _val; \
00084 if (_swap) reverse_byte_order(tmp); \
00085 _os.write( (const char*)&tmp, sizeof(value_type) ); \
00086 return _os.good() ? sizeof(value_type) : 0; \
00087 } \
00088 \
00089 static size_t restore( std::istream& _is, value_type& _val, \
00090 bool _swap=false) { \
00091 _is.read( (char*)&_val, sizeof(value_type) ); \
00092 if (_swap) reverse_byte_order(_val); \
00093 return _is.good() ? sizeof(value_type) : 0; \
00094 } \
00095 }
00096
00097 SIMPLE_BINARY(bool);
00098 SIMPLE_BINARY(int);
00099 SIMPLE_BINARY(unsigned int);
00100 SIMPLE_BINARY(float);
00101 SIMPLE_BINARY(double);
00102 SIMPLE_BINARY(long double);
00103
00104 SIMPLE_BINARY(int8_t);
00105 SIMPLE_BINARY(int16_t);
00106 SIMPLE_BINARY(int32_t);
00107 SIMPLE_BINARY(int64_t);
00108 SIMPLE_BINARY(uint8_t);
00109 SIMPLE_BINARY(uint16_t);
00110 SIMPLE_BINARY(uint32_t);
00111 SIMPLE_BINARY(uint64_t);
00112
00113 #undef SIMPLE_BINARY
00114
00115
00116 #define VECTORT_BINARY( T ) \
00117 template <> struct binary< T > { \
00118 typedef T value_type; \
00119 static const bool is_streamable = true; \
00120 static size_t size_of(void) { return sizeof(value_type); } \
00121 static size_t size_of(const value_type&) { return size_of(); } \
00122 static size_t store( std::ostream& _os, const value_type& _val, \
00123 bool _swap=false) { \
00124 value_type tmp = _val; \
00125 size_t i, b = size_of(_val), N = value_type::size_; \
00126 if (_swap) for (i=0; i<N; ++i) \
00127 reverse_byte_order( tmp[i] ); \
00128 _os.write( (const char*)&tmp[0], b ); \
00129 return _os.good() ? b : 0; \
00130 } \
00131 \
00132 static size_t restore( std::istream& _is, value_type& _val, \
00133 bool _swap=false) { \
00134 size_t i, N=value_type::size_; \
00135 size_t b = N * sizeof(value_type::value_type); \
00136 _is.read( (char*)&_val[0], b ); \
00137 if (_swap) for (i=0; i<N; ++i) \
00138 reverse_byte_order( _val[i] ); \
00139 return _is.good() ? b : 0; \
00140 } \
00141 }
00142
00143 #define VECTORTS_BINARY( N ) \
00144 VECTORT_BINARY( Vec##N##c ); \
00145 VECTORT_BINARY( Vec##N##uc ); \
00146 VECTORT_BINARY( Vec##N##s ); \
00147 VECTORT_BINARY( Vec##N##us ); \
00148 VECTORT_BINARY( Vec##N##i ); \
00149 VECTORT_BINARY( Vec##N##ui ); \
00150 VECTORT_BINARY( Vec##N##f ); \
00151 VECTORT_BINARY( Vec##N##d );
00152
00153 VECTORTS_BINARY( 1 );
00154 VECTORTS_BINARY( 2 );
00155 VECTORTS_BINARY( 3 );
00156 VECTORTS_BINARY( 4 );
00157 VECTORTS_BINARY( 6 );
00158
00159 #undef VECTORTS_BINARY
00160 #undef VECTORT_BINARY
00161
00162 template <> struct binary< std::string > {
00163 typedef std::string value_type;
00164 typedef uint16_t length_t;
00165
00166 static const bool is_streamable = true;
00167
00168 static size_t size_of() { return UnknownSize; }
00169 static size_t size_of(const value_type &_v)
00170 { return sizeof(length_t) + _v.size(); }
00171
00172 static
00173 size_t store(std::ostream& _os, const value_type& _v, bool _swap=false)
00174 {
00175 #if defined(OM_CC_GCC) && (OM_CC_VERSION < 30000)
00176 if (_v.size() < Utils::NumLimitsT<length_t>::max() )
00177 #else
00178 if (_v.size() < std::numeric_limits<length_t>::max() )
00179 #endif
00180 {
00181 length_t len = _v.size();
00182
00183 if (_swap) reverse_byte_order(len);
00184
00185 size_t bytes = binary<length_t>::store( _os, len, _swap );
00186 _os.write( _v.data(), len );
00187 return _os.good() ? len+bytes : 0;
00188 }
00189 throw std::runtime_error("Cannot store string longer than 64Kb");
00190 }
00191
00192 static
00193 size_t restore(std::istream& _is, value_type& _val, bool _swap=false)
00194 {
00195 length_t len;
00196 size_t bytes = binary<length_t>::restore( _is, len, _swap );
00197 if (_swap)
00198 reverse_byte_order(len);
00199 _val.resize(len);
00200 _is.read( const_cast<char*>(_val.data()), len );
00201
00202 return _is.good() ? (len+bytes) : 0;
00203 }
00204 };
00205
00206
00207 template <> struct binary<OpenMesh::Attributes::StatusInfo>
00208 {
00209 typedef OpenMesh::Attributes::StatusInfo value_type;
00210 typedef value_type::value_type status_t;
00211
00212 static const bool is_streamable = true;
00213
00214 static size_t size_of() { return sizeof(status_t); }
00215 static size_t size_of(const value_type&) { return size_of(); }
00216
00217 static size_t n_bytes(size_t _n_elem)
00218 { return _n_elem*sizeof(status_t); }
00219
00220 static
00221 size_t store(std::ostream& _os, const value_type& _v, bool _swap=false)
00222 {
00223 status_t v=_v.bits();
00224 return binary<status_t>::store(_os, v, _swap);
00225 }
00226
00227 static
00228 size_t restore( std::istream& _os, value_type& _v, bool _swap=false)
00229 {
00230 status_t v;
00231 size_t b = binary<status_t>::restore(_os, v, _swap);
00232 _v.set_bits(v);
00233 return b;
00234 }
00235 };
00236
00237
00238
00239
00240
00241 template <typename T>
00242 struct FunctorStore {
00243 FunctorStore( std::ostream& _os, bool _swap) : os_(_os), swap_(_swap) { }
00244 size_t operator () ( size_t _v1, const T& _s2 )
00245 { return _v1+binary<T>::store(os_, _s2, swap_ ); }
00246
00247 std::ostream& os_;
00248 bool swap_;
00249 };
00250
00251
00252 template <typename T>
00253 struct FunctorRestore {
00254 FunctorRestore( std::istream& _is, bool _swap) : is_(_is), swap_(_swap) { }
00255 size_t operator () ( size_t _v1, T& _s2 )
00256 { return _v1+binary<T>::restore(is_, _s2, swap_ ); }
00257 std::istream& is_;
00258 bool swap_;
00259 };
00260
00261 #include <OpenMesh/Core/IO/SR_binary_vector_of_fundamentals.inl>
00262 #include <OpenMesh/Core/IO/SR_binary_vector_of_string.inl>
00263 #include <OpenMesh/Core/IO/SR_binary_vector_of_bool.inl>
00264
00265
00266
00267 #endif // DOXY_IGNORE_THIS
00268
00269
00270 }
00271 }
00272
00273 #endif // OPENMESH_SR_BINARY_SPEC_HH defined
00274
00275