From 324feef9c16da1609847a1575db7b42e52f61b70 Mon Sep 17 00:00:00 2001
From: Ramin Yaghoubzadeh <ryaghoub@techfak.uni-bielefeld.de>
Date: Wed, 19 Sep 2012 14:50:53 +0200
Subject: [PATCH] Added a dedicated wire schema for Messages since Java needed
 to do this.

A new dedicated MessageConverter was added at the same time.
---
 ipaacalib/cpp/include/ipaaca/ipaaca.h | 14 ++++
 ipaacalib/cpp/src/ipaaca.cc           | 97 +++++++++++++++++++++++++++
 2 files changed, 111 insertions(+)

diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca.h b/ipaacalib/cpp/include/ipaaca/ipaaca.h
index 39db64d..3631229 100644
--- a/ipaacalib/cpp/include/ipaaca/ipaaca.h
+++ b/ipaacalib/cpp/include/ipaaca/ipaaca.h
@@ -103,6 +103,9 @@ class PayloadEntryProxy;
 class Payload;
 class IUInterface;
 class IU;
+class Message;
+class IUConverter;
+class MessageConverter;
 class RemotePushIU;
 class IULinkUpdate;
 class IULinkUpdateConverter;
@@ -171,6 +174,7 @@ class SmartLinkMap {
 	friend class IUInterface;
 	friend class IU;
 	friend class IUConverter;
+	friend class MessageConverter;
 	public:
 		const LinkSet& get_links(const std::string& key);
 		const LinkMap& get_all_links();
@@ -365,6 +369,13 @@ class IUConverter: public rsb::converter::Converter<std::string> {//{{{
 		rsb::AnnotatedData deserialize(const std::string& wireSchema, const std::string& wire);
 };//}}}
 
+class MessageConverter: public rsb::converter::Converter<std::string> {//{{{
+	public:
+		MessageConverter();
+		std::string serialize(const rsb::AnnotatedData& data, std::string& wire);
+		rsb::AnnotatedData deserialize(const std::string& wireSchema, const std::string& wire);
+};//}}}
+
 class IUPayloadUpdate {//{{{
 	public:
 		std::string uid;
@@ -449,6 +460,7 @@ class Payload//{{{
 	friend class RemotePushIU;
 	friend class RemoteMessage;
 	friend class IUConverter;
+	friend class MessageConverter;
 	friend class CallbackIUPayloadUpdate;
 	protected:
 		std::string _owner_name;
@@ -477,6 +489,7 @@ class Payload//{{{
 
 class IUInterface {//{{{
 	friend class IUConverter;
+	friend class MessageConverter;
 	friend std::ostream& operator<<(std::ostream& os, const IUInterface& obj);
 	protected:
 		IUInterface();
@@ -625,6 +638,7 @@ class RemoteMessage: public IUInterface {//{{{
 	friend class InputBuffer;
 	friend class OutputBuffer;
 	friend class IUConverter;
+	friend class MessageConverter;
 	public:
 		Payload _payload;
 	protected:
diff --git a/ipaacalib/cpp/src/ipaaca.cc b/ipaacalib/cpp/src/ipaaca.cc
index 75166fd..8667be1 100644
--- a/ipaacalib/cpp/src/ipaaca.cc
+++ b/ipaacalib/cpp/src/ipaaca.cc
@@ -24,6 +24,9 @@ void Initializer::initialize_ipaaca_rsb_if_needed()
 	boost::shared_ptr<IUConverter> iu_converter(new IUConverter());
 	converterRepository<std::string>()->registerConverter(iu_converter);
 	
+	boost::shared_ptr<MessageConverter> message_converter(new MessageConverter());
+	converterRepository<std::string>()->registerConverter(message_converter);
+	
 	boost::shared_ptr<IUPayloadUpdateConverter> payload_update_converter(new IUPayloadUpdateConverter());
 	converterRepository<std::string>()->registerConverter(payload_update_converter);
 	
@@ -1277,6 +1280,100 @@ AnnotatedData IUConverter::deserialize(const std::string& wireSchema, const std:
 			return std::make_pair("ipaaca::RemotePushIU", obj);
 			break;
 			}
+		/*case IU_ACCESS_MESSAGE:
+			{
+			// Create a "Message-type IU"
+			boost::shared_ptr<RemoteMessage> obj = RemoteMessage::create();
+			// transfer pbo data to obj
+			obj->_uid = pbo->uid();
+			obj->_revision = pbo->revision();
+			obj->_category = pbo->category();
+			obj->_payload_type = pbo->payload_type();
+			obj->_owner_name = pbo->owner_name();
+			obj->_committed = pbo->committed();
+			obj->_read_only = pbo->read_only();
+			obj->_access_mode = IU_ACCESS_MESSAGE;
+			for (int i=0; i<pbo->payload_size(); i++) {
+				const protobuf::PayloadItem& it = pbo->payload(i);
+				obj->_payload._store[it.key()] = it.value();
+			}
+			for (int i=0; i<pbo->links_size(); i++) {
+				const protobuf::LinkSet& pls = pbo->links(i);
+				LinkSet& ls = obj->_links._links[pls.type()];
+				for (int j=0; j<pls.targets_size(); j++) {
+					ls.insert(pls.targets(j));
+				}
+			}
+			//return std::make_pair(getDataType(), obj);
+			return std::make_pair("ipaaca::RemoteMessage", obj);
+			break;
+			} */
+		default:
+			// other cases not handled yet! ( TODO )
+			throw NotImplementedError();
+	}
+}
+
+//}}}
+// MessageConverter//{{{
+
+MessageConverter::MessageConverter()
+: Converter<std::string> ("ipaaca::Message", "ipaaca-messageiu", true)
+{
+}
+
+std::string MessageConverter::serialize(const AnnotatedData& data, std::string& wire)
+{
+	// Ensure that DATA actually holds a datum of the data-type we expect.
+	assert(data.first == getDataType()); // "ipaaca::Message"
+	// NOTE: a dynamic_pointer_cast cannot be used from void*
+	boost::shared_ptr<const Message> obj = boost::static_pointer_cast<const Message> (data.second);
+	boost::shared_ptr<protobuf::IU> pbo(new protobuf::IU());
+	// transfer obj data to pbo
+	pbo->set_uid(obj->uid());
+	pbo->set_revision(obj->revision());
+	pbo->set_category(obj->category());
+	pbo->set_payload_type(obj->payload_type());
+	pbo->set_owner_name(obj->owner_name());
+	pbo->set_committed(obj->committed());
+	ipaaca::protobuf::IU_AccessMode a_m;
+	switch(obj->access_mode()) {
+		case IU_ACCESS_PUSH:
+			a_m = ipaaca::protobuf::IU_AccessMode_PUSH;
+			break;
+		case IU_ACCESS_REMOTE:
+			a_m = ipaaca::protobuf::IU_AccessMode_REMOTE;
+			break;
+		case IU_ACCESS_MESSAGE:
+			a_m = ipaaca::protobuf::IU_AccessMode_MESSAGE;
+			break;
+	}
+	pbo->set_access_mode(a_m);
+	pbo->set_read_only(obj->read_only());
+	for (std::map<std::string, std::string>::const_iterator it=obj->_payload._store.begin(); it!=obj->_payload._store.end(); ++it) {
+		protobuf::PayloadItem* item = pbo->add_payload();
+		item->set_key(it->first);
+		item->set_value(it->second);
+		item->set_type("str"); // FIXME other types than str (later)
+	}
+	for (LinkMap::const_iterator it=obj->_links._links.begin(); it!=obj->_links._links.end(); ++it) {
+		protobuf::LinkSet* links = pbo->add_links();
+		links->set_type(it->first);
+		for (std::set<std::string>::const_iterator it2=it->second.begin(); it2!=it->second.end(); ++it2) {
+			links->add_targets(*it2);
+		}
+	}
+	pbo->SerializeToString(&wire);
+	return getWireSchema();
+
+}
+
+AnnotatedData MessageConverter::deserialize(const std::string& wireSchema, const std::string& wire) {
+	assert(wireSchema == getWireSchema()); // "ipaaca-iu"
+	boost::shared_ptr<protobuf::IU> pbo(new protobuf::IU());
+	pbo->ParseFromString(wire);
+	IUAccessMode mode = static_cast<IUAccessMode>(pbo->access_mode());
+	switch(mode) {
 		case IU_ACCESS_MESSAGE:
 			{
 			// Create a "Message-type IU"
-- 
GitLab