From 54c953c931688df111baae8d0ca9ad432e00dc43 Mon Sep 17 00:00:00 2001
From: Ramin Yaghoubzadeh <ryaghoubzadeh@uni-bielefeld.de>
Date: Thu, 26 Feb 2015 16:59:34 +0100
Subject: [PATCH] C++: logging level; iterator work

---
 .../cpp/include/ipaaca/ipaaca-definitions.h   |  8 ++++
 ipaacalib/cpp/include/ipaaca/ipaaca-payload.h |  1 +
 ipaacalib/cpp/include/ipaaca/ipaaca.h         | 15 ++++--
 ipaacalib/cpp/src/ipaaca-cmdline-parser.cc    | 28 +++++++++--
 ipaacalib/cpp/src/ipaaca-json.cc              | 48 ++++++++++++-------
 ipaacalib/cpp/src/ipaaca-payload.cc           |  6 +++
 ipaacalib/cpp/src/ipaaca.cc                   |  1 +
 7 files changed, 80 insertions(+), 27 deletions(-)

diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca-definitions.h b/ipaacalib/cpp/include/ipaaca/ipaaca-definitions.h
index 89030df..681837b 100644
--- a/ipaacalib/cpp/include/ipaaca/ipaaca-definitions.h
+++ b/ipaacalib/cpp/include/ipaaca/ipaaca-definitions.h
@@ -55,6 +55,14 @@ typedef uint32_t IUEventType;
 /// Bit mask for receiving all events
 #define IU_ALL_EVENTS  127
 
