From ba6f2d7e816208db4a98feff6c44521cfc00128c Mon Sep 17 00:00:00 2001
From: Gioacchino Mazzurco <gio@eigenlab.org>
Date: Fri, 26 Jan 2018 17:18:05 +0100
Subject: [PATCH] Remove default template for to/from_JSON

This way the compiler will complain if a type is added directly to
RsTypeSerializer without specify all needed serial operations
---
 .../src/gxstunnel/rsgxstunnelitems.cc         |  3 +
 libretroshare/src/retroshare/rstypes.h        | 35 +++++++---
 libretroshare/src/rsitems/rsconfigitems.cc    | 29 +-------
 .../src/rsitems/rsfiletransferitems.cc        | 42 -----------
 libretroshare/src/rsitems/rsgxsupdateitems.cc | 23 +-----
 libretroshare/src/rsitems/rsgxsupdateitems.h  | 23 +++---
 libretroshare/src/rsserver/rstypes.cc         |  2 +-
 .../src/serialiser/rstypeserializer.cc        | 37 ++++++++--
 .../src/serialiser/rstypeserializer.h         | 70 +++++++++++--------
 libretroshare/src/turtle/rsturtleitem.cc      |  6 ++
 10 files changed, 126 insertions(+), 144 deletions(-)

diff --git a/libretroshare/src/gxstunnel/rsgxstunnelitems.cc b/libretroshare/src/gxstunnel/rsgxstunnelitems.cc
index 8e488c190..d653b03ea 100644
--- a/libretroshare/src/gxstunnel/rsgxstunnelitems.cc
+++ b/libretroshare/src/gxstunnel/rsgxstunnelitems.cc
@@ -102,6 +102,9 @@ template<> void     RsTypeSerializer::print_data(const std::string& name,BIGNUM
     std::cerr << "[BIGNUM] : " << name << std::endl;
 }
 
+RS_TYPE_SERIALIZER_TO_JSON_NOT_IMPLEMENTED_DEF(BIGNUM*)
+RS_TYPE_SERIALIZER_FROM_JSON_NOT_IMPLEMENTED_DEF(BIGNUM*)
+
 void RsGxsTunnelStatusItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
 {
     RsTypeSerializer::serial_process<uint32_t>(j,ctx,status,"status") ;
diff --git a/libretroshare/src/retroshare/rstypes.h b/libretroshare/src/retroshare/rstypes.h
index 9c098db59..84c3fc45d 100644
--- a/libretroshare/src/retroshare/rstypes.h
+++ b/libretroshare/src/retroshare/rstypes.h
@@ -36,6 +36,8 @@
 
 #include <retroshare/rsids.h>
 #include <retroshare/rsflags.h>
+#include <serialiser/rsserializable.h>
+#include <serialiser/rstypeserializer.h>
 
 #define USE_NEW_CHUNK_CHECKING_CODE
 
@@ -118,13 +120,21 @@ class Condition
 	std::string name;
 };
 
-class PeerBandwidthLimits
+struct PeerBandwidthLimits : RsSerializable
 {
-public:
-    PeerBandwidthLimits() : max_up_rate_kbs(0), max_dl_rate_kbs(0) {}
-    
-    uint32_t max_up_rate_kbs ;
-    uint32_t max_dl_rate_kbs ;
+	PeerBandwidthLimits() : max_up_rate_kbs(0), max_dl_rate_kbs(0) {}
+
+	uint32_t max_up_rate_kbs;
+	uint32_t max_dl_rate_kbs;
+
+
+	/// @see RsSerializable
+	void serial_process(RsGenericSerializer::SerializeJob j,
+	                    RsGenericSerializer::SerializeContext& ctx)
+	{
+		RS_SERIAL_PROCESS(max_up_rate_kbs);
+		RS_SERIAL_PROCESS(max_dl_rate_kbs);
+	}
 };
 
 //class SearchRequest // unused stuff.
