1 martin 1.4 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.5 //
|
3 martin 1.4 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.5 //
|
10 martin 1.4 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.5 //
|
17 martin 1.4 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.5 //
|
20 martin 1.4 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.5 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.4 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.5 //
|
28 martin 1.4 //////////////////////////////////////////////////////////////////////////
|
29 kumpf 1.2 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
|
32 mike 1.6 #include <new>
|
33 kumpf 1.2 #include <Pegasus/Common/Exception.h>
34 #include <Pegasus/Common/PegasusAssert.h>
35
36 #include "WsmValue.h"
37 #include "WsmEndpointReference.h"
38 #include "WsmInstance.h"
39
40 PEGASUS_NAMESPACE_BEGIN
41
|
42 mike 1.6 //==============================================================================
43 //
44 // WsmValueRep
45 //
46 //==============================================================================
47
48 struct WsmValueRep
49 {
50 typedef WsmEndpointReference Ref;
51 typedef Array<WsmEndpointReference> RefA;
52 typedef WsmInstance Inst;
53 typedef Array<WsmInstance> InstA;
54 typedef String Str;
55 typedef Array<String> StrA;
56
57 AtomicInt refCount;
58 WsmType type;
59 Boolean isArray;
60 Boolean isNull;
61
62 // This union makes enough space for each of the given types in raw memory.
63 mike 1.6 // WsmValue takes care or doing placement construction and destruction as
64 // needed.
65 union
66 {
67 // Be sure all types are aligned on 64-bit boundary.
68 Uint64 _alignment_;
69 char _ref_[sizeof(Ref)];
70 char _refa_[sizeof(RefA)];
71 char _inst_[sizeof(Inst)];
72 char _insta_[sizeof(InstA)];
73 char _stra_[sizeof(StrA)];
74 char _str_[sizeof(Str)];
75 char buf[1];
76 };
77
78 enum EmptyRepTag { EMPTY_REP_TAG };
|
79 kumpf 1.2
|
80 mike 1.6 WsmValueRep(EmptyRepTag) :
81 refCount(2), type(WSMTYPE_OTHER), isArray(false), isNull(true)
82 {
83 // This construction is for the empty representation. By maintaining
84 // a reference count of one, it will never fall to zero and never
85 // be deleted by _unref() below.
86 }
|
87 kumpf 1.2
|
88 mike 1.6 // Construct a null rep.
89 WsmValueRep() :
90 refCount(1), type(WSMTYPE_OTHER), isArray(false), isNull(true)
91 {
92 }
|
93 kumpf 1.2
|
94 mike 1.6 WsmValueRep(const Ref& x) :
95 refCount(1), type(WSMTYPE_REFERENCE), isArray(false), isNull(false)
96 {
97 new(buf) Ref(x);
98 }
|
99 kumpf 1.2
|
100 mike 1.6 WsmValueRep(const RefA& x) :
101 refCount(1), type(WSMTYPE_REFERENCE), isArray(true), isNull(false)
102 {
103 new(buf) RefA(x);
104 }
|
105 kumpf 1.2
|
106 mike 1.6 WsmValueRep(const Inst& x) :
107 refCount(1), type(WSMTYPE_INSTANCE), isArray(false), isNull(false)
108 {
109 new(buf) Inst(x);
110 }
|
111 kumpf 1.2
|
112 mike 1.6 WsmValueRep(const InstA& x) :
113 refCount(1), type(WSMTYPE_INSTANCE), isArray(true), isNull(false)
114 {
115 new(buf) InstA(x);
116 }
|
117 kumpf 1.2
|
118 mike 1.6 WsmValueRep(const Str& x) :
119 refCount(1), type(WSMTYPE_OTHER), isArray(false), isNull(false)
120 {
121 new(buf) Str(x);
122 }
|
123 kumpf 1.2
|
124 mike 1.6 WsmValueRep(const StrA& x) :
125 refCount(1), type(WSMTYPE_OTHER), isArray(true), isNull(false)
|
126 kumpf 1.2 {
|
127 mike 1.6 new(buf) StrA(x);
|
128 kumpf 1.2 }
129
|
130 mike 1.6 ~WsmValueRep()
131 {
132 clear();
133 }
|
134 kumpf 1.2
|
135 mike 1.6 void clear()
|
136 kumpf 1.2 {
|
137 mike 1.6 if (isNull)
138 return;
139
140 if (isArray)
|
141 kumpf 1.2 {
|
142 mike 1.6 switch (type)
|
143 kumpf 1.2 {
144 case WSMTYPE_REFERENCE:
|
145 mike 1.6 ((RefA*)buf)->~RefA();
|
146 kumpf 1.2 break;
147
148 case WSMTYPE_INSTANCE:
|
149 mike 1.6 ((InstA*)buf)->~InstA();
|
150 kumpf 1.2 break;
151
152 case WSMTYPE_OTHER:
|
153 mike 1.6 ((StrA*)buf)->~StrA();
|
154 kumpf 1.2 break;
155
156 default:
|
157 dl.meetei 1.7 PEGASUS_UNREACHABLE(PEGASUS_ASSERT(0);)
|
158 kumpf 1.2 break;
159 }
160 }
161 else
162 {
|
163 mike 1.6 switch (type)
|
164 kumpf 1.2 {
165 case WSMTYPE_REFERENCE:
|
166 mike 1.6 ((Ref*)buf)->~Ref();
|
167 kumpf 1.2 break;
168
169 case WSMTYPE_INSTANCE:
|
170 mike 1.6 ((Inst*)buf)->~Inst();
|
171 kumpf 1.2 break;
172
173 case WSMTYPE_OTHER:
|
174 mike 1.6 ((Str*)buf)->~Str();
175 break;
176
177 default:
|
178 dl.meetei 1.7 PEGASUS_UNREACHABLE(PEGASUS_ASSERT(0);)
|
179 kumpf 1.2 break;
|
180 mike 1.6 }
181 }
182
183 type = WSMTYPE_OTHER;
184 isNull = true;
185 isArray = false;
186 }
187
188 WsmValueRep* clone() const
189 {
190 if (isNull)
191 return new WsmValueRep();
|
192 kumpf 1.2
|
193 mike 1.6 if (isArray)
194 {
195 switch (type)
196 {
197 case WSMTYPE_REFERENCE:
198 return new WsmValueRep(*((RefA*)buf));
199 case WSMTYPE_INSTANCE:
200 return new WsmValueRep(*((InstA*)buf));
201 case WSMTYPE_OTHER:
202 return new WsmValueRep(*((StrA*)buf));
203 default:
|
204 dl.meetei 1.7 PEGASUS_UNREACHABLE(PEGASUS_ASSERT(0);)
|
205 mike 1.6 break;
206 }
207 }
208 else
209 {
210 switch (type)
211 {
212 case WSMTYPE_REFERENCE:
213 return new WsmValueRep(*((Ref*)buf));
214 case WSMTYPE_INSTANCE:
215 return new WsmValueRep(*((Inst*)buf));
216 case WSMTYPE_OTHER:
217 return new WsmValueRep(*((Str*)buf));
|
218 kumpf 1.2 default:
|
219 dl.meetei 1.7 PEGASUS_UNREACHABLE(PEGASUS_ASSERT(0);)
|
220 kumpf 1.2 break;
221 }
222 }
|
223 mike 1.6
224 // Unreachable!
225 return 0;
|
226 kumpf 1.2 }
227
|
228 mike 1.6 Ref& ref() { return *((Ref*)buf); }
229 const Ref& ref() const { return *((Ref*)buf); }
230
231 RefA& refa() { return *((RefA*)buf); }
232 const RefA& refa() const { return *((RefA*)buf); }
233
234 Inst& inst() { return *((Inst*)buf); }
235 const Inst& inst() const { return *((Inst*)buf); }
236
237 InstA& insta() { return *((InstA*)buf); }
238 const InstA& insta() const { return *((InstA*)buf); }
239
240 Str& str() { return *((Str*)buf); }
241 const Str& str() const { return *((Str*)buf); }
|
242 kumpf 1.2
|
243 mike 1.6 StrA& stra() { return *((StrA*)buf); }
244 const StrA& stra() const { return *((StrA*)buf); }
245 };
246
247 static WsmValueRep _emptyRep(WsmValueRep::EMPTY_REP_TAG);
248
249 inline void _ref(const WsmValueRep* rep_)
250 {
251 WsmValueRep* rep = (WsmValueRep*)rep_;
252
253 if (rep && rep != &_emptyRep)
254 rep->refCount.inc();
255 }
256
257 inline void _unref(const WsmValueRep* rep_)
258 {
259 WsmValueRep* rep = (WsmValueRep*)rep_;
260
261 if (rep && rep != &_emptyRep && rep->refCount.decAndTestIfZero())
262 delete rep;
|
263 kumpf 1.2 }
264
|
265 mike 1.6 //==============================================================================
266 //
267 // WsmValue
268 //
269 //==============================================================================
270
271 WsmValue::WsmValue() : _rep(&_emptyRep)
|
272 kumpf 1.2 {
|
273 mike 1.6 }
|
274 kumpf 1.2
|
275 mike 1.6 WsmValue::WsmValue(const WsmValue& x)
276 {
277 _ref(_rep = x._rep);
278 }
|
279 kumpf 1.2
|
280 mike 1.6 WsmValue::WsmValue(const WsmEndpointReference& x)
281 {
282 _rep = new WsmValueRep(x);
283 }
|
284 kumpf 1.2
|
285 mike 1.6 WsmValue::WsmValue(const Array<WsmEndpointReference>& x)
286 {
287 _rep = new WsmValueRep(x);
288 }
|
289 kumpf 1.3
|
290 mike 1.6 WsmValue::WsmValue(const WsmInstance& x)
291 {
292 _rep = new WsmValueRep(x);
|
293 kumpf 1.2 }
294
|
295 mike 1.6 WsmValue::WsmValue(const Array<WsmInstance>& x)
|
296 kumpf 1.2 {
|
297 mike 1.6 _rep = new WsmValueRep(x);
298 }
|
299 kumpf 1.2
|
300 mike 1.6 WsmValue::WsmValue(const String& x)
301 {
302 _rep = new WsmValueRep(x);
303 }
|
304 kumpf 1.2
|
305 mike 1.6 WsmValue::WsmValue(const Array<String>& x)
306 {
307 _rep = new WsmValueRep(x);
308 }
|
309 kumpf 1.2
|
310 mike 1.6 WsmValue::~WsmValue()
311 {
312 _unref(_rep);
313 }
|
314 kumpf 1.2
|
315 mike 1.6 WsmValue& WsmValue::operator=(const WsmValue& x)
316 {
317 if (this != &x)
318 {
319 _unref(_rep);
320 _ref(_rep = x._rep);
|
321 kumpf 1.2 }
|
322 mike 1.6
323 return *this;
324 }
325
326 Uint32 WsmValue::getArraySize()
327 {
328 if (_rep->isArray)
|
329 kumpf 1.2 {
|
330 mike 1.6 switch (_rep->type)
|
331 kumpf 1.2 {
332 case WSMTYPE_REFERENCE:
|
333 mike 1.6 return _rep->refa().size();
|
334 kumpf 1.2
335 case WSMTYPE_INSTANCE:
|
336 mike 1.6 return _rep->insta().size();
|
337 kumpf 1.2
338 case WSMTYPE_OTHER:
|
339 mike 1.6 return _rep->stra().size();
|
340 kumpf 1.2
341 default:
|
342 dl.meetei 1.7 PEGASUS_UNREACHABLE(PEGASUS_ASSERT(0);)
|
343 kumpf 1.2 }
344 }
|
345 mike 1.6
346 return 0;
|
347 kumpf 1.2 }
348
349 void WsmValue::get(WsmEndpointReference& ref) const
350 {
|
351 mike 1.6 if (_rep->type != WSMTYPE_REFERENCE || _rep->isArray)
|
352 kumpf 1.2 throw TypeMismatchException();
353
|
354 mike 1.6 if (!_rep->isNull)
355 ref = _rep->ref();
|
356 kumpf 1.2 }
357
358 void WsmValue::get(Array<WsmEndpointReference>& ref) const
359 {
|
360 mike 1.6 if (_rep->type != WSMTYPE_REFERENCE || !_rep->isArray)
|
361 kumpf 1.2 throw TypeMismatchException();
362
|
363 mike 1.6 if (!_rep->isNull)
364 ref = _rep->refa();
|
365 kumpf 1.2 }
366
367 void WsmValue::get(WsmInstance& inst) const
368 {
|
369 mike 1.6 if (_rep->type != WSMTYPE_INSTANCE || _rep->isArray)
|
370 kumpf 1.2 throw TypeMismatchException();
371
|
372 mike 1.6 if (!_rep->isNull)
373 inst = _rep->inst();
|
374 kumpf 1.2 }
375
376 void WsmValue::get(Array<WsmInstance>& inst) const
377 {
|
378 mike 1.6 if (_rep->type != WSMTYPE_INSTANCE || !_rep->isArray)
|
379 kumpf 1.2 throw TypeMismatchException();
380
|
381 mike 1.6 if (!_rep->isNull)
382 inst = _rep->insta();
|
383 kumpf 1.2 }
384
385 void WsmValue::get(String& str) const
386 {
|
387 mike 1.6 if (_rep->type != WSMTYPE_OTHER || _rep->isArray)
|
388 kumpf 1.2 throw TypeMismatchException();
389
|
390 mike 1.6 if (!_rep->isNull)
391 str = _rep->str();
|
392 kumpf 1.2 }
393
394 void WsmValue::get(Array<String>& str) const
395 {
|
396 mike 1.6 if (_rep->type != WSMTYPE_OTHER || !_rep->isArray)
|
397 kumpf 1.2 throw TypeMismatchException();
398
|
399 mike 1.6 if (!_rep->isNull)
400 str = _rep->stra();
|
401 kumpf 1.2 }
402
|
403 mike 1.6 void WsmValue::set(const WsmEndpointReference& x)
|
404 kumpf 1.2 {
|
405 mike 1.6 _unref(_rep);
406 _rep = new WsmValueRep(x);
|
407 kumpf 1.2 }
408
|
409 mike 1.6 void WsmValue::set(const Array<WsmEndpointReference>& x)
|
410 kumpf 1.2 {
|
411 mike 1.6 _unref(_rep);
412 _rep = new WsmValueRep(x);
|
413 kumpf 1.2 }
414
|
415 mike 1.6 void WsmValue::set(const WsmInstance& x)
|
416 kumpf 1.2 {
|
417 mike 1.6 _unref(_rep);
418 _rep = new WsmValueRep(x);
|
419 kumpf 1.2 }
420
|
421 mike 1.6 void WsmValue::set(const Array<WsmInstance>& x)
|
422 kumpf 1.2 {
|
423 mike 1.6 _unref(_rep);
424 _rep = new WsmValueRep(x);
|
425 kumpf 1.2 }
426
|
427 mike 1.6 void WsmValue::set(const String& x)
|
428 kumpf 1.2 {
|
429 mike 1.6 _unref(_rep);
430 _rep = new WsmValueRep(x);
|
431 kumpf 1.2 }
432
|
433 mike 1.6 void WsmValue::set(const Array<String>& x)
|
434 kumpf 1.2 {
|
435 mike 1.6 _unref(_rep);
436 _rep = new WsmValueRep(x);
|
437 kumpf 1.2 }
438
439 void WsmValue::setNull()
440 {
|
441 mike 1.6 if (_rep->refCount.get() == 1)
442 {
443 _rep->clear();
444 }
445 else
446 {
447 WsmValueRep* rep = new WsmValueRep();
448 _unref(_rep);
449 _rep = rep;
450 }
|
451 kumpf 1.2 }
452
|
453 mike 1.6 void WsmValue::add(const WsmValue& x)
|
454 kumpf 1.2 {
|
455 mike 1.6 PEGASUS_ASSERT(!x._rep->isArray);
456
457 if (x._rep->isArray)
458 return;
|
459 kumpf 1.2
|
460 mike 1.6 if (_rep->type != x._rep->type)
|
461 kumpf 1.2 throw TypeMismatchException();
462
|
463 mike 1.6 if (_rep->isArray)
|
464 kumpf 1.2 {
|
465 mike 1.6 if (_rep->refCount.get() != 1)
466 {
467 WsmValueRep* rep = _rep->clone();
468 _unref(_rep);
469 _rep = rep;
470 }
471
472 switch (_rep->type)
|
473 kumpf 1.2 {
474 case WSMTYPE_REFERENCE:
475 {
|
476 mike 1.6 _rep->refa().append(x._rep->ref());
|
477 kumpf 1.2 break;
478 }
479 case WSMTYPE_INSTANCE:
480 {
|
481 mike 1.6 _rep->insta().append(x._rep->inst());
|
482 kumpf 1.2 break;
483 }
484 case WSMTYPE_OTHER:
485 {
|
486 mike 1.6 _rep->stra().append(x._rep->str());
|
487 kumpf 1.2 break;
488 }
489 default:
490 {
|
491 dl.meetei 1.7 PEGASUS_UNREACHABLE(PEGASUS_ASSERT(0);)
|
492 kumpf 1.2 break;
493 }
494 }
495 }
496 else
497 {
|
498 mike 1.6 switch (_rep->type)
|
499 kumpf 1.2 {
500 case WSMTYPE_REFERENCE:
501 {
|
502 mike 1.6 Array<WsmEndpointReference> t;
503 t.append(_rep->ref());
504 t.append(x._rep->ref());
505 set(t);
|
506 kumpf 1.2 break;
507 }
508 case WSMTYPE_INSTANCE:
509 {
|
510 mike 1.6 Array<WsmInstance> t;
511 t.append(_rep->inst());
512 t.append(x._rep->inst());
513 set(t);
|
514 kumpf 1.2 break;
515 }
516 case WSMTYPE_OTHER:
517 {
|
518 mike 1.6 Array<String> t;
519 t.append(_rep->str());
520 t.append(x._rep->str());
521 set(t);
|
522 kumpf 1.2 break;
523 }
524 default:
525 {
|
526 dl.meetei 1.7 PEGASUS_UNREACHABLE(PEGASUS_ASSERT(0);)
|
527 kumpf 1.2 break;
528 }
529 }
530 }
531 }
532
533 void WsmValue::toArray()
534 {
|
535 mike 1.6 if (_rep->isArray)
|
536 kumpf 1.2 return;
537
|
538 mike 1.6 switch (_rep->type)
|
539 kumpf 1.2 {
540 case WSMTYPE_REFERENCE:
541 {
|
542 mike 1.6 Array<WsmEndpointReference> x;
543 x.append(_rep->ref());
544 set(x);
|
545 kumpf 1.2 break;
546 }
547 case WSMTYPE_INSTANCE:
548 {
|
549 mike 1.6 Array<WsmInstance> x;
550 x.append(_rep->inst());
551 set(x);
|
552 kumpf 1.2 break;
553 }
554 case WSMTYPE_OTHER:
555 {
|
556 mike 1.6 Array<String> x;
557 x.append(_rep->str());
558 set(x);
|
559 kumpf 1.2 break;
560 }
561 default:
562 {
|
563 dl.meetei 1.7 PEGASUS_UNREACHABLE(PEGASUS_ASSERT(0);)
|
564 kumpf 1.2 break;
565 }
566 }
567 }
568
|
569 mike 1.6 Boolean WsmValue::isArray() const
570 {
571 return _rep->isArray;
572 }
573
574 Boolean WsmValue::isNull() const
575 {
576 return _rep->isNull;
577 }
578
579 WsmType WsmValue::getType() const
580 {
581 return _rep->type;
582 }
583
|
584 kumpf 1.2 PEGASUS_NAMESPACE_END
|