source: branches/1.3/src/core2/RpSerializer.cc @ 5675

Last change on this file since 5675 was 5675, checked in by ldelgass, 9 years ago

merge r5673 from trunk (eol-style)

  • Property svn:eol-style set to native
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.