Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
* This file is part of IPAACA, the
* "Incremental Processing Architecture
* for Artificial Conversational Agents".
*
* Copyright (c) 2009-2015 Social Cognitive Systems Group
* (formerly the Sociable Agents Group)
* CITEC, Bielefeld University
*
* http://opensource.cit-ec.de/projects/ipaaca/
* http://purl.org/net/ipaaca
*
* This file may be licensed under the terms of of the
* GNU Lesser General Public License Version 3 (the ``LGPL''),
* or (at your option) any later version.
*
* Software distributed under the License is distributed
* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the LGPL for the specific language
* governing rights and limitations.
*
* You should have received a copy of the LGPL along with this
* program. If not, go to http://www.gnu.org/licenses/lgpl.html
* or write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The development of this software was supported by the
* Excellence Cluster EXC 277 Cognitive Interaction Technology.
* The Excellence Cluster EXC 277 is a grant of the Deutsche
* Forschungsgemeinschaft (DFG) in the context of the German
* Excellence Initiative.
*/
#include <ipaaca/ipaaca.h>
namespace ipaaca {
using namespace rsb;
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);
return os;
}
//}}}
IPAACA_EXPORT std::ostream& operator<<(std::ostream& os, const Payload& obj)//{{{
{
os << "{";
bool first = true;
for (auto& kv: obj._document_store) {
if (first) { first=false; } else { os << ", "; }

Ramin Yaghoubzadeh Torky
committed
os << "\"" << kv.first << "\":" << kv.second->to_json_string_representation() << "";
}
os << "}";
return os;
}
//}}}
double strict_numerical_interpretation(const std::string& str)
{
char* endptr;
auto s = str_trim(str);
const char* startptr = s.c_str();
long l = strtod(startptr, &endptr);
if ((*endptr)=='\0') {
// everything could be parsed
return l;
} else {
throw PayloadTypeConversionError();
}
}
IPAACA_EXPORT template<> std::string json_value_cast(const rapidjson::Value& v)
{
if (v.IsString()) return v.GetString();
if (v.IsNull()) return "";
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
v.Accept(writer);
return buffer.GetString();
}
IPAACA_EXPORT template<> long json_value_cast(const rapidjson::Value& v)
if (v.IsString()) return (long) strict_numerical_interpretation(v.GetString());
if (v.IsInt()) return v.GetInt();
if (v.IsUint()) return v.GetUint();
if (v.IsInt64()) return v.GetInt64();
if (v.IsUint64()) return v.GetUint64();
if (v.IsDouble()) return (long) v.GetDouble();
if (v.IsBool()) return v.GetBool() ? 1l : 0l;
if (v.IsNull()) return 0l;
// default: return parse of string version (should always be 0 though?)
throw PayloadTypeConversionError();
/*
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
v.Accept(writer);
return atol(std::string(buffer.GetString()).c_str());
*/
}
IPAACA_EXPORT template<> int json_value_cast(const rapidjson::Value& v)
{
if (v.IsString()) return (int) strict_numerical_interpretation(v.GetString());
if (v.IsInt()) return v.GetInt();
if (v.IsUint()) return v.GetUint();
if (v.IsInt64()) return v.GetInt64();
if (v.IsUint64()) return v.GetUint64();
if (v.IsDouble()) return (long) v.GetDouble();
if (v.IsBool()) return v.GetBool() ? 1l : 0l;
if (v.IsNull()) return 0l;
throw PayloadTypeConversionError();
IPAACA_EXPORT template<> double json_value_cast(const rapidjson::Value& v)
if (v.IsString()) return strict_numerical_interpretation(v.GetString());
if (v.IsDouble()) return v.GetDouble();
if (v.IsInt()) return (double) v.GetInt();
if (v.IsUint()) return (double) v.GetUint();
if (v.IsInt64()) return (double) v.GetInt64();
if (v.IsUint64()) return (double) v.GetUint64();
if (v.IsBool()) return v.GetBool() ? 1.0 : 0.0;
if (v.IsNull()) return 0.0;
throw PayloadTypeConversionError();
IPAACA_EXPORT template<> bool json_value_cast(const rapidjson::Value& v)
{
if (v.IsString()) {
std::string s = v.GetString();
return !((s=="")||(s=="false")||(s=="False")||(s=="0"));
//return ((s=="1")||(s=="true")||(s=="True"));
}
if (v.IsBool()) return v.GetBool();
if (v.IsNull()) return false;
if (v.IsInt()) return v.GetInt() != 0;
if (v.IsUint()) return v.GetUint() != 0;
if (v.IsInt64()) return v.GetInt64() != 0;
if (v.IsUint64()) return v.GetUint64() != 0;
if (v.IsDouble()) return v.GetDouble() != 0.0;
// default: assume "pointer-like" semantics (i.e. objects are TRUE)
return true;
}
/*
* std::map<std::string, std::string> result;
std::for_each(_document_store.begin(), _document_store.end(), [&result](std::pair<std::string, PayloadDocumentEntry::ptr> pair) {
result[pair.first] = pair.second->document.GetString();
});
*/
//}}}
IPAACA_EXPORT void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, int newvalue)
{
valueobject.SetInt(newvalue);
}
IPAACA_EXPORT 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, double newvalue)
{
valueobject.SetDouble(newvalue);
}
IPAACA_EXPORT void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, bool newvalue)
{
valueobject.SetBool(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 void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const char* newvalue)
{
valueobject.SetString(newvalue, allocator);
}
/*
IPAACA_EXPORT template<> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::vector<std::string>& newvalue)
{
valueobject.SetArray();
for (auto& str: newvalue) {
rapidjson::Value sv;
sv.SetString(str, allocator);
valueobject.PushBack(sv, allocator);
}
}
IPAACA_EXPORT template<> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::list<std::string>& newvalue)
{
IPAACA_IMPLEMENT_ME
}
IPAACA_EXPORT template<> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::map<std::string, std::string>& newvalue)
{
IPAACA_IMPLEMENT_ME
}
*/
// PayloadDocumentEntry//{{{
IPAACA_EXPORT std::string PayloadDocumentEntry::to_json_string_representation()
{
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
document.Accept(writer);
return buffer.GetString();
}
IPAACA_EXPORT PayloadDocumentEntry::ptr PayloadDocumentEntry::from_json_string_representation(const std::string& json_str)
{
PayloadDocumentEntry::ptr entry = std::make_shared<ipaaca::PayloadDocumentEntry>();
if (entry->document.Parse(json_str.c_str()).HasParseError()) {
throw JsonParsingError();
}

Ramin Yaghoubzadeh Torky
committed
//entry->json_source = json_str;
IPAACA_EXPORT PayloadDocumentEntry::ptr PayloadDocumentEntry::from_unquoted_string_value(const std::string& str)
{
PayloadDocumentEntry::ptr entry = std::make_shared<ipaaca::PayloadDocumentEntry>();
entry->document.SetString(str.c_str(), entry->document.GetAllocator());

Ramin Yaghoubzadeh Torky
committed
//entry->update_json_source();
return entry;
}
/// update json_source after a write operation (on newly cloned entries)

Ramin Yaghoubzadeh Torky
committed
/*
IPAACA_EXPORT void PayloadDocumentEntry::update_json_source()
{
json_source = to_json_string_representation();
}

Ramin Yaghoubzadeh Torky
committed
*/
IPAACA_EXPORT PayloadDocumentEntry::ptr PayloadDocumentEntry::create_null()
{
PayloadDocumentEntry::ptr entry = std::make_shared<ipaaca::PayloadDocumentEntry>();

Ramin Yaghoubzadeh Torky
committed
//entry->json_source = "null"; // rapidjson::Document value is also null implicitly
IPAACA_EXPORT PayloadDocumentEntry::ptr PayloadDocumentEntry::clone()

Ramin Yaghoubzadeh Torky
committed
//auto entry = PayloadDocumentEntry::from_json_string_representation(this->json_source);
auto entry = PayloadDocumentEntry::create_null();
entry->document.CopyFrom(this->document, entry->document.GetAllocator());
IPAACA_DEBUG("Cloned for copy-on-write, contents: " << entry)
return entry;
IPAACA_EXPORT rapidjson::Value& PayloadDocumentEntry::get_or_create_nested_value_from_proxy_path(PayloadEntryProxy* pep)
{
if (!(pep->parent)) {
return document;
}
rapidjson::Value& parent_value = get_or_create_nested_value_from_proxy_path(pep->parent);
if (pep->addressed_as_array) {
IPAACA_DEBUG("Addressed as array with index " << pep->addressed_index)
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
if (! parent_value.IsArray()) {
throw PayloadAddressingError();
} else {
long idx = pep->addressed_index;
long s = parent_value.Size();
if (idx<s) {
return parent_value[idx];
} else {
throw PayloadAddressingError();
}
}
// for append / push_back? :
/*if (parent_value.IsNull()) {
wasnull = true;
parent_value.SetArray();
}
if (wasnull || parent_value.IsArray()) {
long idx = pep->addressed_index;
long s = parent_value.Size();
if (idx<s) {
// existing element modified
parent_value[idx] = *json_value;
} else {
// implicitly initialize missing elements to null values
if (idx>s) {
long missing_elements = pep->addressed_index - p;
for (int i=0; i<missing_elements; ++i) {
parent_value.PushBack(, allocator)
}
}
}
if (s ==
} else {
throw PayloadAddressingError();
}*/
} else {
IPAACA_DEBUG("Addressed as dict with key " << pep->addressed_key)
// addressed as object (dict)
//rapidjson::Value& parent_value = *(pep->parent->json_value);
if (! parent_value.IsObject()) {
IPAACA_DEBUG("parent is not of type Object")
throw PayloadAddressingError();
} else {
rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
//Value key;
//key.SetString(pep->addressed_key, allocator);
//parent_value.AddMember(key, *json_value, allocator);
rapidjson::Value key;
key.SetString(pep->addressed_key, allocator);
auto it = parent_value.FindMember(key);
if (it != parent_value.MemberEnd()) {
return parent_value[key];
} else {
rapidjson::Value val;
parent_value.AddMember(key, val, allocator);
rapidjson::Value rkey;
rkey.SetString(pep->addressed_key, allocator);
return parent_value[rkey];
// PayloadEntryProxy//{{{
IPAACA_EXPORT void PayloadEntryProxy::connect_to_existing_parents()
{
rapidjson::Document::AllocatorType& allocator = document_entry->document.GetAllocator();
PayloadEntryProxy* pep = this;
while (!(pep->existent) && pep->parent) { // only if not top-level
if (pep->addressed_as_array) {
rapidjson::Value& parent_value = *(pep->parent->json_value);
if (! parent_value.IsArray()) {
throw PayloadAddressingError();
} else {
long idx = pep->addressed_index;
long s = parent_value.Size();
if (idx<s) {
parent_value[idx] = *json_value;
} else {
throw PayloadAddressingError();
}
}
/*if (parent_value.IsNull()) {
wasnull = true;
parent_value.SetArray();
}
if (wasnull || parent_value.IsArray()) {
long idx = pep->addressed_index;
long s = parent_value.Size();
if (idx<s) {
// existing element modified
parent_value[idx] = *json_value;
} else {
// implicitly initialize missing elements to null values
if (idx>s) {
long missing_elements = pep->addressed_index - p;
for (int i=0; i<missing_elements; ++i) {
parent_value.PushBack(, allocator)
}
}
}
if (s ==
} else {
throw PayloadAddressingError();
}*/
} else {
// addressed as object (dict)
rapidjson::Value& parent_value = *(pep->parent->json_value);
if (! parent_value.IsObject()) {
throw PayloadAddressingError();
} else {
Value key;
key.SetString(pep->addressed_key, allocator);
parent_value.AddMember(key, *json_value, allocator);
}
}
// repeat for next parent in the tree
pep = pep->parent;
}
}
IPAACA_EXPORT PayloadEntryProxy::PayloadEntryProxy(Payload* payload, const std::string& key)
: _payload(payload), _key(key), parent(nullptr)
{
document_entry = _payload->get_entry(key);
json_value = &(document_entry->document);
}
IPAACA_EXPORT PayloadEntryProxy::PayloadEntryProxy(PayloadEntryProxy* parent_, const std::string& addr_key_)
: parent(parent_), addressed_key(addr_key_), addressed_as_array(false)
{
_payload = parent->_payload;
_key = parent->_key;
document_entry = parent->document_entry;
auto it = parent->json_value->FindMember(addr_key_.c_str());
json_value = &(parent->json_value->operator[](addr_key_.c_str()));
existent = true;
} else {
json_value = nullptr; // avoid heap construction here
existent = false;
}
}
IPAACA_EXPORT PayloadEntryProxy::PayloadEntryProxy(PayloadEntryProxy* parent_, size_t addr_idx_)
: parent(parent_), addressed_index(addr_idx_), addressed_as_array(true)
{
_payload = parent->_payload;
_key = parent->_key;
document_entry = parent->document_entry;
json_value = &(parent->json_value->operator[](addr_idx_));
existent = true;
}
IPAACA_EXPORT PayloadEntryProxy PayloadEntryProxy::operator[](const char* addr_key_)
{
return operator[](std::string(addr_key_));
}
IPAACA_EXPORT PayloadEntryProxy PayloadEntryProxy::operator[](const std::string& addr_key_)
{
IPAACA_DEBUG("Invalid json_value!")
throw PayloadAddressingError();
}
if (! json_value->IsObject()) {
IPAACA_DEBUG("Expected Object for operator[](string)!")
return PayloadEntryProxy(this, addr_key_);
}
IPAACA_EXPORT PayloadEntryProxy PayloadEntryProxy::operator[](size_t addr_idx_)
{
IPAACA_DEBUG("Invalid json_value!")
throw PayloadAddressingError();
}
if (! json_value->IsArray()) {
IPAACA_DEBUG("Expected Array for operator[](size_t)!")
IPAACA_DEBUG("Array out of bounds!")
return PayloadEntryProxy(this, addr_idx_);

Ramin Yaghoubzadeh Torky
committed
IPAACA_EXPORT PayloadEntryProxy PayloadEntryProxy::operator[](int addr_idx_)
{
if (addr_idx_ < 0) {
IPAACA_DEBUG("Negative index!")

Ramin Yaghoubzadeh Torky
committed
throw PayloadAddressingError();
}
return operator[]((size_t) addr_idx_);
}
IPAACA_EXPORT PayloadEntryProxy& PayloadEntryProxy::operator=(const PayloadEntryProxy& otherproxy)
{
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);
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());
}

Ramin Yaghoubzadeh Torky
committed
//new_entry->update_json_source();
_payload->set(_key, new_entry);
return *this;
}
IPAACA_EXPORT PayloadEntryProxy& PayloadEntryProxy::operator=(const std::string& value)
{
//std::cout << "operator=(string)" << std::endl;
IPAACA_IMPLEMENT_ME
//_payload->set(_key, value);
return *this;
}
IPAACA_EXPORT PayloadEntryProxy& PayloadEntryProxy::operator=(const char* value)
{
//std::cout << "operator=(const char*)" << std::endl;
IPAACA_IMPLEMENT_ME
//_payload->set(_key, value);
return *this;
}
IPAACA_EXPORT PayloadEntryProxy& PayloadEntryProxy::operator=(double value)
{
//std::cout << "operator=(double)" << std::endl;
IPAACA_IMPLEMENT_ME
//_payload->set(_key, boost::lexical_cast<std::string>(value));
return *this;
}
IPAACA_EXPORT PayloadEntryProxy& PayloadEntryProxy::operator=(bool value)
{
//std::cout << "operator=(bool)" << std::endl;
IPAACA_IMPLEMENT_ME
//_payload->set(_key, boost::lexical_cast<std::string>(value));
return *this;
}

Ramin Yaghoubzadeh Torky
committed
IPAACA_EXPORT PayloadEntryProxy::operator std::string()
return json_value_cast<std::string>(json_value);
//PayloadEntryProxy::get<std::string>();

Ramin Yaghoubzadeh Torky
committed
}
IPAACA_EXPORT PayloadEntryProxy::operator long()
return json_value_cast<long>(json_value);
//return PayloadEntryProxy::get<long>();
IPAACA_EXPORT PayloadEntryProxy::operator double()
return json_value_cast<double>(json_value);
//return PayloadEntryProxy::get<double>();
IPAACA_EXPORT PayloadEntryProxy::operator bool()
return json_value_cast<bool>(json_value);
//return PayloadEntryProxy::get<bool>();
IPAACA_EXPORT std::string PayloadEntryProxy::to_str()
return json_value_cast<std::string>(json_value);
//return PayloadEntryProxy::get<std::string>();
IPAACA_EXPORT long PayloadEntryProxy::to_long()
return json_value_cast<long>(json_value);
//return PayloadEntryProxy::get<long>();
IPAACA_EXPORT double PayloadEntryProxy::to_float()
return json_value_cast<double>(json_value);
//return PayloadEntryProxy::get<double>();
IPAACA_EXPORT bool PayloadEntryProxy::to_bool()
return json_value_cast<bool>(json_value);
//return PayloadEntryProxy::get<bool>();
}
//
// new stuff for protocol v2
//
IPAACA_EXPORT template<> std::string PayloadEntryProxy::get<std::string>()
if (!json_value) return "";
//IPAACA_INFO( value_diagnosis(json_value) )
if (json_value->IsString()) return json_value->GetString();
if (json_value->IsNull()) return "";
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
json_value->Accept(writer);
return buffer.GetString();
//return _payload->get(_key);
IPAACA_EXPORT template<> long PayloadEntryProxy::get<long>()
{
return atof(operator std::string().c_str());
}
IPAACA_EXPORT template<> double PayloadEntryProxy::get<double>()
{
return atol(operator std::string().c_str());
}
IPAACA_EXPORT template<> bool PayloadEntryProxy::get<bool>()
{
std::string s = operator std::string();
return ((s=="1")||(s=="true")||(s=="True"));
}
// complex types
IPAACA_EXPORT template<> std::list<std::string> PayloadEntryProxy::get<std::list<std::string> >()
{
std::list<std::string> l;
l.push_back(PayloadEntryProxy::get<std::string>());
return l;
}
IPAACA_EXPORT template<> std::vector<std::string> PayloadEntryProxy::get<std::vector<std::string> >()
{
std::vector<std::string> v;
v.push_back(PayloadEntryProxy::get<std::string>());
return v;
}
IPAACA_EXPORT template<> std::map<std::string, std::string> PayloadEntryProxy::get<std::map<std::string, std::string> >()
{
std::map<std::string, std::string> m;
m["__automatic__"] = PayloadEntryProxy::get<std::string>();
return m;
}
//}}}
// Payload//{{{
IPAACA_EXPORT void Payload::initialize(boost::shared_ptr<IUInterface> iu)
{
_iu = boost::weak_ptr<IUInterface>(iu);
}
IPAACA_EXPORT PayloadEntryProxy Payload::operator[](const std::string& key)
{
//boost::shared_ptr<PayloadEntryProxy> p(new PayloadEntryProxy(this, key));
return PayloadEntryProxy(this, key);
IPAACA_EXPORT Payload::operator std::map<std::string, std::string>()
{
std::map<std::string, std::string> result;
std::for_each(_document_store.begin(), _document_store.end(), [&result](std::pair<std::string, PayloadDocumentEntry::ptr> pair) {
result[pair.first] = json_value_cast<std::string>(pair.second->document);
IPAACA_EXPORT void Payload::_internal_set(const std::string& k, PayloadDocumentEntry::ptr v, const std::string& writer_name) {
std::map<std::string, PayloadDocumentEntry::ptr> _new;
std::vector<std::string> _remove;
_iu.lock()->_modify_payload(true, _new, _remove, writer_name );
IPAACA_DEBUG(" Setting local payload item \"" << k << "\" to " << v)
mark_revision_change();
}
IPAACA_EXPORT void Payload::_internal_remove(const std::string& k, const std::string& writer_name) {
std::map<std::string, PayloadDocumentEntry::ptr> _new;
std::vector<std::string> _remove;
_remove.push_back(k);
_iu.lock()->_modify_payload(true, _new, _remove, writer_name );
mark_revision_change();
IPAACA_EXPORT void Payload::_internal_replace_all(const std::map<std::string, PayloadDocumentEntry::ptr>& new_contents, const std::string& writer_name)
{
std::vector<std::string> _remove;
_iu.lock()->_modify_payload(false, new_contents, _remove, writer_name );
mark_revision_change();
IPAACA_EXPORT void Payload::_internal_merge(const std::map<std::string, PayloadDocumentEntry::ptr>& contents_to_merge, const std::string& writer_name)
{
std::vector<std::string> _remove;
_iu.lock()->_modify_payload(true, contents_to_merge, _remove, writer_name );
for (auto& kv: contents_to_merge) {
_document_store[kv.first] = kv.second;
}
mark_revision_change();
//_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 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 std::string Payload::get(const std::string& k) { // DEPRECATED
if (_document_store.count(k)>0) return _document_store[k]->document.GetString();
return "";
IPAACA_EXPORT void Payload::set(const std::map<std::string, std::string>& all_elems)
{
std::map<std::string, PayloadDocumentEntry::ptr> newmap;
for (auto& kv: all_elems) {
/*PayloadDocumentEntry::ptr newit = PayloadDocumentEntry::create_null();
newit->document.SetString(kv.second, newit->document.GetAllocator());
newit->update_json_source();
newmap[kv.first] = newit;*/
newmap[kv.first] = PayloadDocumentEntry::from_unquoted_string_value(kv.second);
}
_internal_replace_all(newmap);
}
IPAACA_EXPORT void Payload::_remotely_enforced_wipe()
{
mark_revision_change();
}
IPAACA_EXPORT void Payload::_remotely_enforced_delitem(const std::string& k)
{
mark_revision_change();
IPAACA_EXPORT void Payload::_remotely_enforced_setitem(const std::string& k, PayloadDocumentEntry::ptr entry)
mark_revision_change();
}
IPAACA_EXPORT PayloadIterator Payload::begin()
{
return PayloadIterator(this, _document_store.begin());
}
IPAACA_EXPORT PayloadIterator Payload::end()
{
return PayloadIterator(this, _document_store.end());
}
//}}}
// PayloadIterator//{{{
IPAACA_EXPORT PayloadIterator::PayloadIterator(Payload* payload, PayloadDocumentStore::iterator&& ref_it)
: _payload(payload), reference_payload_revision(payload->internal_revision), raw_iterator(std::move(ref_it))
{
}
IPAACA_EXPORT PayloadIterator::PayloadIterator(const PayloadIterator& iter)
: _payload(iter._payload), reference_payload_revision(iter.reference_payload_revision), raw_iterator(iter.raw_iterator)
{
}
IPAACA_EXPORT PayloadIterator& PayloadIterator::operator++()
{
if (_payload->revision_changed(reference_payload_revision)) throw PayloadIteratorInvalidError();
++raw_iterator;
return *this;
}
IPAACA_EXPORT 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::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)
{
if (_payload->revision_changed(reference_payload_revision)) throw PayloadIteratorInvalidError();
return (raw_iterator==ref.raw_iterator);
}
IPAACA_EXPORT bool PayloadIterator::operator!=(const PayloadIterator& ref)
{
if (_payload->revision_changed(reference_payload_revision)) throw PayloadIteratorInvalidError();
return (raw_iterator!=ref.raw_iterator);
}
//}}}
} // of namespace ipaaca