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