Skip to content
Snippets Groups Projects
Commit 9f384144 authored by Ramin Yaghoubzadeh Torky's avatar Ramin Yaghoubzadeh Torky
Browse files

C++: Initial basic documentation of all relevant classes.

Also changed constructors of PayloadEntryProxy to protected.
parent e1f4c54c
No related branches found
No related tags found
No related merge requests found
......@@ -69,6 +69,7 @@ IPAACA_HEADER_EXPORT class SmartLinkMap {//{{{
IPAACA_HEADER_EXPORT void _replace_links(const LinkMap& links);
};//}}}
/// The empty link set is returned if undefined links are read for an IU.
IPAACA_MEMBER_VAR_EXPORT const LinkSet EMPTY_LINK_SET;
/// Configuration object that can be passed to Buffer constructors.
......@@ -113,11 +114,20 @@ IPAACA_HEADER_EXPORT class BufferConfigurationBuilder: private BufferConfigurati
};//}}}
/// Type of user-space functions that can be registered on a Buffer to receive IU events.
/** \brief Type of user-space functions that can be registered on a Buffer to receive IU events.
*
* The signature of these functions is void(shared_ptr<IUInterface> iu, IUEventType evt_type, bool local), where:<br/>
* iu can be used mostly like a locally-generated IU reference (e.g. iu->payload() ...)<br/>
* evt_type is one of IU_ADDED, IU_UPDATED, IU_RETRACTED, IU_DELETED, IU_LINKSUPDATED, IU_COMMITTED, IU_MESSAGE<br/>
* local indicates that a remote change to a local IU (in an OutputBuffer) was effected
*
*
*/
IPAACA_HEADER_EXPORT typedef boost::function<void (boost::shared_ptr<IUInterface>, IUEventType, bool)> IUEventHandlerFunction;
/// Internal handler type (wraps used-specified IUEventHandlerFunction)
IPAACA_LOG_LEVEL_NONE, IPAACA_HEADER_EXPORT class IUEventHandler {//{{{
/** \brief Internal handler type used in Buffer (wraps used-specified IUEventHandlerFunction)
*/
IPAACA_HEADER_EXPORT class IUEventHandler {//{{{
protected:
IPAACA_MEMBER_VAR_EXPORT IUEventHandlerFunction _function;
IPAACA_MEMBER_VAR_EXPORT IUEventType _event_mask;
......@@ -137,9 +147,9 @@ IPAACA_LOG_LEVEL_NONE, IPAACA_HEADER_EXPORT class IUEventHandler {//{{{
};//}}}
/**
* \brief Buffer base class
* \brief Buffer base class. Derived classes use its handler registration functionality.
*
* This class is never instantiated directly (use OutputBuffer and InputBuffer, respectively).
* \b Note: This class is never instantiated directly (use OutputBuffer and InputBuffer, respectively).
*/
IPAACA_HEADER_EXPORT class Buffer { //: public boost::enable_shared_from_this<Buffer> {//{{{
friend class IU;
......@@ -173,7 +183,42 @@ IPAACA_HEADER_EXPORT class Buffer { //: public boost::enable_shared_from_this<Bu
public:
IPAACA_HEADER_EXPORT virtual inline ~Buffer() { }
IPAACA_HEADER_EXPORT inline const std::string& unique_name() { return _unique_name; }
/// This version of register_handler takes a set of several category interests instead of just one.
IPAACA_HEADER_EXPORT void register_handler(IUEventHandlerFunction function, IUEventType event_mask, const std::set<std::string>& categories);
/** \brief Register a user-specified handler for IU events.
*
* \param function A function [object] that can be converted to #IUEventHandlerFunction (examples below)
* \param event_mask Which event types to relay to the user (default: all)
* \param category The category to filter for (default: do not filter)
*
* \b Examples:
*
* Adding a plain function as a handler:<br/>
* <pre>
* void global_iu_handler(IUInterface::ptr iu, IUEventType type, bool local) { ... }
* ...
* int main() {
* OutputBuffer::ptr outbuf = OutputBuffer::create("mybufname");
* outbuf->register_handler(global_iu_handler);
* ...
* }
* </pre>
*
* Adding a class member as a handler (using boost::bind):<br/>
* <pre>
* class MyClass {
* protected:
* void my_internal_iu_handler(IUInterface::ptr iu, IUEventType type, bool local) { ... }
* InputBuffer::ptr inbuf;
* public:
* MyClass() {
* inbuf = InputBuffer::create("bufname", "categoryInterest");
* inbuf->register_handler(boost::bind(&MyClass::my_internal_iu_handler, this, _1, _2, _3));
* }
* };
* </pre>
*
*/
IPAACA_HEADER_EXPORT void register_handler(IUEventHandlerFunction function, IUEventType event_mask = IU_ALL_EVENTS, const std::string& category="");
//_IPAACA_ABSTRACT_ virtual void add(boost::shared_ptr<IUInterface> iu) = 0;
IPAACA_HEADER_EXPORT _IPAACA_ABSTRACT_ virtual boost::shared_ptr<IUInterface> get(const std::string& iu_uid) = 0;
......@@ -225,6 +270,7 @@ IPAACA_HEADER_EXPORT class OutputBuffer: public Buffer { //, public boost::enabl
IPAACA_HEADER_EXPORT void _retract_iu(boost::shared_ptr<IU> iu);
protected:
/// \b Note: constructor is protected. Use create()
IPAACA_HEADER_EXPORT OutputBuffer(const std::string& basename, const std::string& channel=""); // empty string auto-replaced with __ipaaca_static_option_default_channel
IPAACA_HEADER_EXPORT void _initialize_server();
public:
......@@ -287,6 +333,7 @@ IPAACA_HEADER_EXPORT class InputBuffer: public Buffer { //, public boost::enable
IPAACA_WARNING("(ERROR) InputBuffer::_send_iu_resendrequest() should never be invoked")
}*/
protected:
/// \b Note: all constructors are protected. Use create()
IPAACA_HEADER_EXPORT InputBuffer(const BufferConfiguration& bufferconfiguration);
IPAACA_HEADER_EXPORT InputBuffer(const std::string& basename, const std::set<std::string>& category_interests);
IPAACA_HEADER_EXPORT InputBuffer(const std::string& basename, const std::vector<std::string>& category_interests);
......@@ -298,15 +345,27 @@ IPAACA_HEADER_EXPORT class InputBuffer: public Buffer { //, public boost::enable
IPAACA_MEMBER_VAR_EXPORT bool triggerResend;
public:
/// Specify whether old, but previously unknown, IUs should be requested to be sent to the buffer over a hidden channel.
/// Specify whether old but previously unseen IUs should be requested to be sent to the buffer over a hidden channel.
IPAACA_HEADER_EXPORT void set_resend(bool resendActive);
IPAACA_HEADER_EXPORT bool get_resend();
/// Create InputBuffer according to configuration in BufferConfiguration object
IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const BufferConfiguration& bufferconfiguration);
/// Create InputBuffer from name and set of category interests
IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::set<std::string>& category_interests);
/// Create InputBuffer from name and vector of category interests
IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::vector<std::string>& category_interests);
// /// Create InputBuffer from name and initializer_list of category interests
// IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::initializer_list<std::string>& category_interests);
/// Convenience function: create InputBuffer from name and one category interest
IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::string& category_interest1);
/// Convenience function: create InputBuffer from name and two category interests [DEPRECATED]
[[deprecated("Use create(string, set<string>) instead")]]
IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::string& category_interest1, const std::string& category_interest2);
/// Convenience function: create InputBuffer from name and three category interests [DEPRECATED]
[[deprecated("Use create(string, set<string>) instead")]]
IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::string& category_interest1, const std::string& category_interest2, const std::string& category_interest3);
/// Convenience function: create InputBuffer from name and four category interests [DEPRECATED]
[[deprecated("Use create(string, set<string>) instead")]]
IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::string& category_interest1, const std::string& category_interest2, const std::string& category_interest3, const std::string& category_interest4);
IPAACA_HEADER_EXPORT ~InputBuffer() {
IPAACA_IMPLEMENT_ME
......
......@@ -50,6 +50,14 @@
#endif
/** \brief Abstract base class for all IU-type classes
*
* In user programs, classes IU or Message should be instantiated.
*
* This abstract type is used in handler callback functions and
* contains most generic user-space functions.
*
*/
IPAACA_HEADER_EXPORT class IUInterface {//{{{
friend class IUConverter;
friend class MessageConverter;
......@@ -87,38 +95,68 @@ IPAACA_HEADER_EXPORT class IUInterface {//{{{
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:
/// Return whether IU has already been published (is in a Buffer).
IPAACA_HEADER_EXPORT inline bool is_published() { return (_buffer != 0); }
/// Return auto-generated UID string (set during IU construction)
IPAACA_HEADER_EXPORT inline const std::string& uid() const { return _uid; }
/// Return current IU revision number (incremented for each update)
IPAACA_HEADER_EXPORT inline revision_t revision() const { return _revision; }
/// Return the IU category string (set during IU construction)
IPAACA_HEADER_EXPORT inline const std::string& category() const { return _category; }
/// Return the channel name the IU is resident on (set on publication)
IPAACA_HEADER_EXPORT const std::string& channel();
/// Return the payload type (default "JSON")
IPAACA_HEADER_EXPORT inline const std::string& payload_type() const { return _payload_type; }
/// Return the owner name (unique fully-qualified buffer name, set on publication)
IPAACA_HEADER_EXPORT inline const std::string& owner_name() const { return _owner_name; }
/// Return whether IU has been committed to (i.e. is complete, confirmed, and henceforth constant)
IPAACA_HEADER_EXPORT inline bool committed() const { return _committed; }
/// Return the access mode (not relevant for the time being)
IPAACA_HEADER_EXPORT inline IUAccessMode access_mode() const { return _access_mode; }
/// Return whether IU is read only (committed, a Message, or explicitly set read-only by owner)
IPAACA_HEADER_EXPORT inline bool read_only() const { return _read_only; }
//inline boost::shared_ptr<Buffer> buffer() { return _buffer; }
/// Return owning buffer [CAVEAT: do not rely on this function for future code]
IPAACA_HEADER_EXPORT inline Buffer* buffer() const { return _buffer; }
/// Return the link set for an arbitrary link type (e.g. "grounded_in"), or EMPTY_LINK_SET
IPAACA_HEADER_EXPORT inline const LinkSet& get_links(std::string type) { return _links.get_links(type); }
/// Return the map of all defined links
IPAACA_HEADER_EXPORT inline const LinkMap& get_all_links() { return _links.get_all_links(); }
// Payload
/// Return the Payload object of this IU, overridden in the derived classes
IPAACA_HEADER_EXPORT _IPAACA_ABSTRACT_ virtual Payload& payload() = 0;
/// Const version of payload()
IPAACA_HEADER_EXPORT _IPAACA_ABSTRACT_ virtual const Payload& const_payload() const = 0;
// setters
/// Commit to an IU (only possible for the IU owner)
IPAACA_HEADER_EXPORT _IPAACA_ABSTRACT_ virtual void commit() = 0;
// functions to modify and update links:
//IPAACA_HEADER_EXPORT void _publish_resend(boost::shared_ptr<IU> iu, const std::string& hidden_scope_name);
/// Add a set of new UIDs for a specific link type
IPAACA_HEADER_EXPORT void add_links(const std::string& type, const LinkSet& targets, const std::string& writer_name = "");
/// Remove a set of UIDs from a link type
IPAACA_HEADER_EXPORT void remove_links(const std::string& type, const LinkSet& targets, const std::string& writer_name = "");
/// Bulk link modification function
IPAACA_HEADER_EXPORT void modify_links(const LinkMap& add, const LinkMap& remove, const std::string& writer_name = "");
/// Bulk link override function
IPAACA_HEADER_EXPORT void set_links(const LinkMap& links, const std::string& writer_name = "");
// (with cpp specific convenience functions:)
/// Convenience function (C++): add a single UID string to an arbitrary link set
IPAACA_HEADER_EXPORT void add_link(const std::string& type, const std::string& target, const std::string& writer_name = "");
/// Convenience function (C++): remove a single UID string from an arbitrary link set (if contained)
IPAACA_HEADER_EXPORT void remove_link(const std::string& type, const std::string& target, const std::string& writer_name = "");
typedef boost::shared_ptr<IUInterface> ptr;
};//}}}
/** \brief Class of locally-owned IU objects.
*
* Use IU::create() (static) to create references to new IUs.
* Use IU::payload() to access the IUs payload object.
* Use OutputBuffer::add() to publish IUs.
*
* See IUInterface for a generic description of most user-space member functions.
*/
IPAACA_HEADER_EXPORT class IU: public IUInterface {//{{{
friend class Buffer;
friend class InputBuffer;
......@@ -155,6 +193,18 @@ IPAACA_HEADER_EXPORT class IU: public IUInterface {//{{{
public:
typedef boost::shared_ptr<IU> ptr;
};//}}}
/** \brief Class of locally-owned message objects ('one-shot' IUs).
*
* This class works the same as IU, except that it sets the internal
* flags so that it is received as a message (ephemeral object) on
* the remote sides, instead of a persistent objects.
*
* Likewise, it is not actually stored by OutputBuffer::add(), but just broadcast.
*
* See IUInterface for a generic description of most user-space member functions.
*
* \see IU, IUInterface
*/
IPAACA_HEADER_EXPORT class Message: public IU {//{{{
friend class Buffer;
friend class InputBuffer;
......@@ -181,6 +231,7 @@ IPAACA_HEADER_EXPORT class Message: public IU {//{{{
typedef boost::shared_ptr<Message> ptr;
};//}}}
/// Copy of a remote IU, received in an InputBuffer. Setter functions call RPC over the backend (RSB). \b Note: Typically handled only as reference in a handler in user space.
IPAACA_HEADER_EXPORT class RemotePushIU: public IUInterface {//{{{
friend class Buffer;
friend class InputBuffer;
......@@ -209,6 +260,7 @@ IPAACA_HEADER_EXPORT class RemotePushIU: public IUInterface {//{{{
IPAACA_HEADER_EXPORT void _apply_retraction();
typedef boost::shared_ptr<RemotePushIU> ptr;
};//}}}
/// Copy of a remote Message, received in an InputBuffer. Setter functions all fail.\b Note: Typically handled only as reference in a handler in user space.
IPAACA_HEADER_EXPORT class RemoteMessage: public IUInterface {//{{{
friend class Buffer;
friend class InputBuffer;
......@@ -238,6 +290,7 @@ IPAACA_HEADER_EXPORT class RemoteMessage: public IUInterface {//{{{
typedef boost::shared_ptr<RemoteMessage> ptr;
};//}}}
/// Mock IU for testing purposes. [INTERNAL]
IPAACA_HEADER_EXPORT class FakeIU: public IUInterface {//{{{
friend class Buffer;
friend class InputBuffer;
......
......@@ -52,6 +52,7 @@
#endif
// casting operators from Value&
/// 'Smart' type conversions, allowing for some leeway type-wise (e.g. string "1.3" can be successfully cast to double or long). Used by PayloadEntryProxy.
IPAACA_HEADER_EXPORT template<typename T> T json_value_cast(const rapidjson::Value&);
IPAACA_HEADER_EXPORT template<typename T> T json_value_cast(const rapidjson::Value* value) { if (!value) return T(); return json_value_cast<T>(*value); }
IPAACA_HEADER_EXPORT template<> long json_value_cast(const rapidjson::Value&);
......@@ -65,14 +66,20 @@ IPAACA_HEADER_EXPORT template<> std::map<std::string, std::string> json_value_ca
// 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);
/// Setter to store int into json value, used by PayloadEntryProxy.
IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, int);
/// Setter to store int into json value, used by PayloadEntryProxy.
IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, long);
/// Setter to store long into json value, used by PayloadEntryProxy.
IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, double);
/// Setter to store double into json value, used by PayloadEntryProxy.
IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, bool);
/// Setter to store bool into json value, used by PayloadEntryProxy.
IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, const std::string&);
/// Setter to store std::string into json value, used by PayloadEntryProxy.
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>
/// Setter to store a vector of supported basic types into json value, used by PayloadEntryProxy.
IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::vector<T>& ts)
{
valueobject.SetArray();
......@@ -82,7 +89,7 @@ IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::V
valueobject.PushBack(newv, allocator);
}
}
/// set Value& from list<T>
/// Setter to store a list of supported basic types into json value, used by PayloadEntryProxy.
IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::list<T>& ts)
{
valueobject.SetArray();
......@@ -92,7 +99,7 @@ IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::V
valueobject.PushBack(newv, allocator);
}
}
/// set Value& from map<string, T>
/// Setter to store a map of string -> supported basic types into json value, used by PayloadEntryProxy.
IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::map<std::string, T>& ts)
{
valueobject.SetObject();
......@@ -110,6 +117,8 @@ IPAACA_HEADER_EXPORT template<> void pack_into_json_value(rapidjson::Value&, rap
*/
// FIXME TODO locking / invalidating proxy on first write of a payload entry
/// Single payload entry wrapping a rapidjson::Document with some conversion glue. Also handles copy-on-write Document cloning.
IPAACA_HEADER_EXPORT class PayloadDocumentEntry//{{{
{
friend std::ostream& operator<<(std::ostream& os, std::shared_ptr<PayloadDocumentEntry> entry);
......@@ -132,57 +141,12 @@ IPAACA_HEADER_EXPORT class PayloadDocumentEntry//{{{
};
//}}}
/*
IPAACA_HEADER_EXPORT class LegacyStringPayloadEntryProxy//{{{
{
protected:
IPAACA_MEMBER_VAR_EXPORT Payload* _payload;
IPAACA_MEMBER_VAR_EXPORT std::string _key;
public:
IPAACA_HEADER_EXPORT PayloadEntryProxy(Payload* payload, const std::string& key);
IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(const std::string& value);
IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(const char* value);
IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(double value);
IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(bool value);
IPAACA_HEADER_EXPORT operator std::string();
IPAACA_HEADER_EXPORT operator long();
IPAACA_HEADER_EXPORT operator double();
IPAACA_HEADER_EXPORT operator bool();
IPAACA_HEADER_EXPORT std::string to_str();
//long to_int() { return operator long(); ;
IPAACA_HEADER_EXPORT long to_long();
IPAACA_HEADER_EXPORT double to_float();
IPAACA_HEADER_EXPORT bool to_bool();
// getters
IPAACA_HEADER_EXPORT template<typename T> T get(); // specializations below
// setters
};
// Available interpretations of payload entries (or children thereof) below.
// Usage of standard complex data structures (vector etc.) currently entails
// casting all entries to a uniform type (a-priori choice: std::string).
IPAACA_HEADER_EXPORT template<> long PayloadEntryProxy::get();
IPAACA_HEADER_EXPORT template<> double PayloadEntryProxy::get();
IPAACA_HEADER_EXPORT template<> bool PayloadEntryProxy::get();
IPAACA_HEADER_EXPORT template<> std::string PayloadEntryProxy::get();
IPAACA_HEADER_EXPORT template<> std::vector<std::string> PayloadEntryProxy::get();
IPAACA_HEADER_EXPORT template<> std::list<std::string> PayloadEntryProxy::get();
IPAACA_HEADER_EXPORT template<> std::map<std::string, std::string> PayloadEntryProxy::get();
//}}}
*/
typedef std::map<std::string, PayloadDocumentEntry::ptr> PayloadDocumentStore;
/*
IPAACA_HEADER_EXPORT class PayloadDocumentStore//{{{
: public std::map<std::string, PayloadDocumentEntry::ptr>
{
public:
typedef std::shared_ptr<PayloadDocumentStore> ptr;
};
//}}}
*/
/** \brief Central class containing the user-set payload of any IUInterface class (IU, Message, RemotePushIU or RemoteMessage)
*
* Obtained by calling payload() on any IUInterface derived object. Created during IU creation.
*/
IPAACA_HEADER_EXPORT class Payload//{{{
{
friend std::ostream& operator<<(std::ostream& os, const Payload& obj);
......@@ -217,20 +181,26 @@ IPAACA_HEADER_EXPORT class Payload//{{{
public:
IPAACA_HEADER_EXPORT inline const std::string& owner_name() { return _owner_name; }
// access
/// Obtain a payload item by name as a PayloadEntryProxy (returning null-type proxy if undefined)
IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](const std::string& key);
/// Legacy / convenience function: interpret the payload map as a map string->string (casting all entries to string)
IPAACA_HEADER_EXPORT operator std::map<std::string, std::string>();
/// set or overwrite a single payload entry with a PayloadDocumentEntry object (typically \b not called by users - use PayloadEntryProxy::operator=() instead).
IPAACA_HEADER_EXPORT inline void set(const std::string& k, PayloadDocumentEntry::ptr entry) { _internal_set(k, entry); }
/// remove a single payload entry
IPAACA_HEADER_EXPORT inline void remove(const std::string& k) { _internal_remove(k); }
// FIXME: json: these two must support a bunch of standard types, not [only] json (users touch them)
// to be more precise: types of map<string, T> with T several interesting things (string, list<string>, etc.)
//IPAACA_HEADER_EXPORT inline void set(const std::map<std::string, const rapidjson::Document&>& all_elems) { _internal_replace_all(all_elems); }
//IPAACA_HEADER_EXPORT inline void merge(const std::map<std::string, const rapidjson::Document&>& elems_to_merge) { _internal_merge(elems_to_merge); }
// legacy / convenience setter
/// Legacy / convenience function: set the whole payload map from a map string->string (all JSON types are also set as string, no interpretation)
IPAACA_HEADER_EXPORT void set(const std::map<std::string, std::string>& all_elems);
protected:
IPAACA_HEADER_EXPORT PayloadDocumentEntry::ptr get_entry(const std::string& k); // json, changed str to proxy here, too
public:
[[deprecated("Use operator[] and operator std::string() instead")]]
/// Read a single entry as string [DEPRECATED] (use string conversion in PayloadEntryProxy instead)
IPAACA_HEADER_EXPORT std::string get(const std::string& k); // DEPRECATED
protected:
IPAACA_MEMBER_VAR_EXPORT unsigned long internal_revision;
......@@ -238,11 +208,24 @@ IPAACA_HEADER_EXPORT class Payload//{{{
public:
IPAACA_HEADER_EXPORT inline bool revision_changed(unsigned long reference_revision) { return internal_revision != reference_revision; }
public:
/// obtain a standard iterator marking the first entry in the payload
IPAACA_HEADER_EXPORT PayloadIterator begin();
/// obtain a standard iterator past the last entry in the payload
IPAACA_HEADER_EXPORT PayloadIterator end();
typedef boost::shared_ptr<Payload> ptr;
};//}}}
/** \brief Standard iterator for Payload (example below)
*
* \b Examples:
* <pre>
* // Print all key-value pairs from a payload (C++11)
* for (auto kv_pair: myiu->payload()) {
* std::cout << kv_pair.first << " -> " << (std::string) kv_pair.second << std::endl;
* }
* </pre>
*
*/
IPAACA_HEADER_EXPORT class PayloadIterator//{{{
{
friend class Payload;
......@@ -265,6 +248,7 @@ IPAACA_HEADER_EXPORT class PayloadIterator//{{{
};
//}}}
/// Iterator over a payload entry that is a json map-type object (returned type during dereferencing: pair<string, PayloadEntryProxy>)
IPAACA_HEADER_EXPORT class PayloadEntryProxyMapIterator//{{{
{
public:
......@@ -281,6 +265,7 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxyMapIterator//{{{
IPAACA_HEADER_EXPORT bool operator!=(const PayloadEntryProxyMapIterator& other_iter);
};
//}}}
/// Iterator over a payload entry that is a json list-type object (returned type during dereferencing: PayloadEntryProxy)
IPAACA_HEADER_EXPORT class PayloadEntryProxyListIterator//{{{
{
protected:
......@@ -296,6 +281,7 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxyListIterator//{{{
IPAACA_HEADER_EXPORT bool operator!=(const PayloadEntryProxyListIterator& other_iter);
};
//}}}
/// Interpretation of a variant json value as a map-type object
IPAACA_HEADER_EXPORT class PayloadEntryProxyMapDecorator//{{{
{
public:
......@@ -306,6 +292,7 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxyMapDecorator//{{{
IPAACA_MEMBER_VAR_EXPORT PayloadEntryProxy* proxy;
};
//}}}
/// Interpretation of a variant json value as a list-type object
IPAACA_HEADER_EXPORT class PayloadEntryProxyListDecorator//{{{
{
public:
......@@ -317,13 +304,37 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxyListDecorator//{{{
};
//}}}
/** PayloadEntryProxy description */
/** \brief Reference to an existent or nonexistent payload entry (or a value deeper in the json tree)
*
* This class is returned by IUInterface::operator[].
* The proxy handles automatic type conversions, requests remote changes of payloads, and enables navigation into and iteration over structured json objects.
*
* \b Examples:
*
* <code>std::string received_name = iu->payload()["name"];</code> // implicit conversion using operator string()
*
* <code>std::vector<double> vd = iu->payload()["double_list"];</code> // some standard container types also supported
*
* <code>auto p = iu->payload()["otherKey"];</code> // auto type is PayloadEntryProxy (conversion is on-demand)
*
* <code>iu->payload()["double_list"][0] = 100.0;</code> // accessing and updating an item in a list
*
* <code>iu->payload()["name_list"] = std::list<std::string>{"Alpha", "Bravo", "Charlie"};</code> // set from basic uniform containers
*
* <code>for (auto val: iu->payload()["my_list"].as_list()) { ... }</code> // as_list is required to select list-type iteration (value type in iteration remains variant)
*
* <code>for (auto k_v_map: iu->payload()["my_map"].as_map()) { ... }</code> // as_map is required to select map-type iteration (value type in iteration is a pair, second part remains variant)
*/
IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
{
friend class Payload;
friend class PayloadIterator;
friend std::ostream& operator<<(std::ostream& os, const PayloadEntryProxy& proxy);
protected:
public:
/// Select map-style iteration for this proxy (to select iterator content type). Will throw if not actually map-type. See example in the class description.
IPAACA_HEADER_EXPORT PayloadEntryProxyMapDecorator as_map();
/// Select list-style iteration for this proxy (to select iterator content type). Will throw if not actually list-type. See example in the class description.
IPAACA_HEADER_EXPORT PayloadEntryProxyListDecorator as_list();
public:
//IPAACA_MEMBER_VAR_EXPORT rapidjson::Document* _json_parent_node;
......@@ -333,41 +344,52 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
//
// new json stuff / hierarchical navigation
//
IPAACA_MEMBER_VAR_EXPORT PayloadEntryProxy* parent; // parent (up to document root -> then null)
IPAACA_MEMBER_VAR_EXPORT PayloadEntryProxy* parent; ///< Parent proxy (up to document root -> then null)
IPAACA_MEMBER_VAR_EXPORT PayloadDocumentEntry::ptr document_entry; // contains lock and json Doc
IPAACA_MEMBER_VAR_EXPORT bool existent; // whether Value exists already (or blindly navigated)
IPAACA_MEMBER_VAR_EXPORT bool addressed_as_array; // whether long or string navigation used
IPAACA_MEMBER_VAR_EXPORT long addressed_index;
IPAACA_MEMBER_VAR_EXPORT std::string addressed_key;
IPAACA_MEMBER_VAR_EXPORT bool existent; ///< Whether Value exists already (or else 'blindly' navigated)
IPAACA_MEMBER_VAR_EXPORT bool addressed_as_array; ///< Whether long or string navigation was used
IPAACA_MEMBER_VAR_EXPORT long addressed_index; ///< Index that was used in list-style access
IPAACA_MEMBER_VAR_EXPORT std::string addressed_key; ///< Key that was used in map-style access
/// currently navigated value in json tree (or a new Null value)
IPAACA_MEMBER_VAR_EXPORT rapidjson::Value* json_value;
IPAACA_MEMBER_VAR_EXPORT rapidjson::Value* json_value; ///< json value that corresponds to the current navigation (or nullptr)
/* protected:
IPAACA_HEADER_EXPORT void connect_to_existing_parents();
*/
public:
protected:
// constructor to create a new top-most parent proxy (from a payload key)
IPAACA_HEADER_EXPORT PayloadEntryProxy(Payload* payload, const std::string& key);
// constructors for navigation through objects
IPAACA_HEADER_EXPORT PayloadEntryProxy(PayloadEntryProxy* parent, const std::string& addressed_key);
IPAACA_HEADER_EXPORT PayloadEntryProxy(PayloadEntryProxy* parent, size_t addressed_index);
public:
/// Return number of contained items (or 0 for non-container types)
IPAACA_HEADER_EXPORT size_t size();
/// Return whether value corresponds to json 'null'; also true if value is nonexistent so far (e.g. navigated to new map entry)
IPAACA_HEADER_EXPORT bool is_null();
/// Return whether value is of string type
IPAACA_HEADER_EXPORT bool is_string();
/// Return whether value is of a numerical type
IPAACA_HEADER_EXPORT bool is_number();
/// Return whether value is of list type
IPAACA_HEADER_EXPORT bool is_list();
/// Return whether value is of map type
IPAACA_HEADER_EXPORT bool is_map();
public:
/// Array-style navigation over json value
IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](size_t index); // array-style navigation
/// Array-style navigation over json value (added to catch [0])
IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](int index); // int is UNFORTUNATELY required to catch
// [0] (addressing using literal zero)
// because ambiguity with const char*
// arises if only [](size_t) is provided.
// size_t is obviously superior ...
// TODO: remove if better solution known
/// Dict-style navigation over json value
IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](const std::string& key); // dict-style navigation
/// Dict-style navigation over json value
IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](const char* key);
//
//
/// Set or overwrite some portion of a payload from the point navigated to
IPAACA_HEADER_EXPORT template<typename T> PayloadEntryProxy& operator=(T t)
{
PayloadDocumentEntry::ptr new_entry = document_entry->clone(); // copy-on-write, no lock required
......@@ -377,8 +399,11 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
_payload->set(_key, new_entry);
return *this;
}
/// Value comparison with other proxy contents
IPAACA_HEADER_EXPORT inline bool operator==(const PayloadEntryProxy& otherproxy) { return (json_value && otherproxy.json_value && ((*json_value)==*(otherproxy.json_value))); }
/// Value comparison with other proxy contents
IPAACA_HEADER_EXPORT inline bool operator!=(const PayloadEntryProxy& otherproxy) { return !operator==(otherproxy); }
/// Value comparison with supported basic types
IPAACA_HEADER_EXPORT template<typename T> bool operator==(T othervalue)
{
if (!json_value) return false;
......@@ -389,14 +414,18 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
return false;
}
}
/// Value comparison with supported basic types
IPAACA_HEADER_EXPORT template<typename T> bool operator!=(T othervalue) { return !operator==(othervalue); }
/// Value comparison with char* (required to be explicitly added)
IPAACA_HEADER_EXPORT inline bool operator==(const char* othervalue)
{
if (!json_value) return false;
return json_value_cast<std::string>(*json_value) == othervalue;
}
/// Value comparison with char* (required to be explicitly added)
IPAACA_HEADER_EXPORT inline bool operator!=(const char* othervalue) { return !operator==(othervalue); }
/// Copy value from below other json node, preserving types
IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(const PayloadEntryProxy& otherproxy);
//IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(const std::string& value);
......@@ -404,10 +433,15 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
//IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(double value);
//IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(bool value);
/// Conversion to std::string (explicit or implicit)
IPAACA_HEADER_EXPORT operator std::string();
/// Conversion to long (explicit or implicit)
IPAACA_HEADER_EXPORT operator long();
/// Conversion to double (explicit or implicit)
IPAACA_HEADER_EXPORT operator double();
/// Conversion to bool (explicit or implicit)
IPAACA_HEADER_EXPORT operator bool();
/// Conversion to uniform std::vector of supported basic type
IPAACA_HEADER_EXPORT template<typename Inner> operator std::vector<Inner>() {
if ((!json_value) || (!json_value->IsArray())) throw PayloadAddressingError();
std::vector<Inner> result;
......@@ -416,6 +450,7 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
}
return result;
}
/// Conversion to uniform std::list of supported basic type
IPAACA_HEADER_EXPORT template<typename Inner> operator std::list<Inner>() {
if ((!json_value) || (!json_value->IsArray())) throw PayloadAddressingError();
std::list<Inner> result;
......@@ -424,6 +459,7 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
}
return result;
}
/// Conversion to uniform std::map of string -> supported basic type
IPAACA_HEADER_EXPORT template<typename Inner> operator std::map<std::string, Inner>() {
if ((!json_value) || (!json_value->IsObject())) throw PayloadAddressingError();
std::map<std::string, Inner> result;
......
......@@ -51,7 +51,7 @@ List of most relevant entry points:
Buffers: InputBuffer, OutputBuffer
IUs: IU, Message
IUs: IUInterface, IU, Message
IU handling (user-set): #IUEventHandlerFunction
......@@ -190,6 +190,7 @@ IU payload contents: Payload, PayloadEntryProxy
#include <list>
#include <algorithm>
#include <utility>
#include <initializer_list>
namespace ipaaca {
......
......@@ -476,6 +476,17 @@ IPAACA_EXPORT InputBuffer::InputBuffer(const std::string& basename, const std::v
_create_category_listener_if_needed(_uuid);
triggerResend = false;
}
/*IPAACA_EXPORT InputBuffer::InputBuffer(const std::string& basename, const std::initializer_list<std::string>& category_interests)
:Buffer(basename, "IB")
{
_channel = __ipaaca_static_option_default_channel;
for (std::initializer_list<std::string>::const_iterator it=category_interests.begin(); it!=category_interests.end(); ++it) {
_create_category_listener_if_needed(*it);
}
_create_category_listener_if_needed(_uuid);
triggerResend = false;
}*/
IPAACA_EXPORT InputBuffer::InputBuffer(const std::string& basename, const std::string& category_interest1)
:Buffer(basename, "IB")
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment