summaryrefslogtreecommitdiffstats
path: root/src/jabber_whiteboard/deserializer.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/jabber_whiteboard/deserializer.h')
-rw-r--r--src/jabber_whiteboard/deserializer.h285
1 files changed, 285 insertions, 0 deletions
diff --git a/src/jabber_whiteboard/deserializer.h b/src/jabber_whiteboard/deserializer.h
new file mode 100644
index 000000000..715ca4c66
--- /dev/null
+++ b/src/jabber_whiteboard/deserializer.h
@@ -0,0 +1,285 @@
+/**
+ * Inkboard message -> XML::Event* deserializer
+ *
+ * Authors:
+ * David Yip <yipdw@rose-hulman.edu>
+ *
+ * Copyright (c) 2005 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef __WHITEBOARD_MESSAGE_DESERIALIZER_H__
+#define __WHITEBOARD_MESSAGE_DESERIALIZER_H__
+
+#include "xml/log-builder.h"
+#include "xml/event.h"
+
+#include "jabber_whiteboard/node-tracker-event-tracker.h"
+#include "jabber_whiteboard/node-tracker.h"
+#include "jabber_whiteboard/typedefs.h"
+
+#include <functional>
+#include <algorithm>
+#include <glibmm.h>
+
+namespace Inkscape {
+
+namespace Whiteboard {
+
+/**
+ * A stateful XML::Event deserializer.
+ *
+ * The Deserializer class is meant to deserialize XML::Events serialized by
+ * Inkscape::Whiteboard::Serializer or a serializer that serializes
+ * XML::Events into the same format.
+ *
+ * Usage is as follows:
+ * <ol>
+ * <li>For each serialized event called, call the appropriate deserialization method.</li>
+ * <li>Detach the deserialized event.</li>
+ * </ol>
+ *
+ * The deserializer does not actually modify any aspect of the document or node-tracking systems.
+ * Methods are provided to provide the information necessary to perform the modifications outside
+ * of the deserializer.
+ */
+class Deserializer {
+public:
+ /**
+ * Constructor.
+ *
+ * \param xnt The XMLNodeTracker that a Deserializer should use for retrieving
+ * XML::Nodes based on string keys.
+ */
+ Deserializer(XMLNodeTracker* xnt) : _xnt(xnt)
+ {
+ this->clearEventLog();
+ }
+
+ ~Deserializer() { }
+
+ /**
+ * Deserialize a node add event.
+ *
+ * \see XML::EventAdd
+ * \param msg The message that describes the event.
+ */
+ void deserializeEventAdd(Glib::ustring const& msg);
+
+ /**
+ * Deserialize a node remove event.
+ *
+ * \see XML::EventDel
+ * \param msg The message that describes the event.
+ */
+ void deserializeEventDel(Glib::ustring const& msg);
+
+ /**
+ * Deserialize a node order change event.
+ *
+ * \see XML::EventChgOrder
+ * \param msg The message that describes the event.
+ */
+ void deserializeEventChgOrder(Glib::ustring const& msg);
+
+ /**
+ * Deserialize a node content change event.
+ *
+ * \see XML::EventChgContent
+ * \param msg The message that describes the event.
+ */
+ void deserializeEventChgContent(Glib::ustring const& msg);
+
+ /**
+ * Deserialize a node attribute change event.
+ *
+ * \see XML::EventChgAttr
+ * \param msg The message that describes the event.
+ */
+ void deserializeEventChgAttr(Glib::ustring const& msg);
+
+ /**
+ * Retrieve the deserialized event log.
+ * This method does <b>not</b> clear the internal event log kept by the deserializer.
+ * To do that, use detachEventLog.
+ *
+ * \return The deserialized event log.
+ */
+ XML::Event* getEventLog()
+ {
+ return this->_log;
+ }
+
+ /**
+ * Retrieve the deserialized event log and clear the internal event log kept by the deserializer.
+ *
+ * \return The deserialized event log.
+ */
+ XML::Event* detachEventLog()
+ {
+ XML::Event* ret = this->_log;
+ this->clearEventLog();
+ return ret;
+ }
+
+ /**
+ * Clear the internal event log.
+ */
+ void clearEventLog()
+ {
+ g_log(NULL, G_LOG_LEVEL_DEBUG, "Clearing event log");
+ this->_log = NULL;
+ }
+
+ /**
+ * Retrieve a list of node entry actions (add node entry, remove node entry)
+ * that need to be performed on the XMLNodeTracker.
+ *
+ * Because this method returns a reference to a list, it is not safe for use
+ * across multiple invocations of this Deserializer.
+ *
+ * \return A reference to a list of node entry actions generated while deserializing.
+ */
+ KeyToNodeActionList& getNodeTrackerActions()
+ {
+ return this->_actions;
+ }
+
+ /**
+ * Retrieve a list of node entry actions (add node entry, remove node entry)
+ * that need to be performed on the XMLNodeTracker.
+ *
+ * \return A list of node entry actions generated while deserializing.
+ */
+ KeyToNodeActionList getNodeTrackerActionsCopy()
+ {
+ return this->_actions;
+ }
+
+ /**
+ * Retrieve a set of nodes for which an EventChgAttr was deserialized.
+ *
+ * For some actions (i.e. text tool) it is necessary to call updateRepr() on
+ * the updated nodes. This method provides the information required to perform
+ * that action.
+ *
+ * Because this method returns a reference to a set, it is not safe for use
+ * across multiple invocations of this Deserializer.
+ *
+ * \return A reference to a set of nodes for which an EventChgAttr was deserialized.
+ */
+ AttributesUpdatedSet& getUpdatedAttributeNodeSet()
+ {
+ return this->_updated;
+ }
+
+ /**
+ * Retrieve a set of nodes for which an EventChgAttr was deserialized.
+ *
+ * For some actions (i.e. text tool) it is necessary to call updateRepr() on
+ * the updated nodes. This method provides the information required to perform
+ * that action.
+ *
+ * \return A set of nodes for which an EventChgAttr was deserialized.
+ */
+ AttributesUpdatedSet getUpdatedAttributeNodeSetCopy()
+ {
+ return this->_updated;
+ }
+
+ /**
+ * Clear all internal node buffers.
+ */
+ void clearNodeBuffers()
+ {
+ g_log(NULL, G_LOG_LEVEL_DEBUG, "Clearing deserializer node buffers");
+ this->_newnodes.clear();
+ this->_actions.clear();
+ this->_newkeys.clear();
+ this->_parent_child_map.clear();
+ this->_updated.clear();
+ }
+
+ /**
+ * Clear all internal state.
+ */
+ void reset()
+ {
+ this->clearEventLog();
+ this->clearNodeBuffers();
+ }
+
+private:
+ XML::Node* _getNodeByID(std::string const& id)
+ {
+ KeyToNodeMap::iterator i = this->_newnodes.find(id);
+ if (i != this->_newnodes.end()) {
+ return const_cast< XML::Node* >(i->second);
+ } else {
+ if (this->_xnt->isTracking(id)) {
+ return this->_xnt->get(id);
+ } else {
+ return NULL;
+ }
+ }
+ }
+
+ void _addOneEvent(XML::Event* event)
+ {
+ if (this->_log == NULL) {
+ this->_log = event;
+ } else {
+ event->next = this->_log;
+ this->_log = event;
+ }
+ }
+
+ void _recursiveMarkForRemoval(XML::Node* node);
+
+ // internal states with accessors:
+
+ // node tracker actions (add node, remove node)
+ KeyToNodeActionList _actions;
+
+ // nodes that have had their attributes updated
+ AttributesUpdatedSet _updated;
+
+ // the deserialized event log
+ XML::Event* _log;
+
+
+ // for internal use:
+
+ // These maps only store information on a single node. That's fine, though;
+ // all we care about is the ability to do key <-> node association. The NodeTrackerEventTracker
+ // and KeyToNodeActionList keep track of the actual actions we need to perform
+ // on the node tracker.
+ NodeToKeyMap _newkeys;
+ KeyToNodeMap _newnodes;
+ NodeTrackerEventTracker _node_action_tracker;
+
+ typedef std::map< XML::Node*, XML::Node* > _pc_map_type;
+ _pc_map_type _parent_child_map;
+
+ XMLNodeTracker* _xnt;
+
+ XML::LogBuilder _builder;
+};
+
+}
+
+}
+
+#endif
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :