1/* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2011, Rene Gollent, rene@gollent.com. 4 * Distributed under the terms of the MIT License. 5 */ 6#ifndef _VARIANT_H 7#define _VARIANT_H 8 9 10#include <Rect.h> 11#include <SupportDefs.h> 12#include <TypeConstants.h> 13 14#include <Referenceable.h> 15 16 17enum { 18 B_VARIANT_DONT_COPY_DATA = 0x01, 19 B_VARIANT_OWNS_DATA = 0x02, 20 B_VARIANT_REFERENCEABLE_DATA = 0x04 21}; 22 23 24class BMessage; 25 26 27class BVariant { 28public: 29 inline BVariant(); 30 inline BVariant(bool value); 31 inline BVariant(int8 value); 32 inline BVariant(uint8 value); 33 inline BVariant(int16 value); 34 inline BVariant(uint16 value); 35 inline BVariant(int32 value); 36 inline BVariant(uint32 value); 37 inline BVariant(int64 value); 38 inline BVariant(uint64 value); 39 inline BVariant(float value); 40 inline BVariant(double value); 41 inline BVariant(const BRect &value); 42 inline BVariant(float left, float top, float right, 43 float bottom); 44 inline BVariant(const void* value); 45 inline BVariant(const char* value, 46 uint32 flags = 0); 47 inline BVariant(BReferenceable* value, type_code type); 48 // type must be a custom type 49 inline BVariant(const BVariant& other); 50 ~BVariant(); 51 52 inline void SetTo(const BVariant& other); 53 inline void SetTo(bool value); 54 inline void SetTo(int8 value); 55 inline void SetTo(uint8 value); 56 inline void SetTo(int16 value); 57 inline void SetTo(uint16 value); 58 inline void SetTo(int32 value); 59 inline void SetTo(uint32 value); 60 inline void SetTo(int64 value); 61 inline void SetTo(uint64 value); 62 inline void SetTo(float value); 63 inline void SetTo(double value); 64 inline void SetTo(const BRect& value); 65 inline void SetTo(float left, float top, float right, 66 float bottom); 67 inline void SetTo(const void* value); 68 inline void SetTo(const char* value, 69 uint32 flags = 0); 70 inline void SetTo(BReferenceable* value, type_code type); 71 // type must be a custom type 72 status_t SetToTypedData(const void* data, 73 type_code type); 74 void Unset(); 75 76 inline BVariant& operator=(const BVariant& other); 77 78 bool operator==(const BVariant& other) const; 79 inline bool operator!=(const BVariant& other) const; 80 81 inline type_code Type() const { return fType; } 82 size_t Size() const; 83 const uint8* Bytes() const; 84 85 inline bool IsNumber() const; 86 inline bool IsInteger(bool* _isSigned = NULL) const; 87 inline bool IsFloat() const; 88 // floating point, not just float 89 90 bool ToBool() const; 91 int8 ToInt8() const; 92 uint8 ToUInt8() const; 93 int16 ToInt16() const; 94 uint16 ToUInt16() const; 95 int32 ToInt32() const; 96 uint32 ToUInt32() const; 97 int64 ToInt64() const; 98 uint64 ToUInt64() const; 99 float ToFloat() const; 100 double ToDouble() const; 101 void* ToPointer() const; 102 const char* ToString() const; 103 BRect ToRect() const; 104 BReferenceable* ToReferenceable() const; 105 106 void SwapEndianess(); 107 // has effect only on scalar types (pointer 108 // counting as scalar, not string, though) 109 110 status_t AddToMessage(BMessage& message, 111 const char* fieldName) const; 112 status_t SetFromMessage(const BMessage& message, 113 const char* fieldName); 114 115 static size_t SizeOfType(type_code type); 116 static bool TypeIsNumber(type_code type); 117 static bool TypeIsInteger(type_code type, 118 bool* _isSigned = NULL); 119 static bool TypeIsFloat(type_code type); 120 121private: 122 void _SetTo(const BVariant& other); 123 void _SetTo(bool value); 124 void _SetTo(int8 value); 125 void _SetTo(uint8 value); 126 void _SetTo(int16 value); 127 void _SetTo(uint16 value); 128 void _SetTo(int32 value); 129 void _SetTo(uint32 value); 130 void _SetTo(int64 value); 131 void _SetTo(uint64 value); 132 void _SetTo(float value); 133 void _SetTo(double value); 134 void _SetTo(const void* value); 135 void _SetTo(float left, float top, float right, 136 float bottom); 137 bool _SetTo(const char* value, 138 uint32 flags); 139 void _SetTo(BReferenceable* value, type_code type); 140 141 template<typename NumberType> 142 inline NumberType _ToNumber() const; 143 144private: 145 type_code fType; 146 uint32 fFlags; 147 union { 148 bool fBool; 149 int8 fInt8; 150 uint8 fUInt8; 151 int16 fInt16; 152 uint16 fUInt16; 153 int32 fInt32; 154 uint32 fUInt32; 155 int64 fInt64; 156 uint64 fUInt64; 157 float fFloat; 158 double fDouble; 159 void* fPointer; 160 char* fString; 161 BReferenceable* fReferenceable; 162 struct { 163 float left; 164 float top; 165 float right; 166 float bottom; 167 } fRect; 168 uint8 fBytes[sizeof(float) * 4]; 169 }; 170}; 171 172 173BVariant::BVariant() 174 : 175 fType(0), 176 fFlags(0) 177{ 178} 179 180 181BVariant::BVariant(bool value) 182{ 183 _SetTo(value); 184} 185 186 187BVariant::BVariant(int8 value) 188{ 189 _SetTo(value); 190} 191 192 193BVariant::BVariant(uint8 value) 194{ 195 _SetTo(value); 196} 197 198 199BVariant::BVariant(int16 value) 200{ 201 _SetTo(value); 202} 203 204 205BVariant::BVariant(uint16 value) 206{ 207 _SetTo(value); 208} 209 210 211BVariant::BVariant(int32 value) 212{ 213 _SetTo(value); 214} 215 216 217BVariant::BVariant(uint32 value) 218{ 219 _SetTo(value); 220} 221 222 223BVariant::BVariant(int64 value) 224{ 225 _SetTo(value); 226} 227 228 229BVariant::BVariant(uint64 value) 230{ 231 _SetTo(value); 232} 233 234 235BVariant::BVariant(float value) 236{ 237 _SetTo(value); 238} 239 240 241BVariant::BVariant(double value) 242{ 243 _SetTo(value); 244} 245 246 247BVariant::BVariant(const BRect& value) 248{ 249 _SetTo(value.left, value.top, value.right, value.bottom); 250} 251 252 253BVariant::BVariant(float left, float top, float right, float bottom) 254{ 255 _SetTo(left, top, right, bottom); 256} 257 258 259BVariant::BVariant(const void* value) 260{ 261 _SetTo(value); 262} 263 264 265BVariant::BVariant(const char* value, uint32 flags) 266{ 267 _SetTo(value, flags); 268} 269 270 271BVariant::BVariant(BReferenceable* value, type_code type) 272{ 273 _SetTo(value, type); 274} 275 276 277BVariant::BVariant(const BVariant& other) 278{ 279 _SetTo(other); 280} 281 282 283BVariant& 284BVariant::operator=(const BVariant& other) 285{ 286 Unset(); 287 _SetTo(other); 288 return *this; 289} 290 291 292bool 293BVariant::operator!=(const BVariant& other) const 294{ 295 return !(*this == other); 296} 297 298 299void 300BVariant::SetTo(const BVariant& other) 301{ 302 Unset(); 303 _SetTo(other); 304} 305 306 307void 308BVariant::SetTo(bool value) 309{ 310 Unset(); 311 _SetTo(value); 312} 313 314 315void 316BVariant::SetTo(int8 value) 317{ 318 Unset(); 319 _SetTo(value); 320} 321 322 323void 324BVariant::SetTo(uint8 value) 325{ 326 Unset(); 327 _SetTo(value); 328} 329 330 331void 332BVariant::SetTo(int16 value) 333{ 334 Unset(); 335 _SetTo(value); 336} 337 338 339void 340BVariant::SetTo(uint16 value) 341{ 342 Unset(); 343 _SetTo(value); 344} 345 346 347void 348BVariant::SetTo(int32 value) 349{ 350 Unset(); 351 _SetTo(value); 352} 353 354 355void 356BVariant::SetTo(uint32 value) 357{ 358 Unset(); 359 _SetTo(value); 360} 361 362 363void 364BVariant::SetTo(int64 value) 365{ 366 Unset(); 367 _SetTo(value); 368} 369 370 371void 372BVariant::SetTo(uint64 value) 373{ 374 Unset(); 375 _SetTo(value); 376} 377 378 379void 380BVariant::SetTo(float value) 381{ 382 Unset(); 383 _SetTo(value); 384} 385 386 387void 388BVariant::SetTo(double value) 389{ 390 Unset(); 391 _SetTo(value); 392} 393 394 395void 396BVariant::SetTo(const BRect& value) 397{ 398 Unset(); 399 _SetTo(value.left, value.top, value.right, value.bottom); 400} 401 402 403void 404BVariant::SetTo(float left, float top, float right, float bottom) 405{ 406 Unset(); 407 _SetTo(left, top, right, bottom); 408} 409 410 411void 412BVariant::SetTo(const void* value) 413{ 414 Unset(); 415 _SetTo(value); 416} 417 418 419void 420BVariant::SetTo(const char* value, uint32 flags) 421{ 422 Unset(); 423 _SetTo(value, flags); 424} 425 426 427void 428BVariant::SetTo(BReferenceable* value, type_code type) 429{ 430 Unset(); 431 _SetTo(value, type); 432} 433 434 435bool 436BVariant::IsNumber() const 437{ 438 return TypeIsNumber(fType); 439} 440 441 442bool 443BVariant::IsInteger(bool* _isSigned) const 444{ 445 return TypeIsInteger(fType, _isSigned); 446} 447 448 449bool 450BVariant::IsFloat() const 451{ 452 return TypeIsFloat(fType); 453} 454 455 456#endif // _VARIANT_H 457