source: trunk/src/mesh/serializer.cc @ 352

Last change on this file since 352 was 349, checked in by cxsong, 18 years ago

updated comments

File size: 8.0 KB
Line 
1#include "serializer.h"
2#include "rp_types.h"
3
4//
5// add an serializable object to the Serializer
6//
7void
8RpSerializer::addObject(RpSerializable* obj)
9{
10        const char* key = obj->objectName();
11
12        // add object pointer to object map
13        m_objMap[key] = obj;
14
15        // add object entry to reference count table
16        m_refCount[key] = 0;
17
18        /*
19        // handle mesh object embedded in field
20        if (obj->objectType() == RpObjectTypes[FIELD] ) {
21                addObject(((RpField*)obj)->getMeshId(),
22                          ((RpField*)obj)->getMeshObj());
23                printf("addObject:
24        }
25        */
26
27#ifdef DEBUG
28        printf("RpSerializer::addObject: obj name=%s, ptr=%x\n", key, (unsigned int)obj);
29        printf("RpSerializer::addObject: map size %d\n", m_objMap.size());
30#endif
31}
32
33void
34RpSerializer::addObject(const char* key, RpSerializable* ptr)
35{
36
37        m_objMap[key] = ptr;
38        m_refCount[key] = 0;
39}
40
41//
42// Remove an object from Serializer
43// Input:
44//      name of rp object (e.g., "output.mesh(m3d)")
45//
46void
47RpSerializer::deleteObject(const char* name)
48{
49        typeObjMap::iterator iter = m_objMap.find(name);
50        if (iter == m_objMap.end())
51                // does not exist
52                return;
53
54        RpSerializable* obj = (*iter).second;
55
56        // handle RpField - update mesh ref count
57        if (obj->objectType() == RpObjectTypes[FIELD]) {
58                deleteObject( ((RpField*)obj)->getMeshId() );
59        }
60
61        // decrement object's reference count
62        // if reference count is zero, free memory and remove entry in obj map
63        if ( (--(m_refCount[name])) == 0) {
64                delete obj; // free obj memory
65                m_objMap.erase(name); // erase entry in object map
66                m_refCount.erase(name); // erase entry in object map
67        }
68
69        return;
70}
71
72void
73RpSerializer::deleteObject(RpSerializable* obj)
74{
75        const char* name = obj->objectName();
76        typeObjMap::iterator iter = m_objMap.find(name);
77
78        if (iter == m_objMap.end())
79                // does not exist
80                return;
81
82        RpSerializable* obj_ptr = (*iter).second;
83
84        // decrement object's reference count
85        // if reference count is zero, free memory and remove entry in obj map
86        if ( (--(m_refCount[name])) == 0) {
87                delete obj_ptr; // free obj memory
88                m_objMap.erase(name); // erase entry in object map
89                m_refCount.erase(name); // erase entry in object map
90        }
91
92        return;
93}
94
95void
96RpSerializer::deleteAllObjects()
97{
98        typeObjMap::iterator iter;
99
100        // free memory for all objects
101        for (iter = m_objMap.begin(); iter != m_objMap.end(); iter++)
102                delete (*iter).second;
103
104        m_objMap.clear();
105        m_refCount.clear();
106}
107
108void
109RpSerializer::clear()
110{
111        deleteAllObjects();
112
113        delete [] m_buf;
114        m_buf = 0;
115}
116
117// retrieve object
118RpSerializable*
119RpSerializer::getObject(const char* objectName)
120{
121        typeObjMap::iterator iter = m_objMap.find(objectName);
122       
123        if (iter != m_objMap.end()) {
124#ifdef DEBUG
125                printf("RpSerializer::getObject: found %s %x\n", objectName,
126                                (unsigned)( (*iter).second ));
127#endif
128                // object found, increment ref count
129                ++(m_refCount[objectName]);
130
131                // special handling of field object with link to mesh
132                RpSerializable* ptmp = (*iter).second;
133                if ( (ptmp->objectType() == RpObjectTypes[FIELD]) ) {
134               
135                        RpField* ftmp = (RpField*)ptmp;
136
137                        // find mesh obj ptr in serializer
138                        typeObjMap::iterator it = m_objMap.find(ftmp->getMeshId());
139                        if (it != m_objMap.end()) { //found mesh obj
140                                ftmp->setMeshObj( ((*it).second) );
141                                ++(m_refCount[ftmp->getMeshId()]);
142                        }
143                        else {
144                                RpAppendErr("RpSerializer::getObject: field without mesh data\n");
145                                RpPrintErr();
146                        }
147                }
148
149                // return pointer to object
150                return (*iter).second;
151        }
152        else {// not found
153#ifdef DEBUG
154                printf("RpSerializer::getObject: obj %s not found\n", objectName);
155#endif
156                return NULL;
157        }
158}
159
160// marshalling
161// The data format for the serialized byte stream:
162// 4 bytes: total number bytes (including these 4 bytes)
163// 2 bytes: encoding flag
164// 2 bytes: compression flag
165// Each object in the serializer is written out to a byte stream in its
166// format:
167//      RV-A-GRID1D
168//      total num bytes
169//      number of chars in object name
170//      object name (e.g., output.grid(g1d) )
171//      num points
172//      x1 x2 ...
173//
174char*
175RpSerializer::serialize()
176{
177        // calculate total number of bytes by adding up all the objects
178        int nbytes = numBytes();       
179
180#ifdef DEBUG
181        printf("RpSerializer::serialize: bytes=%d\n", nbytes);
182#endif
183       
184        // allocate memory -- could cause problem...TODO
185        if (m_buf) {
186                delete [] m_buf;
187        }
188
189        m_buf = new char[nbytes];
190        if (m_buf == NULL) {
191                RpAppendErr("RpSerializer::serialize: new char[] failed\n");
192                RpPrintErr();
193                return m_buf;
194        }
195
196        writeHeader(m_buf, nbytes, "NO", "NO");
197
198        // call each object to serialize itself
199        char* ptr = m_buf + headerSize();
200
201        typeObjMap::iterator iter;
202        int nb;
203        for (iter = m_objMap.begin(); iter != m_objMap.end(); iter++) {
204                RpSerializable* obj = (*iter).second;
205                nb = obj->numBytes();
206                obj->doSerialize(ptr, nb); // object serialization
207                ptr += nb; // advance buffer pointer
208        }
209
210        // return pointer to buffer
211        return m_buf;
212}
213
214//
215// unmarshalling
216//
217// Input:
218//      buf - pointer to byte stream buffer, including the beginning bytes
219//            for total number of bytes, compression and encoding indicators.
220// Side effects:
221//      objects are created in m_objMap
222//      reference count for each object is set to 0
223void
224RpSerializer::deserialize(const char* buf)
225{
226        std::string encodeFlag;
227        std::string compressFlag;
228        int nbytes;
229
230        char* ptr = (char*)buf;
231
232        readHeader(ptr, nbytes, encodeFlag, compressFlag);
233        ptr += headerSize();
234
235        const char* end_ptr = buf + nbytes; // pointer to end of blob
236
237        std::string header;
238        RpSerializable* obj;
239
240        while (ptr < end_ptr) {
241                readString(ptr, header, HEADER_SIZE);
242
243                // create new object based on object type/version
244                if ( (obj = createObject(header, ptr)) != NULL) {
245                        // add object to serializer
246                        addObject(obj);
247
248                        // advance buffer pointer
249                        ptr += obj->numBytes();
250                }
251                else // TODO: add error handling
252                        break;
253        }
254}
255
256//
257// returns total number of bytes from the objects
258//
259int RpSerializer::numBytesObjects()
260{
261        int nbytes = 0;
262        typeObjMap::iterator iter;
263
264        for (iter = m_objMap.begin(); iter != m_objMap.end(); iter++)
265                nbytes += ( (*iter).second)->numBytes();
266
267        return nbytes;
268}
269
270void RpSerializer::readHeader(const char* buf, int& nbytes,
271                std::string& encodeFlag, std::string& compressFlag)
272{
273        char* ptr = (char*)buf;
274
275        // read number of bytes
276        readInt(ptr, nbytes);
277        ptr += sizeof(int);
278
279        // read encoding flag (2 bytes)
280        readString(ptr, encodeFlag, 2);
281        readString(ptr+2, encodeFlag, 2);
282
283#ifdef DBEUG
284        printf("Serializer::readHeader: nbytes=%d ", nbytes);
285        printf("encode: %s ", encodeFlag.c_str());
286        printf("compress: %s\n", compressFlag.c_str());
287#endif
288
289}
290
291//
292//
293void RpSerializer::writeHeader(char* buf, int nbytes, const char* eflag, const char* cflag)
294{
295        char* ptr = (char*)buf;
296
297        // read number of bytes
298        writeInt(ptr, nbytes);
299        ptr += sizeof(int);
300
301        // read encoding flag (2 bytes)
302        writeString(ptr, eflag, 2);
303        writeString(ptr+2, cflag, 2);
304}
305
306void RpSerializer::print()
307{
308        typeObjMap::iterator iter;
309        for (iter = m_objMap.begin(); iter != m_objMap.end(); iter++)
310                printf("objMap: %s= ptr=%x\n", (*iter).first, (unsigned)(*iter).second);
311
312        typeRefCount::iterator it;
313        for (it = m_refCount.begin(); it != m_refCount.end(); it++)
314                printf("count: %s= count=%d\n", (*it).first, (*it).second);
315};
316
317//
318// create a new Serializable object based on header info (obj type
319// and version)
320//
321RpSerializable*
322RpSerializer::createObject(std::string header, const char* buf)
323{
324        RpSerializable* obj;
325#ifdef DEBUG
326        printf("RpSerializer::createObject: header=%s=, ptr=%x\n",
327                        header.c_str(), (unsigned)buf);
328#endif
329
330        if (header == RpCurrentVersion[GRID1D]) {
331                obj = new RpGrid1d(); // create new object
332                obj->deserialize(buf);
333                return obj;
334        }
335        if (header == RpCurrentVersion[GRID2D]) {
336                obj = new RpGrid2d(); // create new object
337                obj->deserialize(buf);
338                return obj;
339        }
340        else if (header == RpCurrentVersion[FIELD]) {
341                obj = new RpField(); // create new object
342                obj->deserialize(buf);
343                return obj;
344        }
345        /*
346        else if (header == RpCurrentVersion[MESH3D]) {
347                obj = new RpMesh3d(); // create new object
348                obj->deserialize(buf);
349                return obj;
350        }
351        else if (header == RpCurrentVersion[ELEMENT]) {
352                obj = new RpElement(); // create new object
353                obj->deserialize(buf);
354                return obj;
355        }*/
356        else {
357                printf("not implemented\n");
358                return NULL;
359        }
360
361                /* TODO
362                  handle other object types
363                */
364
365}
366
Note: See TracBrowser for help on using the repository browser.