+/// Ipaaca (console) log levels
+#define IPAACA_LOG_LEVEL_NONE     0
+#define IPAACA_LOG_LEVEL_CRITICAL 1
+#define IPAACA_LOG_LEVEL_ERROR    2
+#define IPAACA_LOG_LEVEL_WARNING  3
+#define IPAACA_LOG_LEVEL_INFO     4
+#define IPAACA_LOG_LEVEL_DEBUG    5
+
 /// Convert an int event type to a human-readable string
 IPAACA_HEADER_EXPORT inline std::string iu_event_type_to_str(IUEventType type)
 {
diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h b/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h
index 2bbde14..becd6dc 100644
--- a/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h
+++ b/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h
@@ -245,6 +245,7 @@ IPAACA_HEADER_EXPORT class PayloadIterator//{{{
 		IPAACA_HEADER_EXPORT PayloadIterator(const PayloadIterator& iter);
 		IPAACA_HEADER_EXPORT PayloadIterator& operator++();
 		IPAACA_HEADER_EXPORT std::pair<std::string, PayloadEntryProxy> operator*();
+		IPAACA_HEADER_EXPORT std::shared_ptr<std::pair<std::string, PayloadEntryProxy> > operator->();
 		IPAACA_HEADER_EXPORT bool operator==(const PayloadIterator& ref);
 		IPAACA_HEADER_EXPORT bool operator!=(const PayloadIterator& ref);
 		// constructor to create a new top-most parent proxy (from a payload key)
diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca.h b/ipaacalib/cpp/include/ipaaca/ipaaca.h
index 6be8178..bbcb2d4 100644
--- a/ipaacalib/cpp/include/ipaaca/ipaaca.h
+++ b/ipaacalib/cpp/include/ipaaca/ipaaca.h
@@ -75,15 +75,19 @@
 #endif
 
 #ifdef IPAACA_DEBUG_MESSAGES
-#define IPAACA_DEBUG(i) std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << "() -- " << i << std::endl;
-#define IPAACA_INFO(i) std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << "() -- " << i << std::endl;
-#define IPAACA_WARNING(i) std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << "() -- WARNING: " << i << std::endl;
-#define IPAACA_IMPLEMENT_ME std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << "() -- IMPLEMENT ME" << std::endl;
-#define IPAACA_TODO(i) std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << "() -- TODO: " << i << std::endl;
+#define IPAACA_DEBUG(i)     if (__ipaaca_static_option_log_level>=IPAACA_LOG_LEVEL_DEBUG) { std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << "() -- Debug: " << i << std::endl; }
+#define IPAACA_INFO(i)      if (__ipaaca_static_option_log_level>=IPAACA_LOG_LEVEL_INFO) { std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << "() -- Info: " << i << std::endl; }
+#define IPAACA_WARNING(i)   if (__ipaaca_static_option_log_level>=IPAACA_LOG_LEVEL_WARNING) { std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << "() -- WARNING: " << i << std::endl; }
+#define IPAACA_ERROR(i)     if (__ipaaca_static_option_log_level>=IPAACA_LOG_LEVEL_ERROR) { std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << "() -- ERROR: " << i << std::endl; }
+#define IPAACA_CRITICAL(i)  if (__ipaaca_static_option_log_level>=IPAACA_LOG_LEVEL_CRITICAL) { std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << "() -- CRITICAL: " << i << std::endl; }
+#define IPAACA_IMPLEMENT_ME if (__ipaaca_static_option_log_level>=IPAACA_LOG_LEVEL_INFO) { std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << "() -- IMPLEMENT_ME:" << std::endl; }
+#define IPAACA_TODO(i)      if (__ipaaca_static_option_log_level>=IPAACA_LOG_LEVEL_INFO) { std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION_NAME__ << "() -- TODO: " << i << std::endl; }
 #else
 #define IPAACA_DEBUG(i) ;
 #define IPAACA_INFO(i) ;
 #define IPAACA_WARNING(i) ;
+#define IPAACA_ERROR(i) ;
+#define IPAACA_CRITICAL(i) ;
 #define IPAACA_IMPLEMENT_ME ;
 #define IPAACA_TODO(i) ;
 #endif
@@ -171,6 +175,7 @@ namespace ipaaca {
 // Actual initial values are set in ipaaca.cc
 IPAACA_MEMBER_VAR_EXPORT extern std::string __ipaaca_static_option_default_payload_type;
 IPAACA_MEMBER_VAR_EXPORT extern std::string __ipaaca_static_option_default_channel;
+IPAACA_MEMBER_VAR_EXPORT extern unsigned int __ipaaca_static_option_log_level;
 
 IPAACA_MEMBER_VAR_EXPORT Lock& logger_lock();
 
diff --git a/ipaacalib/cpp/src/ipaaca-cmdline-parser.cc b/ipaacalib/cpp/src/ipaaca-cmdline-parser.cc
index 89ae559..e08b33e 100644
--- a/ipaacalib/cpp/src/ipaaca-cmdline-parser.cc
+++ b/ipaacalib/cpp/src/ipaaca-cmdline-parser.cc
@@ -96,7 +96,6 @@ void CommandLineParser::initialize_parser_defaults()
 
 bool CommandLineParser::consume_library_option(const std::string& name, bool expect, const char* optarg)
 {
-	IPAACA_DEBUG("Trying to consume " << name)
 	if (name=="ipaaca-payload-type") {
 		std::string newtype = optarg;
 		if (newtype=="MAP") newtype="STR";
@@ -111,10 +110,31 @@ bool CommandLineParser::consume_library_option(const std::string& name, bool exp
 		IPAACA_DEBUG("Setting default channel " << newch)
 		__ipaaca_static_option_default_channel = newch;
 	} else if (name=="ipaaca-enable-logging") {
-		IPAACA_DEBUG("TODO: set ipaaca log level to " << optarg)
-		IPAACA_IMPLEMENT_ME
+		std::string level(optarg);
+		if ((level=="NONE") || (level=="SILENT")) {
+			IPAACA_DEBUG("Will set log level to NONE")
+			__ipaaca_static_option_log_level = IPAACA_LOG_LEVEL_NONE;
+		} else if (level=="DEBUG") {
+			__ipaaca_static_option_log_level = IPAACA_LOG_LEVEL_DEBUG;
+			IPAACA_DEBUG("Just set log level to DEBUG")
+		} else if (level=="INFO") {
+			IPAACA_DEBUG("Set log level to INFO")
+			__ipaaca_static_option_log_level = IPAACA_LOG_LEVEL_INFO;
+		} else if (level=="WARNING") {
+			IPAACA_DEBUG("Set log level to WARNING")
+			__ipaaca_static_option_log_level = IPAACA_LOG_LEVEL_WARNING;
+		} else if (level=="ERROR") {
+			IPAACA_DEBUG("Set log level to ERROR")
+			__ipaaca_static_option_log_level = IPAACA_LOG_LEVEL_ERROR;
+		} else if (level=="CRITICAL") {
+			IPAACA_DEBUG("Set log level to CRITICAL")
+			__ipaaca_static_option_log_level = IPAACA_LOG_LEVEL_CRITICAL;
+		} else {
+			IPAACA_WARNING("Unknown log level " << optarg)
+			IPAACA_WARNING("Valid levels are: NONE, DEBUG, INFO, WARNING, ERROR, CRITICAL ")
+		}
 	} else if (name=="rsb-enable-logging") {
-		IPAACA_DEBUG("TODO: set rsb log level to " << optarg)
+		IPAACA_WARNING("Unimplemented option ignored: " << name)
 		IPAACA_IMPLEMENT_ME
 	} else {
 		return false;
diff --git a/ipaacalib/cpp/src/ipaaca-json.cc b/ipaacalib/cpp/src/ipaaca-json.cc
index f7fe00e..943f89e 100644
--- a/ipaacalib/cpp/src/ipaaca-json.cc
+++ b/ipaacalib/cpp/src/ipaaca-json.cc
@@ -39,7 +39,26 @@
 using namespace rapidjson;
 using namespace std;
 
-int json_testbed_main(int argc, char** argv)
+int iterators_main(int argc, char** argv)//{{{
+{
+	std::string json_source("[\"old\",2,3,{\"key1\":\"value1\", \"key2\":\"value2\"}]");
+	ipaaca::PayloadDocumentEntry::ptr entry = ipaaca::PayloadDocumentEntry::from_json_string_representation(json_source);
+	
+	ipaaca::FakeIU::ptr iu = ipaaca::FakeIU::create();
+	iu->add_fake_payload_item("a", entry);
+	iu->payload()["b"] = "simpleString";
+	iu->payload()["c"] = "anotherSimpleString";
+	
+	std::cout << "Iterate over payload" << std::endl;
+	for (auto it = iu->payload().begin(); it != iu->payload().end(); ++it) {
+		std::cout << "  " << it->first << " -> " << it->second << std::endl;
+	}
+	
+	return 0;
+}
+//}}}
+
+int json_testbed_main(int argc, char** argv)//{{{
 {
 	std::string json_source("[\"old\",2,3,4]");
 	ipaaca::PayloadDocumentEntry::ptr entry = ipaaca::PayloadDocumentEntry::from_json_string_representation(json_source);
@@ -53,7 +72,6 @@ int json_testbed_main(int argc, char** argv)
 	iu->payload()["c"] = "simpleString";
 	
 	auto proxy = iu->payload()["a"][3];
-	std::cout << proxy << std::endl;
 	
 	std::cout << "IU payload before: " << iu->payload() << std::endl;
 	std::cout << "Entry before:      " << entry << std::endl;
@@ -74,9 +92,9 @@ int json_testbed_main(int argc, char** argv)
 	
 	return 0;
 }
+//}}}
 
-
-int fakeiu_main(int argc, char** argv)
+int fakeiu_main(int argc, char** argv)//{{{
 {
 	//if (argc<2) {
 	//	std::cout << "Please provide json content as the first argument." << std::endl;
@@ -198,20 +216,11 @@ int fakeiu_main(int argc, char** argv)
 	for (auto& kv: pl_flat) {
 		std::cout << "  " << std::left << std::setw(15) << (kv.first+": ") << kv.second << std::endl;
 	}
-	/*{
-		StringBuffer buffer;
-		Writer<StringBuffer> writer(buffer);
-		entry->document.Accept(writer);
-		std::string docstring = buffer.GetString();
-		std::cout << "Final document:  " << docstring << std::endl;
-	}*/
-	
-	// Done
 	return 0;
 }
+//}}}
 
-
-int legacy_iu_main(int argc, char** argv)
+int legacy_iu_main(int argc, char** argv)//{{{
 {
 	// produce and fill a new and a legacy IU with identical contents
 	
@@ -221,7 +230,7 @@ int legacy_iu_main(int argc, char** argv)
 	});
 	std::cout << "--- Create IUs with category jsonTest" << std::endl;
 	ipaaca::IU::ptr iu1 = ipaaca::IU::create("jsonTest");
-	ipaaca::IU::ptr iu2 = ipaaca::IU::create("jsonTest", "STR");
+	ipaaca::IU::ptr iu2 = ipaaca::IU::create("jsonTest", "STR"); // explicity request old payload
 	std::map<std::string, long> newmap = { {"fifty", 50}, {"ninety-nine", 99} };
 	std::cout << "--- Set map" << std::endl;
 	iu1->payload()["map"] = newmap;
@@ -236,8 +245,9 @@ int legacy_iu_main(int argc, char** argv)
 	sleep(5);
 	return 0;
 }
+//}}}
 
-int iu_main(int argc, char** argv)
+int iu_main(int argc, char** argv)//{{{
 {
 	ipaaca::InputBuffer::ptr ib = ipaaca::InputBuffer::create("jsonTestReceiver", "jsonTest");
 	ib->register_handler([](ipaaca::IUInterface::ptr iu, ipaaca::IUEventType event_type, bool local) {
@@ -285,13 +295,15 @@ int iu_main(int argc, char** argv)
 	std::cout << "--- Terminating " << std::endl;
 	return 0;
 }
+//}}}
 
 int main(int argc, char** argv)
 {
 	ipaaca::CommandLineParser::ptr parser = ipaaca::CommandLineParser::create();
 	ipaaca::CommandLineOptions::ptr options = parser->parse(argc, argv);
 
-	return json_testbed_main(argc, argv);
+	return iterators_main(argc, argv);
+	//return json_testbed_main(argc, argv);
 	//return legacy_iu_main(argc, argv);
 	//return fakeiu_main(argc, argv);
 	//return iu_main(argc, argv);
diff --git a/ipaacalib/cpp/src/ipaaca-payload.cc b/ipaacalib/cpp/src/ipaaca-payload.cc
index 8f22279..5989272 100644
--- a/ipaacalib/cpp/src/ipaaca-payload.cc
+++ b/ipaacalib/cpp/src/ipaaca-payload.cc
@@ -728,6 +728,12 @@ IPAACA_EXPORT std::pair<std::string, PayloadEntryProxy> PayloadIterator::operato
 	if (raw_iterator == _payload->_document_store.end()) throw PayloadIteratorInvalidError();
 	return std::pair<std::string, PayloadEntryProxy>(raw_iterator->first, PayloadEntryProxy(_payload, raw_iterator->first));
 }
+IPAACA_EXPORT std::shared_ptr<std::pair<std::string, PayloadEntryProxy> > PayloadIterator::operator->()
+{
+	if (_payload->revision_changed(reference_payload_revision)) throw PayloadIteratorInvalidError();
+	if (raw_iterator == _payload->_document_store.end()) throw PayloadIteratorInvalidError();
+	return std::make_shared<std::pair<std::string, PayloadEntryProxy> >(raw_iterator->first, PayloadEntryProxy(_payload, raw_iterator->first));
+}
 
 IPAACA_EXPORT bool PayloadIterator::operator==(const PayloadIterator& ref)
 {
diff --git a/ipaacalib/cpp/src/ipaaca.cc b/ipaacalib/cpp/src/ipaaca.cc
index f72857e..2e7f995 100644
--- a/ipaacalib/cpp/src/ipaaca.cc
+++ b/ipaacalib/cpp/src/ipaaca.cc
@@ -74,6 +74,7 @@ IPAACA_EXPORT std::string generate_uuid_string()//{{{
 
 IPAACA_EXPORT std::string __ipaaca_static_option_default_payload_type("JSON");
 IPAACA_EXPORT std::string __ipaaca_static_option_default_channel("default");
+IPAACA_EXPORT unsigned int __ipaaca_static_option_log_level(IPAACA_LOG_LEVEL_WARNING);
 
 /*
 void init_inprocess_too() {
-- 
GitLab