xref: /haiku/src/kits/shared/Variant.cpp (revision ddac407426cd3b3d0b4589d7a161b300b3539a2a)
1 /*
2  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include <Variant.h>
7 
8 #include <stdlib.h>
9 #include <string.h>
10 
11 
12 template<typename NumberType>
13 inline NumberType
14 BVariant::_ToNumber() const
15 {
16 	switch (fType) {
17 		case B_INT8_TYPE:
18 			return (NumberType)fInt8;
19 		case B_UINT8_TYPE:
20 			return (NumberType)fUInt8;
21 		case B_INT16_TYPE:
22 			return (NumberType)fInt16;
23 		case B_UINT16_TYPE:
24 			return (NumberType)fUInt16;
25 		case B_INT32_TYPE:
26 			return (NumberType)fInt32;
27 		case B_UINT32_TYPE:
28 			return (NumberType)fUInt32;
29 		case B_INT64_TYPE:
30 			return (NumberType)fInt64;
31 		case B_UINT64_TYPE:
32 			return (NumberType)fUInt64;
33 		case B_FLOAT_TYPE:
34 			return (NumberType)fFloat;
35 		case B_DOUBLE_TYPE:
36 			return (NumberType)fDouble;
37 		default:
38 			return 0;
39 	}
40 }
41 
42 
43 BVariant::~BVariant()
44 {
45 	Unset();
46 }
47 
48 
49 void
50 BVariant::Unset()
51 {
52 	if ((fFlags & B_VARIANT_OWNS_DATA) != 0) {
53 		switch (fType) {
54 			case B_STRING_TYPE:
55 				free(fString);
56 				break;
57 			default:
58 				break;
59 		}
60 	}
61 
62 	fType = 0;
63 	fFlags = 0;
64 }
65 
66 
67 bool
68 BVariant::IsNumber() const
69 {
70 	switch (fType) {
71 		case B_INT8_TYPE:
72 		case B_UINT8_TYPE:
73 		case B_INT16_TYPE:
74 		case B_UINT16_TYPE:
75 		case B_INT32_TYPE:
76 		case B_UINT32_TYPE:
77 		case B_INT64_TYPE:
78 		case B_UINT64_TYPE:
79 		case B_FLOAT_TYPE:
80 		case B_DOUBLE_TYPE:
81 			return true;
82 		default:
83 			return false;
84 	}
85 }
86 
87 
88 bool
89 BVariant::IsInteger() const
90 {
91 	switch (fType) {
92 		case B_INT8_TYPE:
93 		case B_UINT8_TYPE:
94 		case B_INT16_TYPE:
95 		case B_UINT16_TYPE:
96 		case B_INT32_TYPE:
97 		case B_UINT32_TYPE:
98 		case B_INT64_TYPE:
99 		case B_UINT64_TYPE:
100 			return true;
101 		default:
102 			return false;
103 	}
104 }
105 
106 
107 bool
108 BVariant::IsFloat() const
109 {
110 	switch (fType) {
111 		case B_FLOAT_TYPE:
112 		case B_DOUBLE_TYPE:
113 			return true;
114 		default:
115 			return false;
116 	}
117 }
118 
119 
120 int8
121 BVariant::ToInt8() const
122 {
123 	return _ToNumber<int8>();
124 }
125 
126 
127 uint8
128 BVariant::ToUInt8() const
129 {
130 	return _ToNumber<uint8>();
131 }
132 
133 
134 int16
135 BVariant::ToInt16() const
136 {
137 	return _ToNumber<int16>();
138 }
139 
140 
141 uint16
142 BVariant::ToUInt16() const
143 {
144 	return _ToNumber<uint16>();
145 }
146 
147 
148 int32
149 BVariant::ToInt32() const
150 {
151 	return _ToNumber<int32>();
152 }
153 
154 
155 uint32
156 BVariant::ToUInt32() const
157 {
158 	return _ToNumber<uint32>();
159 }
160 
161 
162 int64
163 BVariant::ToInt64() const
164 {
165 	return _ToNumber<int64>();
166 }
167 
168 
169 uint64
170 BVariant::ToUInt64() const
171 {
172 	return _ToNumber<uint64>();
173 }
174 
175 
176 float
177 BVariant::ToFloat() const
178 {
179 	return _ToNumber<float>();
180 }
181 
182 
183 double
184 BVariant::ToDouble() const
185 {
186 	return _ToNumber<double>();
187 }
188 
189 
190 void*
191 BVariant::ToPointer() const
192 {
193 	return fType == B_POINTER_TYPE ? fString : NULL;
194 }
195 
196 
197 const char*
198 BVariant::ToString() const
199 {
200 	return fType == B_STRING_TYPE ? fString : NULL;
201 }
202 
203 
204 void
205 BVariant::_SetTo(const BVariant& other)
206 {
207 	if ((other.fFlags & B_VARIANT_OWNS_DATA) != 0) {
208 		switch (other.fType) {
209 			case B_STRING_TYPE:
210 				fType = B_STRING_TYPE;
211 				fString = strdup(other.fString);
212 				fFlags = B_VARIANT_OWNS_DATA;
213 				return;
214 			default:
215 				break;
216 		}
217 	}
218 
219 	memcpy(this, &other, sizeof(BVariant));
220 }
221 
222 
223 void
224 BVariant::_SetTo(int8 value)
225 {
226 	fType = B_INT8_TYPE;
227 	fFlags = 0;
228 	fInt8 = value;
229 }
230 
231 
232 void
233 BVariant::_SetTo(uint8 value)
234 {
235 	fType = B_UINT8_TYPE;
236 	fFlags = 0;
237 	fUInt8 = value;
238 }
239 
240 
241 void
242 BVariant::_SetTo(int16 value)
243 {
244 	fType = B_INT16_TYPE;
245 	fFlags = 0;
246 	fInt16 = value;
247 }
248 
249 
250 void
251 BVariant::_SetTo(uint16 value)
252 {
253 	fType = B_UINT16_TYPE;
254 	fFlags = 0;
255 	fUInt16 = value;
256 }
257 
258 
259 void
260 BVariant::_SetTo(int32 value)
261 {
262 	fType = B_INT32_TYPE;
263 	fFlags = 0;
264 	fInt32 = value;
265 }
266 
267 
268 void
269 BVariant::_SetTo(uint32 value)
270 {
271 	fType = B_UINT32_TYPE;
272 	fFlags = 0;
273 	fUInt32 = value;
274 }
275 
276 
277 void
278 BVariant::_SetTo(int64 value)
279 {
280 	fType = B_INT64_TYPE;
281 	fFlags = 0;
282 	fInt64 = value;
283 }
284 
285 
286 void
287 BVariant::_SetTo(uint64 value)
288 {
289 	fType = B_UINT64_TYPE;
290 	fFlags = 0;
291 	fUInt64 = value;
292 }
293 
294 
295 void
296 BVariant::_SetTo(float value)
297 {
298 	fType = B_FLOAT_TYPE;
299 	fFlags = 0;
300 	fFloat = value;
301 }
302 
303 
304 void
305 BVariant::_SetTo(double value)
306 {
307 	fType = B_DOUBLE_TYPE;
308 	fFlags = 0;
309 	fDouble = value;
310 }
311 
312 
313 void
314 BVariant::_SetTo(const void* value)
315 {
316 	fType = B_POINTER_TYPE;
317 	fFlags = 0;
318 	fPointer = (void*)value;
319 }
320 
321 
322 void
323 BVariant::_SetTo(const char* value, uint32 flags)
324 {
325 	fType = B_STRING_TYPE;
326 	fFlags = 0;
327 
328 	if (value != NULL) {
329 		if ((flags & B_VARIANT_DONT_COPY_DATA) == 0) {
330 			fString = strdup(value);
331 			fFlags |= B_VARIANT_OWNS_DATA;
332 		} else {
333 			fString = (char*)value;
334 			fFlags |= flags & B_VARIANT_OWNS_DATA;
335 		}
336 	} else
337 		fString = NULL;
338 }
339 
340