source: trunk/src/core2/RpSerializer.cc @ 4503

Last change on this file since 4503 was 3177, checked in by mmc, 12 years ago

Updated all of the copyright notices to reference the transfer to
the new HUBzero Foundation, LLC.

File size: 4.4 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 *  Rappture::Serializer
4 *    The object collects a series of other objects together and
5 *    serializes them into a single byte stream.  That stream can
6 *    be written to a file, send over a socket, and so forth.  The
7 *    resulting stream can be loaded by a Serializer and the objects
8 *    can be reconstituted to their original form.
9 *
10 * ======================================================================
11 *  AUTHOR:  Michael McLennan, Purdue University
12 *  Copyright (c) 2004-2012  HUBzero Foundation, LLC
13 *
14 *  See the file "license.terms" for information on usage and
15 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
16 * ======================================================================
17 */
18#include <assert.h>
19#include <sstream>
20#include "RpSerializer.h"
21
22using namespace Rappture;
23
24Serializer::Serializer()
25{
26}
27
28Serializer::~Serializer()
29{
30}
31
32Outcome
33Serializer::deserialize(const char* bytes, int nbytes)
34{
35    Outcome result;
36    std::string token;
37
38    clear();
39    SerialBuffer buffer(bytes, nbytes);
40
41    // read the format and make sure we've got the right reader
42    token = buffer.readString();
43    if (token != "RpSerial:A") {
44        std::string errmsg("can't deserialize stream: ");
45        errmsg += "bad marker \"";
46        errmsg += token;
47        errmsg += "\" (should be RpSerial:A)";
48        return result.error(errmsg.data());
49    }
50
51    // get the number of objects to read
52    int nobj = buffer.readInt();
53    if (nobj < 0) {
54        std::string errmsg("can't deserialize stream: ");
55        errmsg += "corrupt data (number of objects is negative)";
56        return result.error(errmsg.data());
57    }
58
59    // read out the expected number of objects from the list
60    for (int i=0; i < nobj && !buffer.atEnd(); i++) {
61        token = buffer.readString();
62        if (token != "RpObj:") {
63            std::string errmsg("can't deserialize stream: ");
64            errmsg += "bad marker \"";
65            errmsg += token;
66            errmsg += "\" (should be RpObj:)";
67            return result.error(errmsg.data());
68        }
69        std::string id = buffer.readString();
70
71        Ptr<Serializable> objPtr;
72        result = Serializable::deserialize(buffer, &objPtr);
73
74        // if there was an error, then bail out
75        if (result != 0) {
76            std::ostringstream context;
77            context << "while deserializing object #" << i+1
78              << " of " << nobj;
79            return result.addContext(context.str().data());
80        }
81
82        // add the object to the known list
83        _id2obj[id] = objPtr;
84        SerializerId2Obj::iterator iter = _id2obj.find(id);
85        const char* key = (*iter).first.data();
86        _idlist.push_back(key);
87    }
88
89    return result;
90}
91
92Ptr<SerialBuffer>
93Serializer::serialize()
94{
95    Ptr<SerialBuffer> bufferPtr( new SerialBuffer() );
96    bufferPtr->writeString("RpSerial:A");
97
98    // write out number of objects in the stream
99    bufferPtr->writeInt(_idlist.size());
100
101    // write out each object in the list, in order
102    for (unsigned int i=0; i < _idlist.size(); i++) {
103        const char* id = _idlist.at(i);
104        Ptr<Serializable> objPtr = _id2obj[id];
105
106        bufferPtr->writeString("RpObj:");
107        bufferPtr->writeString(id);
108        objPtr->serialize(*bufferPtr.pointer());
109    }
110    return bufferPtr;
111}
112
113int
114Serializer::size() const
115{
116    return _idlist.size();
117}
118
119Ptr<Serializable>
120Serializer::get(int pos) const
121{
122    Serializer *nonconst = (Serializer*)this;
123    assert(pos >= 0 && (unsigned int)pos < _idlist.size());
124
125    std::string id(_idlist[pos]);
126    return nonconst->_id2obj[id];
127}
128
129Serializer&
130Serializer::clear()
131{
132    _id2obj.clear();
133    _idlist.clear();
134    return *this;
135}
136
137const char*
138Serializer::add(Serializable* objPtr)
139{
140    const char* key = NULL;
141
142    // build a unique string that represents this object
143    std::ostringstream idbuffer;
144    idbuffer << (void*)objPtr;
145    std::string id(idbuffer.str());
146
147    // have we already registered this object?
148    SerializerId2Obj::iterator iter = _id2obj.find(id);
149    if (iter == _id2obj.end()) {
150        // if not, then add to map and also to list of all objects
151        _id2obj[id] = Ptr<Serializable>(objPtr);
152        iter = _id2obj.find(id);
153        key = (*iter).first.data();
154        _idlist.push_back(key);
155    } else {
156        // if so, then update map
157        key = (*iter).first.data();
158        _id2obj[id] = Ptr<Serializable>(objPtr);
159    }
160    return key;
161}
Note: See TracBrowser for help on using the repository browser.