@@ -295,7 +305,7 @@ class FileChunksInfo
 		std::map<uint32_t, std::vector<SliceInfo> > pending_slices ;
 };
 
-class CompressedChunkMap
+class CompressedChunkMap : public RsSerializable
 {
 	public:
 		CompressedChunkMap() {}
@@ -345,10 +355,17 @@ class CompressedChunkMap
 		inline void   set(uint32_t j) { _map[j >> 5] |=  (1 << (j & 31)) ; }
 		inline void reset(uint32_t j) { _map[j >> 5] &= ~(1 << (j & 31)) ; }
 
-		/// compressed map, one bit per chunk
-		std::vector<uint32_t> _map ;
+	/// compressed map, one bit per chunk
+	std::vector<uint32_t> _map;
+
+	/// @see RsSerializable
+	void serial_process(RsGenericSerializer::SerializeJob j,
+	                    RsGenericSerializer::SerializeContext& ctx)
+	{ RS_SERIAL_PROCESS(_map); }
 };
 
+RS_REGISTER_SERIALIZABLE_TYPE_DECL(CompressedChunkMap)
+
 template<class CRCTYPE> class t_CRCMap
 {
 	public:
diff --git a/libretroshare/src/rsitems/rsconfigitems.cc b/libretroshare/src/rsitems/rsconfigitems.cc
index f6296bd04..b673b354a 100644
--- a/libretroshare/src/rsitems/rsconfigitems.cc
+++ b/libretroshare/src/rsitems/rsconfigitems.cc
@@ -28,6 +28,7 @@
 #include "rsitems/rsconfigitems.h"
 #include "retroshare/rspeers.h" // Needed for RsGroupInfo.
 
+#include "serialiser/rsserializable.h"
 #include "serialiser/rstypeserializer.h"
 /***
  * #define RSSERIAL_DEBUG 		1
@@ -89,7 +90,7 @@ void RsFileTransfer::serial_process(RsGenericSerializer::SerializeJob j,RsGeneri
 
     RsTypeSerializer::serial_process<uint32_t> (j,ctx,flags,"flags") ;
     RsTypeSerializer::serial_process<uint32_t> (j,ctx,chunk_strategy,"chunk_strategy") ;
-    RsTypeSerializer::serial_process           (j,ctx,compressed_chunk_map,"compressed_chunk_map") ;
+	RS_SERIAL_PROCESS(compressed_chunk_map);
 }
 
 void RsFileConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
@@ -192,31 +193,7 @@ void RsPeerStunItem::serial_process(RsGenericSerializer::SerializeJob j,RsGeneri
     RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,stunList,"stunList") ;
 }
 
-template<> uint32_t RsTypeSerializer::serial_size(const PeerBandwidthLimits& /*s*/)
-{
-    return 4+4 ;
-}
-
-template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset,const PeerBandwidthLimits& s)
-{
-    bool ok = true ;
-	ok = ok && setRawUInt32(data,size,&offset,s.max_up_rate_kbs);
-	ok = ok && setRawUInt32(data,size,&offset,s.max_dl_rate_kbs);
-	return ok;
-}
-
-template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size,uint32_t& offset,PeerBandwidthLimits& s)
-{
-    bool ok = true ;
-	ok = ok && getRawUInt32(data,size,&offset,&s.max_up_rate_kbs);
-	ok = ok && getRawUInt32(data,size,&offset,&s.max_dl_rate_kbs);
-    return ok;
-}
-
-template<> void RsTypeSerializer::print_data(const std::string& /*n*/, const PeerBandwidthLimits& s)
-{
-    std::cerr << "  [Peer BW limit] " << s.max_up_rate_kbs << " / " << s.max_dl_rate_kbs << std::endl;
-}
+RS_REGISTER_SERIALIZABLE_TYPE_DEF(PeerBandwidthLimits)
 
 RsNodeGroupItem::RsNodeGroupItem(const RsGroupInfo& g)
     :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_PEER_CONFIG, RS_PKT_SUBTYPE_NODE_GROUP)
diff --git a/libretroshare/src/rsitems/rsfiletransferitems.cc b/libretroshare/src/rsitems/rsfiletransferitems.cc
index 7579c9560..4241081a7 100644
--- a/libretroshare/src/rsitems/rsfiletransferitems.cc
+++ b/libretroshare/src/rsitems/rsfiletransferitems.cc
@@ -91,48 +91,6 @@ void RsFileTransferSingleChunkCrcItem::serial_process(RsGenericSerializer::Seria
     RsTypeSerializer::serial_process          (j,ctx,check_sum,   "check_sum") ;
 }
 
-//===================================================================================================//
-//                                         CompressedChunkMap                                        //
-//===================================================================================================//
-
-template<> uint32_t RsTypeSerializer::serial_size(const CompressedChunkMap& s)
-{
-	return 4 + 4*s._map.size() ;
-}
-
-template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset,const CompressedChunkMap& s)
-{
-    bool ok = true ;
-
-	ok &= setRawUInt32(data, size, &offset, s._map.size());
-
-	for(uint32_t i=0;i<s._map.size() && ok;++i)
-		ok &= setRawUInt32(data, size, &offset, s._map[i]);
-
-    return ok;
-}
-
-template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size,uint32_t& offset,CompressedChunkMap& s)
-{
-	uint32_t S =0;
-	bool ok = getRawUInt32(data, size, &offset, &S);
-
-	if(ok)
-	{
-		s._map.resize(S) ;
-
-		for(uint32_t i=0;i<S && ok;++i)
-			ok &= getRawUInt32(data, size, &offset, &(s._map[i]));
-	}
-
-    return ok;
-}
-
-template<> void RsTypeSerializer::print_data(const std::string& n, const CompressedChunkMap& s)
-{
-    std::cerr << "  [Compressed chunk map] " << n << " : length=" << s._map.size() << std::endl;
-}
-
 //===================================================================================================//
 //                                            Serializer                                             //
 //===================================================================================================//
diff --git a/libretroshare/src/rsitems/rsgxsupdateitems.cc b/libretroshare/src/rsitems/rsgxsupdateitems.cc
index 50f154cb2..6e18ed774 100644
--- a/libretroshare/src/rsitems/rsgxsupdateitems.cc
+++ b/libretroshare/src/rsitems/rsgxsupdateitems.cc
@@ -97,30 +97,9 @@ void RsGxsMsgUpdateItem::serial_process(RsGenericSerializer::SerializeJob j,RsGe
     RsTypeSerializer::serial_process(j,ctx,msgUpdateInfos,"msgUpdateInfos");
 }
 
-template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const RsGxsMsgUpdateItem::MsgUpdateInfo& info)
-{
-    bool ok = true ;
+RS_REGISTER_SERIALIZABLE_TYPE_DEF(RsGxsMsgUpdate::MsgUpdateInfo)
 
-    ok = ok && setRawUInt32(data,size,&offset,info.time_stamp);
-    ok = ok && setRawUInt32(data,size,&offset,info.message_count);
 
-    return ok;
-}
-template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, RsGxsMsgUpdateItem::MsgUpdateInfo& info)
-{
-    bool ok = true ;
-
-    ok = ok && getRawUInt32(data,size,&offset,&info.time_stamp);
-    ok = ok && getRawUInt32(data,size,&offset,&info.message_count);
-
-    return ok;
-}
-template<> uint32_t RsTypeSerializer::serial_size(const RsGxsMsgUpdateItem::MsgUpdateInfo& /* info */) { return 8; }
-
-template<> void RsTypeSerializer::print_data(const std::string& name,const RsGxsMsgUpdateItem::MsgUpdateInfo& info)
-{
-    std::cerr << "[MsgUpdateInfo]: " << name << ": " << info.time_stamp << ", " << info.message_count << std::endl;
-}
 
 void RsGxsServerMsgUpdateItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
 {
diff --git a/libretroshare/src/rsitems/rsgxsupdateitems.h b/libretroshare/src/rsitems/rsgxsupdateitems.h
index c9725426c..e0549b2b3 100644
--- a/libretroshare/src/rsitems/rsgxsupdateitems.h
+++ b/libretroshare/src/rsitems/rsgxsupdateitems.h
@@ -28,18 +28,11 @@
 
 
 
-#if 0
-#include <map>
-#include "rsitems/rsserviceids.h"
-#include "serialiser/rsserial.h"
-#include "serialiser/rstlvbase.h"
-#include "serialiser/rstlvtypes.h"
-#include "serialiser/rstlvkeys.h"
-#endif
-
 #include "gxs/rsgxs.h"
 #include "gxs/rsgxsdata.h"
 #include "serialiser/rstlvidset.h"
+#include "serialiser/rstypeserializer.h"
+#include "serialiser/rsserializable.h"
 
 
 const uint8_t RS_PKT_SUBTYPE_GXS_GRP_UPDATE             = 0x01;
@@ -140,17 +133,27 @@ public:
 class RsGxsMsgUpdate
 {
 public:
-    struct MsgUpdateInfo
+	struct MsgUpdateInfo : RsSerializable
     {
         MsgUpdateInfo(): time_stamp(0), message_count(0) {}
 
         uint32_t time_stamp ;
         uint32_t message_count ;
+
+		/// @see RsSerializable
+		void serial_process(RsGenericSerializer::SerializeJob j,
+		                    RsGenericSerializer::SerializeContext& ctx)
+		{
+			RS_SERIAL_PROCESS(time_stamp);
+			RS_SERIAL_PROCESS(message_count);
+		}
     };
 
     std::map<RsGxsGroupId, MsgUpdateInfo> msgUpdateInfos;
 };
 
+RS_REGISTER_SERIALIZABLE_TYPE_DECL(RsGxsMsgUpdate::MsgUpdateInfo)
+
 class RsGxsMsgUpdateItem : public RsGxsNetServiceItem, public RsGxsMsgUpdate
 {
 public:
diff --git a/libretroshare/src/rsserver/rstypes.cc b/libretroshare/src/rsserver/rstypes.cc
index 209a7da88..c13adef7a 100644
--- a/libretroshare/src/rsserver/rstypes.cc
+++ b/libretroshare/src/rsserver/rstypes.cc
@@ -76,4 +76,4 @@ std::ostream &operator<<(std::ostream &out, const FileInfo &info)
 	return out;
 }
 
-
+RS_REGISTER_SERIALIZABLE_TYPE_DEF(CompressedChunkMap)
diff --git a/libretroshare/src/serialiser/rstypeserializer.cc b/libretroshare/src/serialiser/rstypeserializer.cc
index 88585e45a..c03c64684 100644
--- a/libretroshare/src/serialiser/rstypeserializer.cc
+++ b/libretroshare/src/serialiser/rstypeserializer.cc
@@ -65,7 +65,8 @@ template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint3
 }
 template<> bool RsTypeSerializer::serialize(uint8_t /*data*/[], uint32_t /*size*/, uint32_t& /*offset*/, const int32_t& /*member*/)
 {
-	// TODO: nice to have but not used ATM
+	std::cerr << __PRETTY_FUNCTION__ << " Not implemented!" << std::endl;
+	print_stacktrace();
 	return false;
 }
 template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const uint8_t& member)
@@ -98,7 +99,8 @@ template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t siz
 }
 template<> bool RsTypeSerializer::deserialize(const uint8_t /*data*/[], uint32_t /*size*/, uint32_t& /*offset*/, int32_t& /*member*/)
 {
-	// TODO: nice to have but not used ATM
+	std::cerr << __PRETTY_FUNCTION__ << " Not implemented!" << std::endl;
+	print_stacktrace();
 	return false;
 }
 template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, uint8_t& member)
@@ -128,7 +130,9 @@ template<> uint32_t RsTypeSerializer::serial_size(const bool& /* member*/)
 }
 template<> uint32_t RsTypeSerializer::serial_size(const int32_t& /* member*/)
 {
-	return 4;
+	std::cerr << __PRETTY_FUNCTION__ << " Not implemented!" << std::endl;
+	print_stacktrace();
+	return 0;
 }
 template<> uint32_t RsTypeSerializer::serial_size(const uint8_t& /* member*/)
 { 
@@ -513,8 +517,9 @@ bool RsTypeSerializer::to_JSON( const std::string& memberName,
 
 template<> /*static*/
 bool RsTypeSerializer::from_JSON( const std::string& /*memberName*/,
-                                  RsTlvItem& /*member*/, RsJson& /*jVal*/)
+                                  RsTlvItem& member, RsJson& /*jVal*/)
 {
+	member.TlvClear();
 	return true;
 }
 
@@ -580,6 +585,30 @@ template<> void RsTypeSerializer::print_data(const std::string& n, const RsTypeS
     std::cerr << "  [Binary data] " << n << ", length=" << s.second << " data=" << RsUtil::BinToHex((uint8_t*)s.first,std::min(50u,s.second)) << ((s.second>50)?"...":"") << std::endl;
 }
 
+template<> /*static*/
+bool RsTypeSerializer::to_JSON(
+        const std::string& memberName,
+        const RsTypeSerializer::TlvMemBlock_proxy& member, RsJson& jDoc )
+{
+	rapidjson::Document::AllocatorType& allocator = jDoc.GetAllocator();
+
+	rapidjson::Value key;
+	key.SetString(memberName.c_str(), memberName.length(), allocator);
+
+	rapidjson::Value value;
+	const char* tName = typeid(member).name();
+	value.SetString(tName, allocator);
+
+	jDoc.AddMember(key, value, allocator);
+
+	return true;
+}
+
+template<> /*static*/
+bool RsTypeSerializer::from_JSON( const std::string& /*memberName*/,
+                                  RsTypeSerializer::TlvMemBlock_proxy&,
+                                  RsJson& /*jVal*/)
+{ return true; }
 
 //============================================================================//
 //                    RsSerializable and derivated                            //
diff --git a/libretroshare/src/serialiser/rstypeserializer.h b/libretroshare/src/serialiser/rstypeserializer.h
index 452700cf2..4b5486b88 100644
--- a/libretroshare/src/serialiser/rstypeserializer.h
+++ b/libretroshare/src/serialiser/rstypeserializer.h
@@ -828,38 +828,48 @@ bool RsTypeSerializer::from_JSON( const std::string& memberName,
 
 
 //============================================================================//
-// Generic types                                                              //
+// Not implemented types macros                                               //
 //============================================================================//
 
-template<typename T> /*static*/
-bool RsTypeSerializer::to_JSON(const std::string& memberName, const T& member,
-                                RsJson& jDoc )
-{
-	rapidjson::Document::AllocatorType& allocator = jDoc.GetAllocator();
-
-	rapidjson::Value key;
-	key.SetString(memberName.c_str(), memberName.length(), allocator);
-
-	rapidjson::Value value;
-	const char* tName = typeid(member).name();
-	value.SetString(tName, allocator);
-
-	jDoc.AddMember(key, value, allocator);
-
-	std::cerr << __PRETTY_FUNCTION__ << " JSON serialization for type "
-	          << typeid(member).name() << " " << memberName
-	          << " not available." << std::endl;
-	print_stacktrace();
-	return true;
+/**
+ * @def RS_TYPE_SERIALIZER_TO_JSON_NOT_IMPLEMENTED_DEF(T)
+ * @def RS_TYPE_SERIALIZER_FROM_JSON_NOT_IMPLEMENTED_DEF(T)
+ * Helper macros for types that has not yet implemented to/from JSON
+ * should be deleted from the code as soon as they are not needed anymore
+ */
+#define RS_TYPE_SERIALIZER_TO_JSON_NOT_IMPLEMENTED_DEF(T) \
+template<> /*static*/ \
+bool RsTypeSerializer::to_JSON(const std::string& memberName, T const& member, \
+	                            RsJson& jDoc ) \
+{ \
+	rapidjson::Document::AllocatorType& allocator = jDoc.GetAllocator(); \
+ \
+	rapidjson::Value key; \
+	key.SetString(memberName.c_str(), memberName.length(), allocator); \
+ \
+	rapidjson::Value value; \
+	const char* tName = typeid(member).name(); \
+	value.SetString(tName, allocator); \
+ \
+	jDoc.AddMember(key, value, allocator); \
+ \
+	std::cerr << __FILE__ << __LINE__ << __PRETTY_FUNCTION__ \
+	          << " JSON serialization for type " \
+	          << typeid(member).name() << " " << memberName \
+	          << " not available." << std::endl; \
+	print_stacktrace(); \
+	return true; \
 }
 
-template<typename T> /*static*/
-bool RsTypeSerializer::from_JSON( const std::string& memberName,
-                                  T& member, RsJson& /*jDoc*/ )
-{
-	std::cerr << __PRETTY_FUNCTION__ << " JSON deserialization for type "
-	          << typeid(member).name() << " " << memberName
-	          << " not available." << std::endl;
-	print_stacktrace();
-	return true;
+#define RS_TYPE_SERIALIZER_FROM_JSON_NOT_IMPLEMENTED_DEF(T) \
+template<> /*static*/ \
+bool RsTypeSerializer::from_JSON( const std::string& memberName, \
+	                              T& member, RsJson& /*jDoc*/ ) \
+{ \
+	std::cerr << __FILE__ << __LINE__ << __PRETTY_FUNCTION__ \
+	          << " JSON deserialization for type " \
+	          << typeid(member).name() << " " << memberName \
+	          << " not available." << std::endl; \
+	print_stacktrace(); \
+	return true; \
 }
diff --git a/libretroshare/src/turtle/rsturtleitem.cc b/libretroshare/src/turtle/rsturtleitem.cc
index 35b250117..cf206a153 100644
--- a/libretroshare/src/turtle/rsturtleitem.cc
+++ b/libretroshare/src/turtle/rsturtleitem.cc
@@ -140,6 +140,9 @@ template<> void RsTypeSerializer::print_data(const std::string& n, const RsRegul
     std::cerr << "  [RegExpr    ] " << n << ", tokens=" << expr._tokens.size() << " ints=" << expr._ints.size() << " strings=" << expr._strings.size() << std::endl;
 }
 
+RS_TYPE_SERIALIZER_TO_JSON_NOT_IMPLEMENTED_DEF(RsRegularExpression::LinearizedExpression)
+RS_TYPE_SERIALIZER_FROM_JSON_NOT_IMPLEMENTED_DEF(RsRegularExpression::LinearizedExpression)
+
 void RsTurtleSearchResultItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
 {
     RsTypeSerializer::serial_process<uint32_t>(j,ctx,request_id,"request_id") ;
@@ -193,6 +196,9 @@ template<> void RsTypeSerializer::print_data(const std::string& n, const TurtleF
     std::cerr << "  [FileInfo  ] " << n << " size=" << i.size << " hash=" << i.hash << ", name=" << i.name << std::endl;
 }
 
+RS_TYPE_SERIALIZER_TO_JSON_NOT_IMPLEMENTED_DEF(TurtleFileInfo)
+RS_TYPE_SERIALIZER_FROM_JSON_NOT_IMPLEMENTED_DEF(TurtleFileInfo)
+
 void RsTurtleOpenTunnelItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
 {
     RsTypeSerializer::serial_process          (j,ctx,file_hash        ,"file_hash") ;