diff --git a/ipaacalib/cpp/CMakeLists.txt b/ipaacalib/cpp/CMakeLists.txt index 4a621513fd1cd8280dcea7423321fd9ea64209bb..891d01e744a0cf944402e8425c38d48bf7120ed2 100644 --- a/ipaacalib/cpp/CMakeLists.txt +++ b/ipaacalib/cpp/CMakeLists.txt @@ -106,6 +106,7 @@ else() # change for each new rsb version if (DEFINED APPLE) set(RSBLIBS rsc0.11 rsb0.11) + #set(RSBLIBS rsc0.10 rsb.0.10) else(DEFINED APPLE) set(RSBLIBS ${PROJECT_SOURCE_DIR}/../../deps/lib/librsc0.11.so ${PROJECT_SOURCE_DIR}/../../deps/lib/librsb0.11.so ) set(LIBS ${LIBS} uuid) @@ -136,6 +137,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_OLD_CODE_CONVENIENCE_FLAGS} ${IPAA # add for for each new rsb version include_directories( ${PROJECT_SOURCE_DIR}/../../deps/include/rsc0.11 ) include_directories( ${PROJECT_SOURCE_DIR}/../../deps/include/rsb0.11 ) +#include_directories( ${PROJECT_SOURCE_DIR}/../../deps/include/rsc0.10 ) +#include_directories( ${PROJECT_SOURCE_DIR}/../../deps/include/rsb0.10 ) # add include dir for auto-generated headers placed in build/ include_directories( ${PROJECT_SOURCE_DIR}/build ) @@ -164,8 +167,10 @@ set (SOURCE ) set (JSON_TEST_SOURCE + src/ipaaca.cc src/ipaaca-buffers.cc src/ipaaca-fake.cc + src/ipaaca-internal.cc src/ipaaca-iuinterface.cc src/ipaaca-json.cc # main src/ipaaca-locking.cc @@ -174,6 +179,7 @@ set (JSON_TEST_SOURCE src/ipaaca-string-utils.cc # more stuff going beyond the fake test case src/ipaaca-ius.cc + build/ipaaca/ipaaca.pb.cc ) diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca-internal.h b/ipaacalib/cpp/include/ipaaca/ipaaca-internal.h index 2bc528b1d5657c126b52d9386c2b696090e11e1b..a94e2e4c3449e12d5b2fb6c788c354d8c93c268f 100644 --- a/ipaacalib/cpp/include/ipaaca/ipaaca-internal.h +++ b/ipaacalib/cpp/include/ipaaca/ipaaca-internal.h @@ -41,7 +41,7 @@ #ifdef IPAACA_EXPOSE_FULL_RSB_API -IPAACA_HEADER_EXPORT inline std::string json_to_string(PayloadDocumentEntry::ptr entry); +// ??? ///IPAACA_HEADER_EXPORT inline std::string json_to_string(PayloadDocumentEntry::ptr entry); IPAACA_HEADER_EXPORT class CallbackIUPayloadUpdate: public rsb::patterns::Server::Callback<IUPayloadUpdate, int> {//{{{ protected: diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca-ius.h b/ipaacalib/cpp/include/ipaaca/ipaaca-ius.h index c22e9a1e1d61620e114ba00b49a58222adc9aaff..03bd9a3531f5f49f4383f8ed5175933fc12b082f 100644 --- a/ipaacalib/cpp/include/ipaaca/ipaaca-ius.h +++ b/ipaacalib/cpp/include/ipaaca/ipaaca-ius.h @@ -73,8 +73,8 @@ IPAACA_HEADER_EXPORT class IUInterface {//{{{ IPAACA_HEADER_EXPORT void _set_owner_name(const std::string& owner_name); protected: // internal functions that do not emit update events - IPAACA_HEADER_EXPORT inline void _add_and_remove_links(const LinkMap& add, const LinkMap& remove) { _links._add_and_remove_links(add, remove); } - IPAACA_HEADER_EXPORT inline void _replace_links(const LinkMap& links) { _links._replace_links(links); } + IPAACA_HEADER_EXPORT void _add_and_remove_links(const LinkMap& add, const LinkMap& remove) { _links._add_and_remove_links(add, remove); } + IPAACA_HEADER_EXPORT void _replace_links(const LinkMap& links) { _links._replace_links(links); } public: IPAACA_HEADER_EXPORT inline bool is_published() { return (_buffer != 0); } IPAACA_HEADER_EXPORT inline const std::string& uid() const { return _uid; } diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h b/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h index 7199a365a777c6026e834e5dffb45bd99920a4bc..d32c4f2264f7e2687fa96ff35273f77d9c8cd204 100644 --- a/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h +++ b/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h @@ -50,12 +50,12 @@ IPAACA_HEADER_EXPORT template<> std::list<std::string> json_value_cast(const rap IPAACA_HEADER_EXPORT template<> std::map<std::string, std::string> json_value_cast(const rapidjson::Value&); // helpers to set Value& from various standard types -IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, T t); -IPAACA_HEADER_EXPORT template<> void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, long); -IPAACA_HEADER_EXPORT template<> void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, double); -IPAACA_HEADER_EXPORT template<> void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, bool); -IPAACA_HEADER_EXPORT template<> void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, const std::string&); -IPAACA_HEADER_EXPORT template<> void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, const char*); +//IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, T t); +IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, long); +IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, double); +IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, bool); +IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, const std::string&); +IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, const char*); // helpers to set Value& from several standard containers containing the above standard types /// set Value& from vector<T> IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::vector<T>& ts) @@ -63,7 +63,7 @@ IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::V valueobject.SetArray(); for (auto& val: ts) { rapidjson::Value newv; - pack_into_json_value<T>(newv, allocator, val); + pack_into_json_value(newv, allocator, val); valueobject.PushBack(newv, allocator); } } @@ -73,7 +73,7 @@ IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::V valueobject.SetArray(); for (auto& val: ts) { rapidjson::Value newv; - pack_into_json_value<T>(newv, allocator, val); + pack_into_json_value(newv, allocator, val); valueobject.PushBack(newv, allocator); } } @@ -85,7 +85,7 @@ IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::V rapidjson::Value key; key.SetString(val.first, allocator); rapidjson::Value newv; - pack_into_json_value<T>(newv, allocator, val.second); + pack_into_json_value(newv, allocator, val.second); valueobject.AddMember(key, newv, allocator); } } @@ -111,6 +111,7 @@ IPAACA_HEADER_EXPORT class PayloadDocumentEntry//{{{ IPAACA_HEADER_EXPORT static std::shared_ptr<PayloadDocumentEntry> create_null(); IPAACA_HEADER_EXPORT std::shared_ptr<PayloadDocumentEntry> clone(); IPAACA_HEADER_EXPORT rapidjson::Value& get_or_create_nested_value_from_proxy_path(PayloadEntryProxy* pep); + IPAACA_HEADER_EXPORT void update_json_source(); typedef std::shared_ptr<PayloadDocumentEntry> ptr; }; //}}} @@ -215,6 +216,7 @@ IPAACA_HEADER_EXPORT class Payload//{{{ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{ { + friend std::ostream& operator<<(std::ostream& os, const PayloadEntryProxy& proxy); protected: public: //IPAACA_MEMBER_VAR_EXPORT rapidjson::Document* _json_parent_node; @@ -257,6 +259,7 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{ PayloadDocumentEntry::ptr new_entry = document_entry->clone(); // copy-on-write, no lock required rapidjson::Value& newval = new_entry->get_or_create_nested_value_from_proxy_path(this); pack_into_json_value(newval, new_entry->document.GetAllocator(), t); + new_entry->update_json_source(); _payload->set(_key, new_entry); return *this; } diff --git a/ipaacalib/cpp/src/ipaaca-buffers.cc b/ipaacalib/cpp/src/ipaaca-buffers.cc index b6398a0ae43d11ce296c56750e272841596f0773..a485d04eaeda454bfdf1390331305524551744f4 100644 --- a/ipaacalib/cpp/src/ipaaca-buffers.cc +++ b/ipaacalib/cpp/src/ipaaca-buffers.cc @@ -170,6 +170,7 @@ IPAACA_EXPORT CallbackIUResendRequest::CallbackIUResendRequest(Buffer* buffer): IPAACA_EXPORT boost::shared_ptr<int> CallbackIUPayloadUpdate::call(const std::string& methodName, boost::shared_ptr<IUPayloadUpdate> update) { + IPAACA_INFO("") //std::cout << "-- Received a modify_payload with " << update->new_items.size() << " keys to merge." << std::endl; IUInterface::ptr iui = _buffer->get(update->uid); if (! iui) { @@ -180,6 +181,7 @@ IPAACA_EXPORT boost::shared_ptr<int> CallbackIUPayloadUpdate::call(const std::st iu->_revision_lock.lock(); if ((update->revision != 0) && (update->revision != iu->_revision)) { IPAACA_INFO("Remote write operation failed because request was out of date; IU " << update->uid) + IPAACA_INFO(" Referred-to revision was " << update->revision << " while local one is " << iu->_revision) iu->_revision_lock.unlock(); return boost::shared_ptr<int>(new int(0)); } @@ -287,8 +289,8 @@ IPAACA_EXPORT OutputBuffer::OutputBuffer(const std::string& basename, const std: IPAACA_EXPORT void OutputBuffer::_initialize_server() { //IPAACA_INFO("Entering ...") - //IPAACA_INFO("Calling createLocalServer(\"" << _unique_name << "\")") - _server = getFactory().createLocalServer( Scope( _unique_name ) ); + //_server = getFactory().createLocalServer( Scope( _unique_name ) ); + _server = getFactory().createServer( Scope( _unique_name ) ); //IPAACA_INFO("Registering methods") _server->registerMethod("updatePayload", Server::CallbackPtr(new CallbackIUPayloadUpdate(this))); _server->registerMethod("updateLinks", Server::CallbackPtr(new CallbackIULinkUpdate(this))); diff --git a/ipaacalib/cpp/src/ipaaca-internal.cc b/ipaacalib/cpp/src/ipaaca-internal.cc index 6b3e4c89fee0802d4ff7c03a7a88a056c7b4e285..d9a890f7f1cb1f88b32cfa8f79d72c2d1f75d6bf 100644 --- a/ipaacalib/cpp/src/ipaaca-internal.cc +++ b/ipaacalib/cpp/src/ipaaca-internal.cc @@ -171,7 +171,7 @@ IPAACA_EXPORT std::string IUConverter::serialize(const AnnotatedData& data, std: for (auto& kv: obj->_payload._document_store) { protobuf::PayloadItem* item = pbo->add_payload(); item->set_key(kv.first); - item->set_value( kv.second.document.to_json_string_representation() ); + item->set_value( kv.second->to_json_string_representation() ); item->set_type("json"); } for (LinkMap::const_iterator it=obj->_links._links.begin(); it!=obj->_links._links.end(); ++it) { @@ -221,7 +221,7 @@ IPAACA_EXPORT AnnotatedData IUConverter::deserialize(const std::string& wireSche PayloadDocumentEntry::ptr entry; if (it.type() == "json") { // fully parse json text - entry = PayloadDocumentEntry::from_json_string_representation( it.value() ) + entry = PayloadDocumentEntry::from_json_string_representation( it.value() ); } else { // assuming legacy "str" -> just copy value to raw string in document entry = std::make_shared<PayloadDocumentEntry>(); @@ -259,7 +259,7 @@ IPAACA_EXPORT AnnotatedData IUConverter::deserialize(const std::string& wireSche PayloadDocumentEntry::ptr entry; if (it.type() == "json") { // fully parse json text - entry = PayloadDocumentEntry::from_json_string_representation( it.value() ) + entry = PayloadDocumentEntry::from_json_string_representation( it.value() ); } else { // assuming legacy "str" -> just copy value to raw string in document entry = std::make_shared<PayloadDocumentEntry>(); @@ -323,7 +323,7 @@ IPAACA_EXPORT std::string MessageConverter::serialize(const AnnotatedData& data, for (auto& kv: obj->_payload._document_store) { protobuf::PayloadItem* item = pbo->add_payload(); item->set_key(kv.first); - item->set_value( kv.second.document.to_json_string_representation() ); + item->set_value( kv.second->to_json_string_representation() ); item->set_type("json"); } for (LinkMap::const_iterator it=obj->_links._links.begin(); it!=obj->_links._links.end(); ++it) { @@ -370,7 +370,7 @@ IPAACA_EXPORT AnnotatedData MessageConverter::deserialize(const std::string& wir PayloadDocumentEntry::ptr entry; if (it.type() == "json") { // fully parse json text - entry = PayloadDocumentEntry::from_json_string_representation( it.value() ) + entry = PayloadDocumentEntry::from_json_string_representation( it.value() ); } else { // assuming legacy "str" -> just copy value to raw string in document entry = std::make_shared<PayloadDocumentEntry>(); @@ -407,7 +407,7 @@ IPAACA_EXPORT AnnotatedData MessageConverter::deserialize(const std::string& wir PayloadDocumentEntry::ptr entry; if (it.type() == "json") { // fully parse json text - entry = PayloadDocumentEntry::from_json_string_representation( it.value() ) + entry = PayloadDocumentEntry::from_json_string_representation( it.value() ); } else { // assuming legacy "str" -> just copy value to raw string in document entry = std::make_shared<PayloadDocumentEntry>(); @@ -453,7 +453,7 @@ IPAACA_EXPORT std::string IUPayloadUpdateConverter::serialize(const AnnotatedDat for (auto& kv: obj->new_items) { protobuf::PayloadItem* item = pbo->add_new_items(); item->set_key(kv.first); - item->set_value( kv.second.document.to_json_string_representation() ); + item->set_value( kv.second->to_json_string_representation() ); item->set_type("json"); } for (auto& key: obj->keys_to_remove) { @@ -479,7 +479,8 @@ AnnotatedData IUPayloadUpdateConverter::deserialize(const std::string& wireSchem PayloadDocumentEntry::ptr entry; if (it.type() == "json") { // fully parse json text - entry = PayloadDocumentEntry::from_json_string_representation( it.value() ) + entry = PayloadDocumentEntry::from_json_string_representation( it.value() ); + IPAACA_INFO("New/updated payload entry: " << it.key() << " -> " << it.value() ) } else { // assuming legacy "str" -> just copy value to raw string in document entry = std::make_shared<PayloadDocumentEntry>(); diff --git a/ipaacalib/cpp/src/ipaaca-ius.cc b/ipaacalib/cpp/src/ipaaca-ius.cc index 8a9aad15314c78a79f1b236549dbfdc566414b63..2c4b0643d2728c65dc780153c264742c4eb2f4a1 100644 --- a/ipaacalib/cpp/src/ipaaca-ius.cc +++ b/ipaacalib/cpp/src/ipaaca-ius.cc @@ -97,6 +97,7 @@ IPAACA_EXPORT void IU::_modify_links(bool is_delta, const LinkMap& new_links, co IPAACA_EXPORT void IU::_modify_payload(bool is_delta, const std::map<std::string, PayloadDocumentEntry::ptr>& new_items, const std::vector<std::string>& keys_to_remove, const std::string& writer_name) { + IPAACA_INFO("") _revision_lock.lock(); if (_committed) { _revision_lock.unlock(); diff --git a/ipaacalib/cpp/src/ipaaca-json.cc b/ipaacalib/cpp/src/ipaaca-json.cc index fde7d209b2bbc77de753db22b3adca016a7db96e..deb817f05f586ec4fa4839f9ffab8c392634eb13 100644 --- a/ipaacalib/cpp/src/ipaaca-json.cc +++ b/ipaacalib/cpp/src/ipaaca-json.cc @@ -151,12 +151,50 @@ int fakeiu_main(int argc, char** argv) return 0; } + + int iu_main(int argc, char** argv) { - ipaaca::IU::ptr iu = ipaaca::IU::create("testcategory"); + ipaaca::InputBuffer::ptr ib = ipaaca::InputBuffer::create("jsonTestReceiver", "jsonTest"); + ib->register_handler([](ipaaca::IUInterface::ptr iu, ipaaca::IUEventType event_type, bool local) { + if (event_type==IU_ADDED) { + std::cout << "Received a new IU, payload: " << iu->payload() << std::endl; + std::cout << "Will write something." << std::endl; + // iu->commit(); + iu->payload()["list"][0] = "Overridden from C++"; + } + }); + std::cout << "--- Waiting for IUs for 10s " << std::endl; + sleep(10); + return 0; + + ipaaca::OutputBuffer::ptr ob = ipaaca::OutputBuffer::create("jsonTestSender"); + ob->register_handler([](ipaaca::IUInterface::ptr iu, ipaaca::IUEventType event_type, bool local) { + std::cout << "Received remote update, new payload: " << iu->payload() << std::endl; + }); + std::cout << "--- Create IU with category jsonTest" << std::endl; + ipaaca::IU::ptr iu = ipaaca::IU::create("jsonTest"); std::map<std::string, long> newmap = { {"fifty", 50}, {"ninety-nine", 99} }; + std::cout << "--- Set map" << std::endl; iu->payload()["map"] = newmap; - iu->payload()["map"]["str_array"] = std::vector<std::string>{"str1", "str2"}; + std::cout << "--- Publishing IU with this payload:" << std::endl; + std::cout << iu->payload() << std::endl; + ob->add(iu); + std::cout << "--- Waiting for changes for 5s before next write" << std::endl; + sleep(5); + std::cout << "--- Contents of map after 5s" << std::endl; + std::cout << iu->payload()["map"] << std::endl; + // + std::cout << "--- Creating a list" << std::endl; + std::vector<long> newlist = { 1, 0 }; + iu->payload()["list"] = newlist; + std::cout << "--- Waiting for changes for 5s " << std::endl; + sleep(5); + std::cout << "--- Final map " << std::endl; + std::cout << iu->payload()["map"] << std::endl; + std::cout << "--- Final list " << std::endl; + std::cout << iu->payload()["list"] << std::endl; + std::cout << "--- Terminating " << std::endl; return 0; } diff --git a/ipaacalib/cpp/src/ipaaca-payload.cc b/ipaacalib/cpp/src/ipaaca-payload.cc index 0026dc7c8d3a954c3e872fbdcd2b3d292ea81da5..bea8bfda8728170233b9a316348e4704384e2bce 100644 --- a/ipaacalib/cpp/src/ipaaca-payload.cc +++ b/ipaacalib/cpp/src/ipaaca-payload.cc @@ -42,12 +42,34 @@ using namespace rsb::filter; using namespace rsb::converter; using namespace rsb::patterns; +// temporary helper to show rapidjson internal type +std::string value_diagnosis(rapidjson::Value* val) +{ + if (!val) return "nullptr"; + if (val->IsNull()) return "null"; + if (val->IsString()) return "string"; + if (val->IsNumber()) return "number"; + if (val->IsBool()) return "bool"; + if (val->IsArray()) return "array"; + if (val->IsObject()) return "object"; + return "other"; + +} + + IPAACA_EXPORT std::ostream& operator<<(std::ostream& os, const rapidjson::Value& val)//{{{ { os << json_value_cast<std::string>(val); return os; } //}}} +IPAACA_EXPORT std::ostream& operator<<(std::ostream& os, const PayloadEntryProxy& proxy)//{{{ +{ + if (proxy.json_value) os << *(proxy.json_value); + else os << "null"; + return os; +} +//}}} IPAACA_EXPORT std::ostream& operator<<(std::ostream& os, PayloadDocumentEntry::ptr entry)//{{{ { os << json_value_cast<std::string>(entry->document); @@ -139,23 +161,23 @@ IPAACA_EXPORT template<> bool json_value_cast(const rapidjson::Value& v) */ //}}} -IPAACA_EXPORT template<> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, long newvalue) +IPAACA_EXPORT void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, long newvalue) { valueobject.SetInt(newvalue); } -IPAACA_EXPORT template<> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, double newvalue) +IPAACA_EXPORT void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, double newvalue) { valueobject.SetDouble(newvalue); } -IPAACA_EXPORT template<> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, bool newvalue) +IPAACA_EXPORT void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, bool newvalue) { valueobject.SetBool(newvalue); } -IPAACA_EXPORT template<> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::string& newvalue) +IPAACA_EXPORT void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::string& newvalue) { valueobject.SetString(newvalue.c_str(), allocator); } -IPAACA_EXPORT template<> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const char* newvalue) +IPAACA_EXPORT void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const char* newvalue) { valueobject.SetString(newvalue, allocator); } @@ -180,7 +202,7 @@ IPAACA_EXPORT template<> void pack_into_json_value(rapidjson::Value& valueobject */ // PayloadDocumentEntry//{{{ -IPAACA_EXPORT inline std::string PayloadDocumentEntry::to_json_string_representation() +IPAACA_EXPORT std::string PayloadDocumentEntry::to_json_string_representation() { rapidjson::StringBuffer buffer; rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); @@ -196,7 +218,15 @@ IPAACA_EXPORT PayloadDocumentEntry::ptr PayloadDocumentEntry::from_json_string_r entry->json_source = json_str; return entry; } -IPAACA_EXPORT inline PayloadDocumentEntry::ptr PayloadDocumentEntry::create_null() + +/// update json_source after a write operation (on newly cloned entries) +IPAACA_EXPORT void PayloadDocumentEntry::update_json_source() +{ + json_source = to_json_string_representation(); +} + + +IPAACA_EXPORT PayloadDocumentEntry::ptr PayloadDocumentEntry::create_null() { PayloadDocumentEntry::ptr entry = std::make_shared<ipaaca::PayloadDocumentEntry>(); entry->json_source = "null"; // rapidjson::Document value is also null implicitly @@ -204,17 +234,24 @@ IPAACA_EXPORT inline PayloadDocumentEntry::ptr PayloadDocumentEntry::create_null } IPAACA_EXPORT PayloadDocumentEntry::ptr PayloadDocumentEntry::clone() { - IPAACA_INFO("") - return PayloadDocumentEntry::from_json_string_representation(this->json_source); + IPAACA_INFO("Cloning from: " << this->json_source) + auto entry = PayloadDocumentEntry::from_json_string_representation(this->json_source); + IPAACA_INFO("Cloned entry contents: " << entry) + return entry; } IPAACA_EXPORT rapidjson::Value& PayloadDocumentEntry::get_or_create_nested_value_from_proxy_path(PayloadEntryProxy* pep) { if (!(pep->parent)) { IPAACA_INFO("Reached top-most parent") + IPAACA_INFO("doc contents: " << document ) + IPAACA_INFO("doc diag: " << value_diagnosis(&document)) return document; } - IPAACA_INFO("(Check parent)") + IPAACA_INFO("(Check parent ...)") rapidjson::Value& parent_value = get_or_create_nested_value_from_proxy_path(pep->parent); + IPAACA_INFO("(... back from parent)") + IPAACA_INFO("par contents: " << parent_value ) + IPAACA_INFO("par diag: " << value_diagnosis(&parent_value)) IPAACA_INFO("Resolving address path") if (pep->addressed_as_array) { IPAACA_INFO("Addressed as array with index " << pep->addressed_index) @@ -258,6 +295,10 @@ IPAACA_EXPORT rapidjson::Value& PayloadDocumentEntry::get_or_create_nested_value // addressed as object (dict) //rapidjson::Value& parent_value = *(pep->parent->json_value); if (! parent_value.IsObject()) { + IPAACA_INFO("parent is not of type Object") + IPAACA_INFO("parent contents: " << *(pep->parent) ) + IPAACA_INFO("parent_value contents: " << parent_value ) + IPAACA_INFO("parent_value diag: " << value_diagnosis(&parent_value)) throw PayloadAddressingError(); } else { rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); @@ -351,15 +392,15 @@ IPAACA_EXPORT void PayloadEntryProxy::connect_to_existing_parents() IPAACA_EXPORT PayloadEntryProxy::PayloadEntryProxy(Payload* payload, const std::string& key) : _payload(payload), _key(key), parent(nullptr) { - IPAACA_INFO("PEP construction on parent document ...") + //IPAACA_INFO("PEP construction on parent document ...") document_entry = _payload->get_entry(key); json_value = &(document_entry->document); - IPAACA_INFO("... parent done.") + //IPAACA_INFO("... parent done.") } IPAACA_EXPORT PayloadEntryProxy::PayloadEntryProxy(PayloadEntryProxy* parent_, const std::string& addr_key_) : parent(parent_), addressed_key(addr_key_), addressed_as_array(false) { - IPAACA_INFO("PEP construction as dict child, addressed by " << addr_key_ << " ...") + //IPAACA_INFO("PEP construction as dict child, addressed by " << addr_key_ << " ...") _payload = parent->_payload; _key = parent->_key; document_entry = parent->document_entry; @@ -376,7 +417,7 @@ IPAACA_EXPORT PayloadEntryProxy::PayloadEntryProxy(PayloadEntryProxy* parent_, c IPAACA_EXPORT PayloadEntryProxy::PayloadEntryProxy(PayloadEntryProxy* parent_, size_t addr_idx_) : parent(parent_), addressed_index(addr_idx_), addressed_as_array(true) { - IPAACA_INFO("PEP construction as array child, addressed by " << addr_idx_ << " ...") + //IPAACA_INFO("PEP construction as array child, addressed by " << addr_idx_ << " ...") _payload = parent->_payload; _key = parent->_key; document_entry = parent->document_entry; @@ -492,19 +533,6 @@ IPAACA_EXPORT bool PayloadEntryProxy::to_bool() } -std::string value_diagnosis(rapidjson::Value* val) -{ - if (!val) return "nullptr"; - if (val->IsNull()) return "null"; - if (val->IsString()) return "string"; - if (val->IsNumber()) return "number"; - if (val->IsBool()) return "bool"; - if (val->IsArray()) return "array"; - if (val->IsObject()) return "object"; - return "other"; - -} - // // new stuff for protocol v2 // @@ -583,13 +611,16 @@ IPAACA_EXPORT Payload::operator std::map<std::string, std::string>() } IPAACA_EXPORT void Payload::_internal_set(const std::string& k, PayloadDocumentEntry::ptr v, const std::string& writer_name) { + IPAACA_INFO("") std::map<std::string, PayloadDocumentEntry::ptr> _new; std::vector<std::string> _remove; _new[k] = v; _iu.lock()->_modify_payload(true, _new, _remove, writer_name ); + IPAACA_INFO(" Setting local payload item \"" << k << "\" to " << v) _document_store[k] = v; } IPAACA_EXPORT void Payload::_internal_remove(const std::string& k, const std::string& writer_name) { + IPAACA_INFO("") std::map<std::string, PayloadDocumentEntry::ptr> _new; std::vector<std::string> _remove; _remove.push_back(k); @@ -598,24 +629,29 @@ IPAACA_EXPORT void Payload::_internal_remove(const std::string& k, const std::st } IPAACA_EXPORT void Payload::_internal_replace_all(const std::map<std::string, PayloadDocumentEntry::ptr>& new_contents, const std::string& writer_name) { + IPAACA_INFO("") std::vector<std::string> _remove; _iu.lock()->_modify_payload(false, new_contents, _remove, writer_name ); _document_store = new_contents; } IPAACA_EXPORT void Payload::_internal_merge(const std::map<std::string, PayloadDocumentEntry::ptr>& contents_to_merge, const std::string& writer_name) { + IPAACA_INFO("") std::vector<std::string> _remove; _iu.lock()->_modify_payload(true, contents_to_merge, _remove, writer_name ); - _document_store.insert(contents_to_merge.begin(), contents_to_merge.end()); + for (auto& kv: contents_to_merge) { + _document_store[kv.first] = kv.second; + } + //_document_store.insert(contents_to_merge.begin(), contents_to_merge.end()); //for (std::map<std::string, std::string>::iterator it = contents_to_merge.begin(); it!=contents_to_merge.end(); i++) { // _store[it->first] = it->second; //} } -IPAACA_EXPORT inline PayloadDocumentEntry::ptr Payload::get_entry(const std::string& k) { +IPAACA_EXPORT PayloadDocumentEntry::ptr Payload::get_entry(const std::string& k) { if (_document_store.count(k)>0) return _document_store[k]; else return PayloadDocumentEntry::create_null(); // contains Document with 'null' value } -IPAACA_EXPORT inline std::string Payload::get(const std::string& k) { // DEPRECATED +IPAACA_EXPORT std::string Payload::get(const std::string& k) { // DEPRECATED if (_document_store.count(k)>0) return _document_store[k]->document.GetString(); return ""; } @@ -629,6 +665,7 @@ IPAACA_EXPORT void Payload::_remotely_enforced_delitem(const std::string& k) } IPAACA_EXPORT void Payload::_remotely_enforced_setitem(const std::string& k, PayloadDocumentEntry::ptr entry) { + IPAACA_INFO("Setting payload entry for \"" << k <<"\" to " << entry) _document_store[k] = entry; }