00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef SB_DATATYPE_H
00024 #define SB_DATATYPE_H
00025
00026 #include <Inventor/STL/map>
00027
00028 #include <Inventor/SbBase.h>
00029 #include <Inventor/SbString.h>
00030 #include <Inventor/sys/port.h>
00031 #include <Inventor/STL/limits>
00032 #include <Inventor/errors/SoDebugError.h>
00033
00034 #ifdef _MSC_VER
00035 #pragma warning( push )
00036 #pragma warning(disable:4251)
00037 #endif
00038
00057 class SbDataType
00058 {
00059 public:
00063 enum DataType
00064 {
00066 UNSIGNED_BYTE = 0,
00068 UNSIGNED_SHORT = 1,
00070 UNSIGNED_INT32 = 2,
00072 SIGNED_BYTE = 4,
00074 SIGNED_SHORT = 5,
00076 SIGNED_INT32 = 6,
00078 FLOAT = 10,
00080 DOUBLE = 11,
00082 UNKNOWN = 0xFFFF
00083 };
00084
00088 explicit SbDataType(DataType type) : m_type(type) {}
00089
00094 SbDataType(const SbString& type);
00095
00099 SbDataType() : m_type(UNSIGNED_BYTE) {}
00100
00101
00102
00103
00104
00105 inline operator unsigned int() const;
00106
00111 inline DataType getType() const;
00112
00116 inline unsigned int getSize() const;
00117
00121 inline SbBool isSigned() const;
00122
00126 inline SbBool isInteger() const;
00127
00131 inline unsigned int getNumBits() const;
00132
00137 SbString getString() const;
00138
00143 double getMin() const;
00144
00148 double getMax() const;
00149
00150 private:
00151
00152
00153
00154
00155
00156 double getLowest() const;
00157
00161 static void initClass();
00162
00170 inline double normalize(double val) const;
00171
00176 static const bool m_true;
00177
00181 SbDataType(int type) { m_type = static_cast<DataType>(type); };
00182
00183 template<typename T> static SbDataType getTemplateType (const T&);
00184
00186 typedef union
00187 {
00188 unsigned char l_uCHAR;
00189 unsigned short l_uSHORT;
00190 unsigned int l_uINT;
00191 signed char l_sCHAR;
00192 signed short l_sSHORT;
00193 signed int l_sINT;
00194 float l_FLOAT;
00195 double l_DOUBLE;
00196 } DataValue;
00197
00208 template <typename T>
00209 DataValue cast( T value ) const;
00210
00211 template <typename T>
00212 T cast( void* value) const;
00213
00214 private:
00215 typedef std::map<DataType, SbString> TypeToStrMap;
00216
00218 template<typename T> static double getMinInternal();
00219
00221 template<typename T> static double getMaxInternal();
00222
00224 template<typename T> static double getLowestInternal();
00225
00227 DataType m_type;
00228
00230 static TypeToStrMap s_typeToStrMap;
00231 static std::map<SbString, DataType> s_strToTypeMap;
00232 };
00233
00234
00235 SbDataType::DataType
00236 SbDataType::getType() const
00237 {
00238 return m_type;
00239 }
00240
00241
00242 SbDataType::operator unsigned int() const
00243 {
00244 return static_cast<unsigned int >(m_type);
00245 }
00246
00247
00248 SbBool
00249 SbDataType::isSigned() const
00250 {
00251
00252 return ( (m_type >> 2)?TRUE:FALSE );
00253 }
00254
00255
00256 unsigned int
00257 SbDataType::getSize() const
00258 {
00259 return (1 << (m_type % 4));
00260 }
00261
00262
00263 unsigned int
00264 SbDataType::getNumBits() const
00265 {
00266 return (1 << (m_type % 4)) * 8;
00267 }
00268
00269
00270 SbBool
00271 SbDataType::isInteger() const
00272 {
00273 return ( (m_type < 10)?TRUE:FALSE );
00274 }
00275
00276
00277 double
00278 SbDataType::normalize(double val) const
00279 {
00280 if ( m_type != SbDataType::FLOAT )
00281 {
00282 double minType = getMin();
00283 double maxType = getMax();
00284 val = (val-minType)/(maxType-minType);
00285
00286 if ( isSigned() )
00287 val = (val-0.5)*2.;
00288 }
00289
00290 return val;
00291 }
00292
00293
00294 template <typename T>
00295 SbDataType::DataValue
00296 SbDataType::cast( T value ) const
00297 {
00298 DataValue dataValue;
00299 switch ( m_type )
00300 {
00301 case UNSIGNED_BYTE : dataValue.l_uCHAR = (unsigned char)value; break;
00302 case UNSIGNED_SHORT: dataValue.l_uSHORT = (unsigned short)value; break;
00303 case UNSIGNED_INT32: dataValue.l_uINT = (unsigned int)value; break;
00304 case SIGNED_BYTE : dataValue.l_sCHAR = (signed char)value; break;
00305 case SIGNED_SHORT : dataValue.l_sSHORT = (signed short)value; break;
00306 case SIGNED_INT32 : dataValue.l_sINT = (signed int)value; break;
00307 case FLOAT : dataValue.l_FLOAT = (float)value; break;
00308 case DOUBLE : dataValue.l_DOUBLE = (double)value; break;
00309 default : SoDebugError::postWarning("SbDataType::cast()", "Unknown data type %d", m_type); memset(&dataValue, 0, sizeof(DataValue)); break;
00310 }
00311 return dataValue;
00312 }
00313
00314
00315 template <typename T>
00316 T
00317 SbDataType::cast( void* value ) const
00318 {
00319 switch ( m_type )
00320 {
00321 case UNSIGNED_BYTE : return (T)(*(unsigned char*)value); break;
00322 case UNSIGNED_SHORT: return (T)(*(unsigned short*)value); break;
00323 case UNSIGNED_INT32: return (T)(*(unsigned int*)value); break;
00324 case SIGNED_BYTE : return (T)(*(signed char*)value); break;
00325 case SIGNED_SHORT : return (T)(*(signed short*)value); break;
00326 case SIGNED_INT32 : return (T)(*(signed int*)value); break;
00327 case FLOAT : return (T)(*(float*)value); break;
00328 case DOUBLE : return (T)(*(double*)value); break;
00329 default : SoDebugError::postWarning("SbDataType::cast()", "Unknown data type %d", m_type); break;
00330 }
00331 return (T)0;
00332 }
00333
00334 template<>
00335 inline
00336 SbDataType
00337 SbDataType::getTemplateType (const unsigned char&)
00338 {
00339 return SbDataType(SbDataType::UNSIGNED_BYTE);
00340 }
00341
00342 template<>
00343 inline
00344 SbDataType
00345 SbDataType::getTemplateType (const unsigned short&)
00346 {
00347 return SbDataType(SbDataType::UNSIGNED_SHORT);
00348 }
00349
00350 template<>
00351 inline
00352 SbDataType
00353 SbDataType::getTemplateType (const uint32_t&)
00354 {
00355 return SbDataType(SbDataType::UNSIGNED_INT32);
00356 }
00357
00358 template<>
00359 inline
00360 SbDataType
00361 SbDataType::getTemplateType (const signed char&)
00362 {
00363 return SbDataType(SbDataType::SIGNED_BYTE );
00364 }
00365
00366 template<>
00367 inline
00368 SbDataType
00369 SbDataType::getTemplateType (const signed short&)
00370 {
00371 return SbDataType(SbDataType::SIGNED_SHORT);
00372 }
00373
00374 template<>
00375 inline
00376 SbDataType
00377 SbDataType::getTemplateType (const int&)
00378 {
00379 return SbDataType(SbDataType::SIGNED_INT32);
00380 }
00381
00382 template<>
00383 inline
00384 SbDataType
00385 SbDataType::getTemplateType (const float&)
00386 {
00387 return SbDataType(SbDataType::FLOAT);
00388 }
00389
00390 template<>
00391 inline
00392 SbDataType
00393 SbDataType::getTemplateType (const double&)
00394 {
00395 return SbDataType(SbDataType::DOUBLE);
00396 }
00397
00398 template<typename T>
00399 inline
00400 SbDataType
00401 SbDataType::getTemplateType (const T&)
00402 {
00403 return SbDataType(SbDataType::UNKNOWN);
00404 }
00405
00406
00407
00408 #ifdef _MSC_VER
00409 #pragma warning( pop )
00410 #endif
00411
00412 #endif // SB_DATATYPE_H
00413
00414
00415