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