1 thilo.boehm 1.2 //%LICENSE////////////////////////////////////////////////////////////////
2 //
3 // 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 //
10 // 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 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 thilo.boehm 1.2 // 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 //
28 //////////////////////////////////////////////////////////////////////////
29 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include <Pegasus/Common/Config.h>
33 #include <cstdlib>
34 #include <cstdio>
35 #include <Pegasus/Common/SCMOStreamer.h>
36 #include <Pegasus/Common/ArrayIterator.h>
37 #include <Pegasus/Common/Tracer.h>
38
39 PEGASUS_USING_STD;
40
41 PEGASUS_NAMESPACE_BEGIN
42
43 thilo.boehm 1.2
44 #define PEGASUS_ARRAY_T SCMOResolutionTable
45 # include <Pegasus/Common/ArrayImpl.h>
46 #undef PEGASUS_ARRAY_T
47
48 SCMOStreamer::SCMOStreamer(CIMBuffer& out, Array<SCMOInstance>& x) :
49 _buf(out),
50 _scmoInstances(x),
51 _ttlNumInstances(0),
52 _ttlNumClasses(0)
53 {
54 };
55
56 // Writes a single SCMOClass to the given CIMBuffer
57 void SCMOStreamer::serializeClass(CIMBuffer& out, const SCMOClass& scmoClass)
58 {
59 PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::serializeClass");
60
61 Array<SCMBClass_Main*> classTable;
62 classTable.append(scmoClass.cls.hdr);
63
64 thilo.boehm 1.2 _putClasses(out, classTable);
65
66 PEG_METHOD_EXIT();
67 };
68
69 // Reads a single SCMOClass from the given CIMBuffer
70 bool SCMOStreamer::deserializeClass(CIMBuffer& in, SCMOClass& scmoClass)
71 {
72 PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::deserializeClass");
73
74 Array<SCMBClass_Main*> classTable;
75 if(!_getClasses(in, classTable))
76 {
77 PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
78 "Failed to get Class!");
79 PEG_METHOD_EXIT();
80 return false;
81 }
82
83 if (classTable.size() > 0)
84 {
85 thilo.boehm 1.2 scmoClass = SCMOClass(classTable[0]);
86 }
87
88 PEG_METHOD_EXIT();
89 return true;
90 };
91
92 // Writes the list of SCMOInstances stored in this instance of SCMOStreamer
93 // to the output buffer, including their referenced Classes and Instances
94 void SCMOStreamer::serialize()
95 {
96 PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::serialize");
97
98 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL3,
99 "Serializing %d instances\n",
100 _scmoInstances.size()));
101
102 ConstArrayIterator<SCMOInstance> iterator(_scmoInstances);
103
104 // First build the tables for references classes and instances
105 for (Uint32 i = 0; i < iterator.size(); i++)
106 thilo.boehm 1.2 {
107 const SCMOInstance& inst = iterator[i];
108
109 _appendToResolverTables(inst);
110 }
111
112 _putClasses(_buf,_classTable);
113
114 _putInstances();
115
116 //dumpTables();
117
118 PEG_METHOD_EXIT();
119 }
120
121 // Reads a list of SCMOInstances from the input buffer and stores them in this
122 // instance of SCMOStreamer, including their referenced Classes and Instances
123 bool SCMOStreamer::deserialize()
124 {
125 PEG_METHOD_ENTER(TRC_DISPATCHER,"SCMOStreamer::deserialize");
126
127 thilo.boehm 1.2 if(!_getClasses(_buf,_classTable))
128 {
129 PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
130 "Failed to get Classes!");
131 PEG_METHOD_EXIT();
132 return false;
133 }
134
135 if(!_getInstances())
136 {
137 PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
138 "Failed to get Instances!");
139 PEG_METHOD_EXIT();
140 return false;
141 }
142
143 //dumpTables();
144
145 PEG_METHOD_EXIT();
146 return true;
147 }
148 thilo.boehm 1.2
149 // This function takes and instance and adds all of its external
150 // references (SCMOClass and SCMOInstances) to the index tables
151 // For referenced SCMOInstances, the function recusively calls itself.
152 //
153 // Returns the index position at which the class for this instance was inserted
154 // in the class resolver table.
155 Uint32 SCMOStreamer::_appendToResolverTables(const SCMOInstance& inst)
156 {
157 // First handle the external references to other SCMOInstances
158 Uint32 numExtRefs = inst.numberExtRef();
159 for (Uint32 x=0; x < numExtRefs; x++)
160 {
161 SCMOInstance* extRef = inst.getExtRef(x);
162
163 Uint32 idx = _appendToResolverTables(*extRef);
164 _appendToInstResolverTable(*extRef,idx);
165 }
166
167 // Add the instance to the class resolution table
168 // (Also adds the class to the class table when neccessary)
169 thilo.boehm 1.2 return _appendToClassResolverTable(inst);
170 }
171
172
173 // This function adds the given instance to the instance resolver table,
174 // which stores the connections between instances and their external
175 // references.
176 //
177 // Returns the index position at which the instance was inserted in the
178 // instance resolver table.
179 Uint32 SCMOStreamer::_appendToInstResolverTable(
180 const SCMOInstance& inst,
181 Uint32 idx)
182 {
|
206 thilo.boehm 1.2 _clsResolverTable.append(tableEntry);
207
208 // The number of elements in the array minus 1 is the index position
209 // at which the instance was added.
210 return _clsResolverTable.size() - 1;
211 }
212
213
214 // Add the SCMOClass for the given instance to the class table.
215 // If the class already exists in the table, it returns the index position
216 // for this class, otherwise appends the class at the end of the table
217 // and returns the new index position of the class.
218 Uint32 SCMOStreamer::_appendToClassTable(const SCMOInstance& inst)
219 {
220 Uint32 clsTableSize = _classTable.size();
221 SCMBClass_Main* clsPtr = inst.inst.hdr->theClass.ptr->cls.hdr;
222
223 const SCMBClass_Main* const* clsArray = _classTable.getData();
224
225 // Search through the table for the index of the class
226 for (Uint32 x=0; x < clsTableSize; x++)
227 thilo.boehm 1.2 {
228 if (clsArray[x] == clsPtr)
229 {
230 return x;
231 }
232 }
233
234 // Class is not yet listed in the table, therefore append it at the end ...
235 _classTable.append(clsPtr);
236
237 // ... and return the new size off the array minus one as the index
238 return _classTable.size()-1;
239 }
240
241 #ifdef PEGASUS_DEBUG
242 void SCMOStreamer::_dumpTables()
243 {
244 fprintf(stderr,"=====================================================\n");
245 fprintf(stderr,"Dump of SCMOStreamer Tables:\n");
246 fprintf(stderr,"CLASSES:\n");
247 for (Uint32 x=0; x < _classTable.size(); x++)
248 thilo.boehm 1.2 {
249 fprintf(stderr,"\t[%2d] %p %s\n",x, _classTable[x],
250 _getCharString(_classTable[x]->className,
251 (const char*)_classTable[x]));
252 }
253
254 fprintf(stderr,"INSTANCES:\n");
255 for (Uint32 x=0; x < _clsResolverTable.size(); x++)
256 {
|
267 thilo.boehm 1.2 x,
268 _instResolverTable[x].scmbptr,
269 _instResolverTable[x].index);
270 }
271 fprintf(stderr,"=====================================================\n");
272 }
273 #endif
274
275
276 // Adds the list of SCMOClasses from the ClassTable to the output buffer
277 void SCMOStreamer::_putClasses(
278 CIMBuffer& out,
279 Array<SCMBClass_Main*>& classTable)
280 {
281 Uint32 numClasses = classTable.size();
282 const SCMBClass_Main* const* clsArray = classTable.getData();
283
284 // Number of classes
285 out.putUint32(numClasses);
286
287 // SCMOClasses, one by one
288 thilo.boehm 1.2 for (Uint32 x=0; x < numClasses; x++)
289 {
290 // Calculate the in-use size of the SCMOClass data
291 Uint64 size =
292 clsArray[x]->header.totalSize - clsArray[x]->header.freeBytes;
293 out.putUint64(size);
294
295 // Write class data
296 out.putBytes(clsArray[x],(size_t)size);
297 }
298
299 }
300
301 // Reads a list of SCMOClasses from the input buffer
302 bool SCMOStreamer::_getClasses(
303 CIMBuffer& in,
304 Array<SCMBClass_Main*>& classTable)
305 {
306 // Number of classes
307 Uint32 numClasses;
308 if(! in.getUint32(numClasses) )
309 thilo.boehm 1.2 {
310 return false;
311 }
312
313 // SCMOClasses, one by one
314 for (Uint32 x=0; x < numClasses; x++)
315 {
316 Uint64 size;
317 if (!in.getUint64(size))
318 {
319 return false;
320 }
321
322 // Read class data
323 SCMBClass_Main* scmbClassPtr = (SCMBClass_Main*)malloc((size_t)size);
324 if (0 == scmbClassPtr)
325 {
326 // Not enough memory!
327 throw PEGASUS_STD(bad_alloc)();
328 }
329
330 thilo.boehm 1.2 if (!in.getBytes(scmbClassPtr,(size_t)size))
331 {
332 return false;
333 }
334
335
336 // Resolve the class
337 scmbClassPtr->header.totalSize = size;
338 scmbClassPtr->header.freeBytes = 0;
339 scmbClassPtr->refCount.set(0);
340
341 classTable.append(scmbClassPtr);
342 }
343
344 return true;
345 }
346
347 // Adds the list of SCMO Instances from the _clsResolverTable to the
348 // output buffer
349 void SCMOStreamer::_putInstances()
350 {
351 thilo.boehm 1.2 Uint32 numInst = _clsResolverTable.size();
352 const SCMOResolutionTable* instArray = _clsResolverTable.getData();
353
354 // Number of instances
355 _buf.putUint32(numInst);
356
357 // Instance to class resolution table
358 _buf.putBytes(instArray, numInst*sizeof(SCMOResolutionTable));
359
360
361 Uint32 numExtRefs = _instResolverTable.size();
362 const SCMOResolutionTable* extRefArray = _instResolverTable.getData();
363
364 // Number of references
365 _buf.putUint32(numExtRefs);
366
367 // Instance references resolution table
368 _buf.putBytes(extRefArray, numExtRefs*sizeof(SCMOResolutionTable));
369
370
371 // SCMOInstances, one by one
372 thilo.boehm 1.2 for (Uint32 x=0; x < numInst; x++)
373 {
374 // Calculate the in-use size of the SCMOInstance data
375 SCMBInstance_Main* instPtr = (SCMBInstance_Main*)instArray[x].scmbptr;
376 Uint64 size = instPtr->header.totalSize - instPtr->header.freeBytes;
377 _buf.putUint64(size);
378
379 // Write class data
380 _buf.putBytes(instPtr,(size_t)size);
381 }
382 }
383
384
385 // Reads a list of SCMO Instances from the input buffer.
386 // Resolves the pointers to the SCMOClass and external references via the
387 // Class and Instance resolver tables.
388 bool SCMOStreamer::_getInstances()
389 {
390 // Number of instances
391 Uint32 numInst;
392 if(!_buf.getUint32(numInst))
393 thilo.boehm 1.2 {
394 return false;
395 }
396
397 // Instance to class resolution table
398 SCMOResolutionTable *instArray = new SCMOResolutionTable[numInst];
399 if(!_buf.getBytes(instArray, numInst*sizeof(SCMOResolutionTable)))
400 {
401 return false;
402 }
403
404 // Number of references
405 Uint32 numExtRefs;
406 if(!_buf.getUint32(numExtRefs))
407 {
408 return false;
409 }
410
411 // Instance references resolution table
412 SCMOResolutionTable *extRefArray = new SCMOResolutionTable[numExtRefs];
413 Uint32 extRefIndex=0;
414 thilo.boehm 1.2 if (numExtRefs > 0)
415 {
416 if(!_buf.getBytes(extRefArray, numExtRefs*sizeof(SCMOResolutionTable)))
417 {
418 return false;
419 }
420 }
421
422 // Use simple array for access to class pointers
423 const SCMBClass_Main* const* clsArray = _classTable.getData();
424
425 // SCMOInstances, one by one
426 for (Uint32 x=0; x < numInst; x++)
427 {
428 Uint64 size;
429 if(!_buf.getUint64(size))
430 {
431 return false;
432 }
433
434 // Reserve 64 bytes more of storage to allow for hostname and namespace
435 thilo.boehm 1.2 // updates without reallocation
436
437 // Read instance data
438 SCMBInstance_Main* scmbInstPtr =
439 (SCMBInstance_Main*)malloc((size_t)size+64);
440 if (0 == scmbInstPtr)
441 {
442 // Not enough memory!
443 throw PEGASUS_STD(bad_alloc)();
444 }
445
446 if(!_buf.getBytes(scmbInstPtr,(size_t)size))
447 {
448 return false;
449 }
450
451 // Resolve the instance
452 scmbInstPtr->header.totalSize = size+64;
453 scmbInstPtr->header.freeBytes = 64;
454 scmbInstPtr->refCount.set(0);
455 scmbInstPtr->theClass.ptr =
456 thilo.boehm 1.2 new SCMOClass((SCMBClass_Main*)clsArray[instArray[x].index]);
457
458 SCMOInstance* scmoInstPtr = new SCMOInstance(scmbInstPtr);
459
460 if (numExtRefs > 0)
461 {
462 // Handle the external references to other SCMOInstances
463 Uint32 numExtRefs = scmoInstPtr->numberExtRef();
464 for (Uint32 i=0; i < numExtRefs; i++)
465 {
466 Uint32 extRefPos = extRefArray[extRefIndex].index;
467 SCMOInstance* extRefPtr =
468 (SCMOInstance*)instArray[extRefPos].scmbptr;
469 scmoInstPtr->putExtRef(i,extRefPtr);
470
471 // Mark instance as already consumed
472 instArray[extRefPos].scmbptr = 0;
473
474 extRefIndex++;
475 }
476 }
477 thilo.boehm 1.2
478 instArray[x].scmbptr = (Uint64)(void*)scmoInstPtr;
479
480 #ifdef PEGASUS_DEBUG
481 _clsResolverTable.append(instArray[x]);
482 #endif
483 }
484
485 // Append all non-referenced instances to output array
486 for (Uint32 x=0; x < numInst; x++)
487 {
488 if (instArray[x].scmbptr)
489 {
490 _scmoInstances.append(*((SCMOInstance*)instArray[x].scmbptr));
491 delete (SCMOInstance*)instArray[x].scmbptr;
492 }
493 }
494 delete [] instArray;
495 delete [] extRefArray;
496
497 return true;
498 thilo.boehm 1.2 }
499
500 PEGASUS_NAMESPACE_END
501
|