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