From b6d855c10896bfe06516e5456f1c28528db5a9fe Mon Sep 17 00:00:00 2001 From: Ramin Yaghoubzadeh <ryaghoubzadeh@uni-bielefeld.de> Date: Sat, 28 Mar 2015 23:05:19 +0100 Subject: [PATCH] C++: added push_back() and extend() for proxy arguments --- ipaacalib/cpp/include/ipaaca/ipaaca-payload.h | 31 +++++++++++++++++-- ipaacalib/cpp/src/ipaaca-json.cc | 9 ++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h b/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h index aad0f3f..58386e7 100644 --- a/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h +++ b/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h @@ -505,8 +505,20 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{ list.PushBack(newval, new_entry->document.GetAllocator()); _payload->set(_key, new_entry); } - /// Alias for push_back() (somewhat pythonic - since we also provide extend()) - IPAACA_HEADER_EXPORT template<typename T> void append(T t) { push_back<T>(t); } + /// Append the value of another proxy (or a null value) to a list-type value + IPAACA_HEADER_EXPORT void push_back(const PayloadEntryProxy& otherproxy) + { + if ((!json_value) || (!json_value->IsArray())) throw PayloadAddressingError(); + PayloadDocumentEntry::ptr new_entry = document_entry->clone(); // copy-on-write, no lock required + rapidjson::Value& list = new_entry->get_or_create_nested_value_from_proxy_path(this); + rapidjson::Value newval; + auto valueptr = otherproxy.json_value; + if (valueptr) { // only set if value is valid, keep default null value otherwise + newval.CopyFrom(*valueptr, new_entry->document.GetAllocator()); + } + list.PushBack(newval, new_entry->document.GetAllocator()); + _payload->set(_key, new_entry); + } /// Extend a list-type payload value with a vector containing items of a supported type IPAACA_HEADER_EXPORT template<typename T> void extend(const std::vector<T>& ts) { @@ -533,6 +545,21 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{ } _payload->set(_key, new_entry); } + /// Extend a list-type payload value with items (copies) from another list-type value + IPAACA_HEADER_EXPORT void extend(const PayloadEntryProxy& otherproxy) + { + if ((!json_value) || (!json_value->IsArray())) throw PayloadAddressingError(); + if ((!otherproxy.json_value) || (!(otherproxy.json_value->IsArray()))) throw PayloadAddressingError(); + PayloadDocumentEntry::ptr new_entry = document_entry->clone(); // copy-on-write, no lock required + rapidjson::Value& list = new_entry->get_or_create_nested_value_from_proxy_path(this); + for (size_t i=0; i<otherproxy.json_value->Size(); ++i) { + rapidjson::Value newval; + rapidjson::Value& value = (*(otherproxy.json_value))[i]; + newval.CopyFrom(value, new_entry->document.GetAllocator()); + list.PushBack(newval, new_entry->document.GetAllocator()); + } + _payload->set(_key, new_entry); + } }; // Available interpretations of payload entries (or children thereof) below. // Usage of standard complex data structures (vector etc.) currently entails diff --git a/ipaacalib/cpp/src/ipaaca-json.cc b/ipaacalib/cpp/src/ipaaca-json.cc index e0a0888..fb0aa13 100644 --- a/ipaacalib/cpp/src/ipaaca-json.cc +++ b/ipaacalib/cpp/src/ipaaca-json.cc @@ -66,6 +66,7 @@ int iterators_main(int argc, char** argv)//{{{ iu->payload()["d"] = 100; iu->payload()["e"] = 3l; iu->payload()["f"] = "12.5000"; + iu->payload()["g"] = std::vector<std::string>{"g1", "g2"}; std::cout << std::endl << "Iterate over payload" << std::endl; for (auto it = iu->payload().begin(); it != iu->payload().end(); ++it) { @@ -166,6 +167,14 @@ int iterators_main(int argc, char** argv)//{{{ std::cout << " " << v << std::endl; } + std::cout << std::endl << "Extending payload['a'] by payload['g'] and appending payload['f']" << std::endl; + iu->payload()["a"].extend(iu->payload()["g"]); + iu->payload()["a"].push_back(iu->payload()["f"]); + std::cout << "Resulting entries in payload['a']:" << std::endl; + for (auto v: iu->payload()["a"].as_list()) { + std::cout << " " << v << std::endl; + } + return 0; } //}}} -- GitLab