(file) Return to WsmValue.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / WsmServer

  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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2