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
00156 double getLowest() const;
00157
00161 static void initClass();
00162
00170 inline double normalize(double val) const;
00171
00173 friend inline std::ostream& operator << (std::ostream& os, const SbDataType type);
00174
00179 static const bool m_true;
00180
00184 SbDataType(int type) { m_type = static_cast<DataType>(type); };
00185
00186 template<typename T> static SbDataType getTemplateType (const T&);
00187
00189 typedef union
00190 {
00191 unsigned char l_uCHAR;
00192 unsigned short l_uSHORT;
00193 unsigned int l_uINT;
00194 signed char l_sCHAR;
00195 signed short l_sSHORT;
00196 signed int l_sINT;
00197 float l_FLOAT;
00198 double l_DOUBLE;
00199 } DataValue;
00200
00211 template <typename T>
00212 DataValue cast( T value ) const;
00213
00214 template <typename T>
00215 T cast( void* value) const;
00216
00217 private:
00218 typedef std::map<DataType, SbString> TypeToStrMap;
00219
00221 template<typename T> static double getMinInternal();
00222
00224 template<typename T> static double getMaxInternal();
00225
00227 template<typename T> static double getLowestInternal();
00228
00230 DataType m_type;
00231
00233 static TypeToStrMap s_typeToStrMap;
00234 static std::map<SbString, DataType> s_strToTypeMap;
00235 };
00236
00237
00238 SbDataType::DataType
00239 SbDataType::getType() const
00240 {
00241 return m_type;
00242 }
00243
00244
00245 SbDataType::operator unsigned int() const
00246 {
00247 return static_cast<unsigned int >(m_type);
00248 }
00249
00250
00251 SbBool
00252 SbDataType::isSigned() const
00253 {
00254
00255 return ( (m_type >> 2)?TRUE:FALSE );
00256 }
00257
00258
00259 unsigned int
00260 SbDataType::getSize() const
00261 {
00262 return (1 << (m_type % 4));
00263 }
00264
00265
00266 unsigned int
00267 SbDataType::getNumBits() const
00268 {
00269 return (1 << (m_type % 4)) * 8;
00270 }
00271
00272
00273 SbBool
00274 SbDataType::isInteger() const
00275 {
00276 return ( (m_type < 10)?TRUE:FALSE );
00277 }
00278
00279
00280 double
00281 SbDataType::normalize(double val) const
00282 {
00283 if ( m_type != SbDataType::FLOAT )
00284 {
00285 double minType = getMin();
00286 double maxType = getMax();
00287 val = (val-minType)/(maxType-minType);
00288
00289 if ( isSigned() )
00290 val = (val-0.5)*2.;
00291 }
00292
00293 return val;
00294 }
00295
00296
00297 template <typename T>
00298 SbDataType::DataValue
00299 SbDataType::cast( T value ) const
00300 {
00301 DataValue dataValue;
00302 switch ( m_type )
00303 {
00304 case UNSIGNED_BYTE : dataValue.l_uCHAR = (unsigned char)value; break;
00305 case UNSIGNED_SHORT: dataValue.l_uSHORT = (unsigned short)value; break;
00306 case UNSIGNED_INT32: dataValue.l_uINT = (unsigned int)value; break;
00307 case SIGNED_BYTE : dataValue.l_sCHAR = (signed char)value; break;
00308 case SIGNED_SHORT : dataValue.l_sSHORT = (signed short)value; break;
00309 case SIGNED_INT32 : dataValue.l_sINT = (signed int)value; break;
00310 case FLOAT : dataValue.l_FLOAT = (float)value; break;
00311 case DOUBLE : dataValue.l_DOUBLE = (double)value; break;
00312 default : SoDebugError::postWarning("SbDataType::cast()", "Unknown data type %d", m_type); memset(&dataValue, 0, sizeof(DataValue)); break;
00313 }
00314 return dataValue;
00315 }
00316
00317
00318 template <typename T>
00319 T
00320 SbDataType::cast( void* value ) const
00321 {
00322 switch ( m_type )
00323 {
00324 case UNSIGNED_BYTE : return (T)(*(unsigned char*)value); break;
00325 case UNSIGNED_SHORT: return (T)(*(unsigned short*)value); break;
00326 case UNSIGNED_INT32: return (T)(*(unsigned int*)value); break;
00327 case SIGNED_BYTE : return (T)(*(signed char*)value); break;
00328 case SIGNED_SHORT : return (T)(*(signed short*)value); break;
00329 case SIGNED_INT32 : return (T)(*(signed int*)value); break;
00330 case FLOAT : return (T)(*(float*)value); break;
00331 case DOUBLE : return (T)(*(double*)value); break;
00332 default : SoDebugError::postWarning("SbDataType::cast()", "Unknown data type %d", m_type); break;
00333 }
00334 return (T)0;
00335 }
00336
00337 template<>
00338 inline
00339 SbDataType
00340 SbDataType::getTemplateType (const unsigned char&)
00341 {
00342 return SbDataType(SbDataType::UNSIGNED_BYTE);
00343 }
00344
00345 template<>
00346 inline
00347 SbDataType
00348 SbDataType::getTemplateType (const unsigned short&)
00349 {
00350 return SbDataType(SbDataType::UNSIGNED_SHORT);
00351 }
00352
00353 template<>
00354 inline
00355 SbDataType
00356 SbDataType::getTemplateType (const uint32_t&)
00357 {
00358 return SbDataType(SbDataType::UNSIGNED_INT32);
00359 }
00360
00361 template<>
00362 inline
00363 SbDataType
00364 SbDataType::getTemplateType (const signed char&)
00365 {
00366 return SbDataType(SbDataType::SIGNED_BYTE );
00367 }
00368
00369 template<>
00370 inline
00371 SbDataType
00372 SbDataType::getTemplateType (const signed short&)
00373 {
00374 return SbDataType(SbDataType::SIGNED_SHORT);
00375 }
00376
00377 template<>
00378 inline
00379 SbDataType
00380 SbDataType::getTemplateType (const int&)
00381 {
00382 return SbDataType(SbDataType::SIGNED_INT32);
00383 }
00384
00385 template<>
00386 inline
00387 SbDataType
00388 SbDataType::getTemplateType (const float&)
00389 {
00390 return SbDataType(SbDataType::FLOAT);
00391 }
00392
00393 template<>
00394 inline
00395 SbDataType
00396 SbDataType::getTemplateType (const double&)
00397 {
00398 return SbDataType(SbDataType::DOUBLE);
00399 }
00400
00401 template<typename T>
00402 inline
00403 SbDataType
00404 SbDataType::getTemplateType (const T&)
00405 {
00406 return SbDataType(SbDataType::UNKNOWN);
00407 }
00408
00412 inline std::ostream& operator << (std::ostream& os, const SbDataType type)
00413 {
00414 switch ( type.m_type )
00415 {
00416 case SbDataType::UNSIGNED_BYTE:
00417 return os << "uint8";
00418 case SbDataType:: UNSIGNED_SHORT:
00419 return os << "uint16";
00420 case SbDataType:: UNSIGNED_INT32:
00421 return os << "uint32";
00422 case SbDataType:: SIGNED_BYTE:
00423 return os << "int8";
00424 case SbDataType:: SIGNED_SHORT:
00425 return os << "int16";
00426 case SbDataType:: SIGNED_INT32:
00427 return os << "int32";
00428 case SbDataType:: FLOAT:
00429 return os << "float";
00430 case SbDataType:: DOUBLE:
00431 return os << "double";
00432 default:
00433 return os << "unknown data type!";
00434 }
00435 }
00436
00437
00438 #ifdef _MSC_VER
00439 #pragma warning( pop )
00440 #endif
00441
00442 #endif // SB_DATATYPE_H
00443
00444
00445