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.
13 #include <ByteOrder.h>
17 template<typename NumberType
>
19 BVariant::_ToNumber() const
25 return (NumberType
)fInt8
;
27 return (NumberType
)fUInt8
;
29 return (NumberType
)fInt16
;
31 return (NumberType
)fUInt16
;
33 return (NumberType
)fInt32
;
35 return (NumberType
)fUInt32
;
37 return (NumberType
)fInt64
;
39 return (NumberType
)fUInt64
;
41 return (NumberType
)fFloat
;
43 return (NumberType
)fDouble
;
57 BVariant::SetToTypedData(const void* data
, type_code type
)
69 fUInt8
= *(uint8
*)data
;
72 fInt16
= *(int16
*)data
;
75 fUInt16
= *(uint16
*)data
;
78 fInt32
= *(int32
*)data
;
81 fUInt32
= *(uint32
*)data
;
84 fInt64
= *(int64
*)data
;
87 fUInt64
= *(uint64
*)data
;
90 fFloat
= *(float*)data
;
93 fDouble
= *(double*)data
;
96 fPointer
= *(void**)data
;
99 return _SetTo((const char*)data
, 0) ? B_OK
: B_NO_MEMORY
;
102 BRect
*rect
= (BRect
*)data
;
103 _SetTo(rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
118 if ((fFlags
& B_VARIANT_OWNS_DATA
) != 0) {
126 } else if ((fFlags
& B_VARIANT_REFERENCEABLE_DATA
) != 0) {
127 if (fReferenceable
!= NULL
)
128 fReferenceable
->ReleaseReference();
137 BVariant::operator==(const BVariant
& other
) const
140 return other
.fType
== 0;
141 if (other
.fType
== 0)
144 // TODO: The number comparisons are not really accurate. Particularly a
145 // conversion between signed and unsigned integers might actually change the
150 return fBool
== other
.ToBool();
155 if (!other
.IsNumber())
157 return ToInt64() == other
.ToInt64();
162 if (!other
.IsNumber())
164 return ToUInt64() == other
.ToUInt64();
167 if (!other
.IsNumber())
169 return ToDouble() == other
.ToDouble();
171 return other
.fType
== B_POINTER_TYPE
172 && fPointer
== other
.fPointer
;
174 if (other
.fType
!= B_STRING_TYPE
)
176 if (fString
== NULL
|| other
.fString
== NULL
)
177 return fString
== other
.fString
;
178 return strcmp(fString
, other
.fString
) == 0;
180 return BRect(fRect
.left
, fRect
.top
, fRect
.right
, fRect
.bottom
)
181 == BRect(other
.fRect
.left
, other
.fRect
.top
, other
.fRect
.right
,
190 BVariant::Size() const
192 if (fType
== B_STRING_TYPE
)
193 return fString
!= NULL
? strlen(fString
) + 1 : 0;
194 if ((fFlags
& B_VARIANT_REFERENCEABLE_DATA
) != 0)
195 return sizeof(this->fReferenceable
);
196 return SizeOfType(fType
);
201 BVariant::Bytes() const
203 if (fType
== B_STRING_TYPE
)
204 return (const uint8
*)fString
;
210 BVariant::ToBool() const
236 return fPointer
!= NULL
;
238 return fString
!= NULL
;
239 // TODO: We should probably check for actual values like "true",
240 // "false", "on", "off", etc.
248 BVariant::ToInt8() const
250 return _ToNumber
<int8
>();
255 BVariant::ToUInt8() const
257 return _ToNumber
<uint8
>();
262 BVariant::ToInt16() const
264 return _ToNumber
<int16
>();
269 BVariant::ToUInt16() const
271 return _ToNumber
<uint16
>();
276 BVariant::ToInt32() const
278 return _ToNumber
<int32
>();
283 BVariant::ToUInt32() const
285 return _ToNumber
<uint32
>();
290 BVariant::ToInt64() const
292 return _ToNumber
<int64
>();
297 BVariant::ToUInt64() const
299 return _ToNumber
<uint64
>();
304 BVariant::ToFloat() const
306 return _ToNumber
<float>();
311 BVariant::ToDouble() const
313 return _ToNumber
<double>();
318 BVariant::ToRect() const
320 return BRect(fRect
.left
, fRect
.top
, fRect
.right
, fRect
.bottom
);
325 BVariant::ToPointer() const
327 return fType
== B_POINTER_TYPE
? fString
: NULL
;
332 BVariant::ToString() const
334 return fType
== B_STRING_TYPE
? fString
: NULL
;
339 BVariant::_SetTo(const BVariant
& other
)
341 if ((other
.fFlags
& B_VARIANT_OWNS_DATA
) != 0) {
342 switch (other
.fType
) {
344 fType
= B_STRING_TYPE
;
345 fString
= strdup(other
.fString
);
346 fFlags
= B_VARIANT_OWNS_DATA
;
351 } else if ((other
.fFlags
& B_VARIANT_REFERENCEABLE_DATA
) != 0) {
352 if (other
.fReferenceable
!= NULL
)
353 other
.fReferenceable
->AcquireReference();
356 memcpy(this, &other
, sizeof(BVariant
));
361 BVariant::ToReferenceable() const
363 return (fFlags
& B_VARIANT_REFERENCEABLE_DATA
) != 0
364 ? fReferenceable
: NULL
;
369 BVariant::SwapEndianess()
371 if (!IsNumber() || fType
== B_POINTER_TYPE
)
374 swap_data(fType
, fBytes
, Size(), B_SWAP_ALWAYS
);
379 BVariant::AddToMessage(BMessage
& message
, const char* fieldName
) const
383 return message
.AddBool(fieldName
, fBool
);
385 return message
.AddInt8(fieldName
, fInt8
);
387 return message
.AddUInt8(fieldName
, fUInt8
);
389 return message
.AddInt16(fieldName
, fInt16
);
391 return message
.AddUInt16(fieldName
, fUInt16
);
393 return message
.AddInt32(fieldName
, fInt32
);
395 return message
.AddUInt32(fieldName
, fUInt32
);
397 return message
.AddInt64(fieldName
, fInt64
);
399 return message
.AddUInt64(fieldName
, fUInt64
);
401 return message
.AddFloat(fieldName
, fFloat
);
403 return message
.AddDouble(fieldName
, fDouble
);
405 return message
.AddPointer(fieldName
, fPointer
);
407 return message
.AddString(fieldName
, fString
);
409 return message
.AddRect(fieldName
, BRect(fRect
.left
, fRect
.top
,
410 fRect
.right
, fRect
.bottom
));
412 return B_UNSUPPORTED
;
418 BVariant::SetFromMessage(const BMessage
& message
, const char* fieldName
)
420 // get the message field info
423 status_t error
= message
.GetInfo(fieldName
, &type
, &count
);
430 error
= message
.FindData(fieldName
, type
, &data
, &numBytes
);
435 return SetToTypedData(data
, type
);
440 BVariant::SizeOfType(type_code type
)
462 return sizeof(float);
464 return sizeof(double);
466 return sizeof(void*);
468 return sizeof(BRect
);
476 BVariant::TypeIsNumber(type_code type
)
497 BVariant::TypeIsInteger(type_code type
, bool* _isSigned
)
504 if (_isSigned
!= NULL
)
511 if (_isSigned
!= NULL
)
521 BVariant::TypeIsFloat(type_code type
)
534 BVariant::_SetTo(bool value
)
543 BVariant::_SetTo(int8 value
)
552 BVariant::_SetTo(uint8 value
)
554 fType
= B_UINT8_TYPE
;
561 BVariant::_SetTo(int16 value
)
563 fType
= B_INT16_TYPE
;
570 BVariant::_SetTo(uint16 value
)
572 fType
= B_UINT16_TYPE
;
579 BVariant::_SetTo(int32 value
)
581 fType
= B_INT32_TYPE
;
588 BVariant::_SetTo(uint32 value
)
590 fType
= B_UINT32_TYPE
;
597 BVariant::_SetTo(int64 value
)
599 fType
= B_INT64_TYPE
;
606 BVariant::_SetTo(uint64 value
)
608 fType
= B_UINT64_TYPE
;
615 BVariant::_SetTo(float value
)
617 fType
= B_FLOAT_TYPE
;
624 BVariant::_SetTo(double value
)
626 fType
= B_DOUBLE_TYPE
;
633 BVariant::_SetTo(float left
, float top
, float right
, float bottom
)
640 fRect
.bottom
= bottom
;
645 BVariant::_SetTo(const void* value
)
647 fType
= B_POINTER_TYPE
;
649 fPointer
= (void*)value
;
654 BVariant::_SetTo(const char* value
, uint32 flags
)
656 fType
= B_STRING_TYPE
;
660 if ((flags
& B_VARIANT_DONT_COPY_DATA
) == 0) {
661 fString
= strdup(value
);
662 fFlags
|= B_VARIANT_OWNS_DATA
;
666 fString
= (char*)value
;
667 fFlags
|= flags
& B_VARIANT_OWNS_DATA
;
677 BVariant::_SetTo(BReferenceable
* value
, type_code type
)
680 fFlags
= B_VARIANT_REFERENCEABLE_DATA
;
681 fReferenceable
= value
;
683 if (fReferenceable
!= NULL
)
684 fReferenceable
->AcquireReference();