summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJürgen Gehring <juergen.gehring@bmw.de>2015-06-11 06:57:47 -0700
committerJürgen Gehring <juergen.gehring@bmw.de>2015-06-11 06:57:47 -0700
commit6c463fcc3dcee619925f08ea09e19a86b9e581cc (patch)
tree17e765e0623c58778150605d1cd0340c658ce6ab /include
parent1d83eb38e546e0165f1ad6821f04445b2b9b19d2 (diff)
downloadgenivi-common-api-runtime-6c463fcc3dcee619925f08ea09e19a86b9e581cc.tar.gz
CommonAPI 3.1.1
Diffstat (limited to 'include')
-rw-r--r--include/CommonAPI/Address.hpp52
-rw-r--r--include/CommonAPI/Attribute.hpp143
-rw-r--r--include/CommonAPI/AttributeExtension.hpp54
-rw-r--r--include/CommonAPI/ByteBuffer.hpp18
-rw-r--r--include/CommonAPI/CallInfo.hpp31
-rw-r--r--include/CommonAPI/CommonAPI.hpp22
-rw-r--r--include/CommonAPI/Config.hpp17
-rw-r--r--include/CommonAPI/ContainerUtils.hpp33
-rw-r--r--include/CommonAPI/Deployable.hpp59
-rw-r--r--include/CommonAPI/Deployment.hpp75
-rw-r--r--include/CommonAPI/Enumeration.hpp40
-rw-r--r--include/CommonAPI/Event.hpp158
-rw-r--r--include/CommonAPI/Export.hpp22
-rw-r--r--include/CommonAPI/Factory.hpp58
-rw-r--r--include/CommonAPI/IniFileReader.hpp40
-rw-r--r--include/CommonAPI/InputStream.hpp241
-rw-r--r--include/CommonAPI/Logger.hpp179
-rw-r--r--include/CommonAPI/MainLoopContext.hpp299
-rw-r--r--include/CommonAPI/OutputStream.hpp241
-rw-r--r--include/CommonAPI/Proxy.hpp47
-rw-r--r--include/CommonAPI/ProxyManager.hpp73
-rw-r--r--include/CommonAPI/Runtime.hpp203
-rw-r--r--include/CommonAPI/SelectiveEvent.hpp28
-rw-r--r--include/CommonAPI/SerializableArguments.hpp62
-rw-r--r--include/CommonAPI/Struct.hpp174
-rw-r--r--include/CommonAPI/Stub.hpp60
-rw-r--r--include/CommonAPI/TypeOutputStream.hpp197
-rw-r--r--include/CommonAPI/Types.hpp116
-rw-r--r--include/CommonAPI/Utils.hpp22
-rw-r--r--include/CommonAPI/Variant.hpp746
-rw-r--r--include/CommonAPI/Version.hpp29
31 files changed, 3539 insertions, 0 deletions
diff --git a/include/CommonAPI/Address.hpp b/include/CommonAPI/Address.hpp
new file mode 100644
index 0000000..0826a8f
--- /dev/null
+++ b/include/CommonAPI/Address.hpp
@@ -0,0 +1,52 @@
+// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef COMMONAPI_ADDRESS_HPP_
+#define COMMONAPI_ADDRESS_HPP_
+
+#include <iostream>
+#include <string>
+
+#include <CommonAPI/Export.hpp>
+
+namespace CommonAPI {
+
+class Address {
+public:
+ COMMONAPI_EXPORT Address() = default;
+ COMMONAPI_EXPORT Address(const std::string &_address);
+ COMMONAPI_EXPORT Address(const std::string &_domain,
+ const std::string &_interface,
+ const std::string &_instance);
+ COMMONAPI_EXPORT Address(const Address &_source);
+ COMMONAPI_EXPORT virtual ~Address();
+
+ COMMONAPI_EXPORT bool operator==(const Address &_other) const;
+ COMMONAPI_EXPORT bool operator!=(const Address &_other) const;
+ COMMONAPI_EXPORT bool operator<(const Address &_other) const;
+
+ COMMONAPI_EXPORT std::string getAddress() const;
+ COMMONAPI_EXPORT void setAddress(const std::string &_address);
+
+ COMMONAPI_EXPORT const std::string &getDomain() const;
+ COMMONAPI_EXPORT void setDomain(const std::string &_domain);
+
+ COMMONAPI_EXPORT const std::string &getInterface() const;
+ COMMONAPI_EXPORT void setInterface(const std::string &_interface);
+
+ COMMONAPI_EXPORT const std::string &getInstance() const;
+ COMMONAPI_EXPORT void setInstance(const std::string &_instance);
+
+private:
+ std::string domain_;
+ std::string interface_;
+ std::string instance_;
+
+ friend COMMONAPI_EXPORT std::ostream &operator<<(std::ostream &_out, const Address &_address);
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_ADDRESS_HPP_
diff --git a/include/CommonAPI/Attribute.hpp b/include/CommonAPI/Attribute.hpp
new file mode 100644
index 0000000..200d3bb
--- /dev/null
+++ b/include/CommonAPI/Attribute.hpp
@@ -0,0 +1,143 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_ATTRIBUTE_HPP_
+#define COMMONAPI_ATTRIBUTE_HPP_
+
+#include <cstdint>
+#include <functional>
+#include <future>
+#include <memory>
+
+#include <CommonAPI/CallInfo.hpp>
+#include <CommonAPI/Event.hpp>
+#include <CommonAPI/Types.hpp>
+
+namespace CommonAPI {
+
+/**
+ * \brief Class representing a read only attribute
+ *
+ * Class representing a read only attribute
+ */
+template <typename _ValueType>
+class ReadonlyAttribute {
+ public:
+ typedef _ValueType ValueType;
+
+ typedef std::function<void(const CallStatus &, _ValueType)> AttributeAsyncCallback;
+
+ virtual ~ReadonlyAttribute() { }
+
+ /**
+ * \brief Get value of attribute, usually from remote. Synchronous call.
+ *
+ * Get value of attribute, usually from remote. Synchronous call.
+ *
+ * @param value Reference to be filled with value.
+ * @param callStatus call status reference will be filled with status of the operation
+ */
+ virtual void getValue(CallStatus &_status,
+ _ValueType &_value,
+ const CallInfo *_info = nullptr) const = 0;
+
+ /**
+ * \brief Get value of attribute, usually from remote. Asynchronous call.
+ *
+ * Get value of attribute, usually from remote. Asynchronous call.
+ *
+ * @param attributeAsyncCallback std::function object for the callback to be invoked.
+ * @return std::future containing the call status of the operation.
+ */
+ virtual std::future<CallStatus> getValueAsync(AttributeAsyncCallback attributeAsyncCallback,
+ const CallInfo *_info = nullptr) = 0;
+};
+
+/**
+ * \brief Class representing a read and writable attribute
+ *
+ * Class representing a read and writable attribute
+ */
+template <typename _ValueType>
+class Attribute: public ReadonlyAttribute<_ValueType> {
+ public:
+ typedef typename ReadonlyAttribute<_ValueType>::ValueType ValueType;
+ typedef typename ReadonlyAttribute<_ValueType>::AttributeAsyncCallback AttributeAsyncCallback;
+
+ virtual ~Attribute() { }
+
+ /**
+ * \brief Set value of attribute, usually to remote. Synchronous call.
+ *
+ * Set value of attribute, usually to remote. Synchronous call.
+ *
+ * @param requestValue Value to be set
+ * @param callStatus call status reference will be filled with status of the operation
+ * @param responseValue Reference which will contain the actuall value set by the remote.
+ */
+ virtual void setValue(const _ValueType& requestValue,
+ CallStatus& callStatus,
+ _ValueType& responseValue,
+ const CallInfo *_info = nullptr) = 0;
+
+ /**
+ * \brief Set value of attribute, usually to remote. Asynchronous call.
+ *
+ * Set value of attribute, usually to remote. Asynchronous call.
+ *
+ * @param requestValue Value to be set
+ * @param attributeAsyncCallback std::function object for the callback to be invoked.
+ * @return std::future containing the call status of the operation.
+ */
+ virtual std::future<CallStatus> setValueAsync(const _ValueType& requestValue,
+ AttributeAsyncCallback attributeAsyncCallback,
+ const CallInfo *_info = nullptr) = 0;
+};
+
+/**
+ * \brief Class representing an observable attribute
+ *
+ * Class representing an observable attribute
+ */
+template <typename _AttributeBaseClass>
+class _ObservableAttributeImpl: public _AttributeBaseClass {
+ public:
+ typedef typename _AttributeBaseClass::ValueType ValueType;
+ typedef typename _AttributeBaseClass::AttributeAsyncCallback AttributeAsyncCallback;
+ typedef Event<ValueType> ChangedEvent;
+
+ virtual ~_ObservableAttributeImpl() { }
+
+ /**
+ * \brief Returns the event handler for the remote change notification event
+ *
+ * Returns the event handler for the remote change notification event
+ *
+ * @return The event handler object
+ */
+ virtual ChangedEvent& getChangedEvent() = 0;
+};
+
+template <typename _ValueType>
+struct ObservableReadonlyAttribute: _ObservableAttributeImpl< ReadonlyAttribute<_ValueType> > {
+};
+
+template <typename _ValueType>
+struct ObservableAttribute: _ObservableAttributeImpl< Attribute<_ValueType> > {
+};
+
+#ifdef WIN32
+struct WINDummyAttribute {
+ WINDummyAttribute() {}
+};
+#endif
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_ATTRIBUTE_HPP_
diff --git a/include/CommonAPI/AttributeExtension.hpp b/include/CommonAPI/AttributeExtension.hpp
new file mode 100644
index 0000000..5135924
--- /dev/null
+++ b/include/CommonAPI/AttributeExtension.hpp
@@ -0,0 +1,54 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMON_API_DBUS_ATTRIBUTE_EXTENSION_HPP_
+#define COMMON_API_DBUS_ATTRIBUTE_EXTENSION_HPP_
+
+#include <cstdint>
+#include <functional>
+#include <memory>
+
+#include <CommonAPI/Event.hpp>
+#include <CommonAPI/Types.hpp>
+
+#ifdef WIN32
+#include "Attribute.hpp"
+#endif
+
+namespace CommonAPI {
+
+template<typename _AttributeType>
+class AttributeExtension {
+ public:
+ _AttributeType& getBaseAttribute() {
+ return baseAttribute_;
+ }
+
+ protected:
+ AttributeExtension() = delete;
+ AttributeExtension(_AttributeType& baseAttribute): baseAttribute_(baseAttribute) {
+ }
+
+ _AttributeType& baseAttribute_;
+};
+
+#ifdef WIN32
+template<typename _AttributeType>
+class WINDummyAttributeExtension : public CommonAPI::AttributeExtension<_AttributeType> {
+ typedef AttributeExtension<_AttributeType> __baseClass_t;
+ WINDummyAttribute dummyAttribute;
+public:
+ WINDummyAttributeExtension() {};
+ ~WINDummyAttributeExtension() {}
+};
+#endif
+
+} // namespace CommonAPI
+
+#endif // COMMON_API_DBUS_ATTRIBUTE_EXTENSION_HPP_
diff --git a/include/CommonAPI/ByteBuffer.hpp b/include/CommonAPI/ByteBuffer.hpp
new file mode 100644
index 0000000..5d3ad39
--- /dev/null
+++ b/include/CommonAPI/ByteBuffer.hpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef COMMONAPI_BYTE_BUFFER_HPP_
+#define COMMONAPI_BYTE_BUFFER_HPP_
+
+#include <vector>
+#include <cstdint>
+
+namespace CommonAPI {
+
+typedef std::vector<uint8_t> ByteBuffer;
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_BYTE_BUFFER_HPP_
diff --git a/include/CommonAPI/CallInfo.hpp b/include/CommonAPI/CallInfo.hpp
new file mode 100644
index 0000000..a6f43bd
--- /dev/null
+++ b/include/CommonAPI/CallInfo.hpp
@@ -0,0 +1,31 @@
+// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef COMMONAPI_CALLINFO_HPP_
+#define COMMONAPI_CALLINFO_HPP_
+
+#include <CommonAPI/Config.hpp>
+#include <CommonAPI/Types.hpp>
+
+namespace CommonAPI {
+
+struct COMMONAPI_EXPORT CallInfo {
+ CallInfo()
+ : timeout_(DEFAULT_SEND_TIMEOUT_MS), sender_(0) {
+ }
+ CallInfo(Timeout_t _timeout)
+ : timeout_(_timeout), sender_(0) {
+ }
+ CallInfo(Timeout_t _timeout, Sender_t _sender)
+ : timeout_(_timeout), sender_(_sender) {
+ }
+
+ Timeout_t timeout_;
+ Sender_t sender_;
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_ADDRESS_HPP_
diff --git a/include/CommonAPI/CommonAPI.hpp b/include/CommonAPI/CommonAPI.hpp
new file mode 100644
index 0000000..5568330
--- /dev/null
+++ b/include/CommonAPI/CommonAPI.hpp
@@ -0,0 +1,22 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef COMMONAPI_HPP_
+#define COMMONAPI_HPP_
+
+#ifndef COMMONAPI_INTERNAL_COMPILATION
+#define COMMONAPI_INTERNAL_COMPILATION
+#endif
+
+#include "Address.hpp"
+#include "AttributeExtension.hpp"
+#include "ByteBuffer.hpp"
+#include "MainLoopContext.hpp"
+#include "Runtime.hpp"
+#include "Types.hpp"
+
+#undef COMMONAPI_INTERNAL_COMPILATION
+
+#endif // COMMONAPI_HPP_
diff --git a/include/CommonAPI/Config.hpp b/include/CommonAPI/Config.hpp
new file mode 100644
index 0000000..fb99bf3
--- /dev/null
+++ b/include/CommonAPI/Config.hpp
@@ -0,0 +1,17 @@
+// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef COMMONAPI_CONFIG_HPP_
+#define COMMONAPI_CONFIG_HPP_
+
+#include <CommonAPI/Types.hpp>
+
+namespace CommonAPI {
+
+static const Timeout_t DEFAULT_SEND_TIMEOUT_MS = 5000;
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_CONFIG_HPP_
diff --git a/include/CommonAPI/ContainerUtils.hpp b/include/CommonAPI/ContainerUtils.hpp
new file mode 100644
index 0000000..9fddc08
--- /dev/null
+++ b/include/CommonAPI/ContainerUtils.hpp
@@ -0,0 +1,33 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_CONTAINERUTILS_HPP_
+#define COMMONAPI_CONTAINERUTILS_HPP_
+
+#include <functional>
+#include <memory>
+
+#include <CommonAPI/Export.hpp>
+
+namespace CommonAPI {
+class ClientId;
+
+struct COMMONAPI_EXPORT SharedPointerClientIdContentHash : public std::unary_function<std::shared_ptr<ClientId>, size_t> {
+ size_t operator()(const std::shared_ptr<ClientId>& t) const;
+};
+
+struct COMMONAPI_EXPORT SharedPointerClientIdContentEqual : public std::binary_function<std::shared_ptr<ClientId>, std::shared_ptr<ClientId>, bool> {
+ bool operator()(const std::shared_ptr<ClientId>& a, const std::shared_ptr<ClientId>& b) const;
+};
+
+
+} // namespace std
+
+
+#endif // COMMONAPI_CONTAINERUTILS_HPP_
diff --git a/include/CommonAPI/Deployable.hpp b/include/CommonAPI/Deployable.hpp
new file mode 100644
index 0000000..7a9002c
--- /dev/null
+++ b/include/CommonAPI/Deployable.hpp
@@ -0,0 +1,59 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_DEPLOYABLE_HPP_
+#define COMMONAPI_DEPLOYABLE_HPP_
+
+namespace CommonAPI {
+
+struct DeployableBase {
+};
+
+template<typename _Type, typename _TypeDepl>
+struct Deployable : DeployableBase
+{
+ Deployable(const _TypeDepl *_depl = nullptr)
+ : depl_(const_cast<_TypeDepl *>(_depl)) {
+ }
+
+ Deployable(const _Type &_value, const _TypeDepl *_depl)
+ : value_(_value),
+ depl_(const_cast<_TypeDepl *>(_depl)) {
+ };
+
+ Deployable<_Type, _TypeDepl>& operator=(const Deployable<_Type, _TypeDepl> &_source) {
+ value_ = _source.value_;
+ depl_ = _source.depl_;
+ return (*this);
+ }
+
+ operator _Type() const {
+ return value_;
+ }
+
+ const _Type &getValue() const {
+ return value_;
+ }
+
+ _Type &getValue() {
+ return value_;
+ }
+
+ const _TypeDepl *getDepl() const {
+ return depl_;
+ }
+
+ protected:
+ _Type value_;
+ _TypeDepl *depl_;
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DEPLOYABLE_HPP_
diff --git a/include/CommonAPI/Deployment.hpp b/include/CommonAPI/Deployment.hpp
new file mode 100644
index 0000000..db2a914
--- /dev/null
+++ b/include/CommonAPI/Deployment.hpp
@@ -0,0 +1,75 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.hpp> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_DEPLOYMENT_HPP_
+#define COMMONAPI_DEPLOYMENT_HPP_
+
+#include <tuple>
+
+namespace CommonAPI {
+// The binding-specific deployment parameters should be
+// defined like this:
+//
+// struct BindingUInt16Deployment : CommonAPI::Deployment<> {
+// // Binding-specific bool deployment parameters
+// };
+//
+// struct BindingStringDeployment : CommonAPI::Deployment<> {
+// // Binding-specific String deployment parameters
+// };
+//
+// template<typename... _Types>
+// struct BindingStructDeployment
+// : CommonAPI::Deployment<_Types...> {
+// BindingStructDeployment(<SPECIFIC PARAMETERS>, _Types... t)
+// : CommonAPI::Deployment<_Types...>(t),
+// <SPECIFIC INITIALIZERS> {};
+//
+// // Binding-specific struct deployment parameters
+// };
+//
+// The generated code needs to use these definitions to
+// provide the deployment informations for the actual data.
+// E.g., for struct consisting of a boolean and a string
+// value, it needs to generate:
+//
+// CommonAPI::BindingStructDeployment<
+// CommonAPI::BindingBoolDeployment,
+// CommonAPI::BindingStringDeployment
+// > itsDeployment(<PARAMS);
+
+struct EmptyDeployment {};
+
+template<typename _ElementDepl>
+struct ArrayDeployment {
+ ArrayDeployment(_ElementDepl *_elementDepl)
+ : elementDepl_(_elementDepl) {}
+
+ _ElementDepl *elementDepl_;
+};
+
+template<typename _KeyDepl, typename _ValueDepl>
+struct MapDeployment {
+ MapDeployment(_KeyDepl *_key, _ValueDepl *_value)
+ : key_(_key), value_(_value) {}
+
+ const _KeyDepl *key_;
+ const _ValueDepl *value_;
+};
+
+// The following shall be used as a base for structure/variant deployments.
+template<typename... _Types>
+struct Deployment {
+ Deployment(_Types*... _values) : values_(_values...) {}
+ std::tuple<_Types*...> values_;
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DEPLOYABLE_HPP_
diff --git a/include/CommonAPI/Enumeration.hpp b/include/CommonAPI/Enumeration.hpp
new file mode 100644
index 0000000..1a4d5f4
--- /dev/null
+++ b/include/CommonAPI/Enumeration.hpp
@@ -0,0 +1,40 @@
+// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef COMMONAPI_ENUMERATION_HPP_
+#define COMMONAPI_ENUMERATION_HPP_
+
+namespace CommonAPI {
+
+template <typename _Base>
+struct Enumeration {
+ Enumeration() = default;
+ Enumeration(const _Base &_value)
+ : value_(_value) {
+ }
+
+ inline Enumeration &operator=(const _Base &_value) {
+ value_ = _value;
+ return (*this);
+ }
+
+ inline operator const _Base() const {
+ return value_;
+ }
+
+ inline bool operator == (const Enumeration<_Base> &_other) const {
+ return value_ == _other.value_;
+ }
+
+ inline bool operator != (const Enumeration<_Base> &_other) const {
+ return value_ != _other.value_;
+ }
+
+ _Base value_;
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_ENUMERATION_HPP_
diff --git a/include/CommonAPI/Event.hpp b/include/CommonAPI/Event.hpp
new file mode 100644
index 0000000..90971f5
--- /dev/null
+++ b/include/CommonAPI/Event.hpp
@@ -0,0 +1,158 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_EVENT_HPP_
+#define COMMONAPI_EVENT_HPP_
+
+#include <functional>
+#include <mutex>
+#include <map>
+#include <set>
+#include <tuple>
+
+namespace CommonAPI {
+
+/**
+ * \brief Class representing an event
+ *
+ * Class representing an event
+ */
+template<typename... _Arguments>
+class Event {
+public:
+ typedef std::tuple<_Arguments...> ArgumentsTuple;
+ typedef std::function<void(const _Arguments&...)> Listener;
+ typedef uint32_t Subscription;
+ typedef std::set<Subscription> SubscriptionsSet;
+ typedef std::map<Subscription, Listener> ListenersMap;
+
+ /**
+ * \brief Constructor
+ */
+ Event() : nextSubscription_(0) {};
+
+ /**
+ * \brief Subscribe a listener to this event
+ *
+ * Subscribe a listener to this event.
+ * ATTENTION: You should not build new proxies or register services in callbacks
+ * from events. This can cause a deadlock or assert. Instead, you should set a
+ * trigger for your application to do this on the next iteration of your event loop
+ * if needed. The preferred solution is to build all proxies you need at the
+ * beginning and react to events appropriatly for each.
+ *
+ * @param listener A listener to be added
+ * @return key of the new subscription
+ */
+ Subscription subscribe(Listener listener);
+
+ /**
+ * \brief Remove a listener from this event
+ *
+ * Remove a listener from this event
+ * Note: Do not call this inside a listener notification callback it will deadlock! Use cancellable listeners instead.
+ *
+ * @param subscription A listener token to be removed
+ */
+ void unsubscribe(Subscription subscription);
+
+ virtual ~Event() {}
+
+protected:
+ void notifyListeners(const _Arguments&... eventArguments);
+
+ virtual void onFirstListenerAdded(const Listener& listener) {}
+ virtual void onListenerAdded(const Listener& listener) {}
+
+ virtual void onListenerRemoved(const Listener& listener) {}
+ virtual void onLastListenerRemoved(const Listener& listener) {}
+
+//private:
+ ListenersMap subscriptions_;
+ Subscription nextSubscription_;
+
+ ListenersMap pendingSubscriptions_;
+ SubscriptionsSet pendingUnsubscriptions_;
+
+ std::mutex notificationMutex_;
+ std::mutex subscriptionMutex_;
+};
+
+template<typename ... _Arguments>
+typename Event<_Arguments...>::Subscription Event<_Arguments...>::subscribe(Listener listener) {
+ Subscription subscription;
+ bool isFirstListener;
+
+ subscriptionMutex_.lock();
+ subscription = nextSubscription_++;
+ // TODO?: check for key/subscription overrun
+ listener = pendingSubscriptions_[subscription] = std::move(listener);
+ isFirstListener = (0 == subscriptions_.size());
+ subscriptionMutex_.unlock();
+
+ if (isFirstListener)
+ onFirstListenerAdded(listener);
+ onListenerAdded(listener);
+
+ return subscription;
+}
+
+template<typename ... _Arguments>
+void Event<_Arguments...>::unsubscribe(Subscription subscription) {
+ bool isLastListener(false);
+
+ subscriptionMutex_.lock();
+ auto listener = subscriptions_.find(subscription);
+ if (subscriptions_.end() != listener
+ && pendingUnsubscriptions_.end() == pendingUnsubscriptions_.find(subscription)) {
+ if (0 == pendingSubscriptions_.erase(subscription)) {
+ pendingUnsubscriptions_.insert(subscription);
+ isLastListener = (1 == subscriptions_.size());
+ } else {
+ isLastListener = (0 == subscriptions_.size());
+ }
+ }
+ subscriptionMutex_.unlock();
+
+ if (subscriptions_.end() != listener) {
+ onListenerRemoved(listener->second);
+ if (isLastListener)
+ onLastListenerRemoved(listener->second);
+ }
+}
+
+template<typename ... _Arguments>
+void Event<_Arguments...>::notifyListeners(const _Arguments&... eventArguments) {
+ subscriptionMutex_.lock();
+ notificationMutex_.lock();
+ for (auto iterator = pendingUnsubscriptions_.begin();
+ iterator != pendingUnsubscriptions_.end();
+ iterator++) {
+ subscriptions_.erase(*iterator);
+ }
+ pendingUnsubscriptions_.clear();
+
+ for (auto iterator = pendingSubscriptions_.begin();
+ iterator != pendingSubscriptions_.end();
+ iterator++) {
+ subscriptions_.insert(*iterator);
+ }
+ pendingSubscriptions_.clear();
+
+ subscriptionMutex_.unlock();
+ for (auto iterator = subscriptions_.begin(); iterator != subscriptions_.end(); iterator++) {
+ iterator->second(eventArguments...);
+ }
+
+ notificationMutex_.unlock();
+}
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_EVENT_HPP_
diff --git a/include/CommonAPI/Export.hpp b/include/CommonAPI/Export.hpp
new file mode 100644
index 0000000..1fe9734
--- /dev/null
+++ b/include/CommonAPI/Export.hpp
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef COMMONAPI_EXPORT_HPP_
+#define COMMONAPI_EXPORT_HPP_
+
+#ifdef WIN32
+ #define COMMONAPI_EXPORT __declspec(dllexport)
+
+ #if COMMONAPI_DLL_COMPILATION
+ #define COMMONAPI_IMPORT_EXPORT __declspec(dllexport)
+ #else
+ #define COMMONAPI_IMPORT_EXPORT __declspec(dllimport)
+ #endif
+#else
+ #define COMMONAPI_EXPORT
+ #define COMMONAPI_IMPORT_EXPORT
+#endif
+
+#endif // COMMONAPI_EXPORT_HPP_
diff --git a/include/CommonAPI/Factory.hpp b/include/CommonAPI/Factory.hpp
new file mode 100644
index 0000000..df8354d
--- /dev/null
+++ b/include/CommonAPI/Factory.hpp
@@ -0,0 +1,58 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef COMMONAPI_FACTORY_HPP_
+#define COMMONAPI_FACTORY_HPP_
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include <CommonAPI/Export.hpp>
+#include <CommonAPI/Types.hpp>
+
+namespace CommonAPI {
+
+class MainLoopContext;
+class Proxy;
+class StubBase;
+
+class COMMONAPI_EXPORT Factory {
+public:
+ typedef std::function<void(std::vector<std::string> &)> AvailableInstancesCbk_t;
+ typedef std::function<void(bool)> InstanceAliveCbk_t;
+
+ virtual ~Factory() {};
+
+ virtual std::shared_ptr<Proxy> createProxy(const std::string &_domain,
+ const std::string &_interface,
+ const std::string &_instance,
+ const ConnectionId_t &_connectionId) = 0;
+
+ virtual std::shared_ptr<Proxy> createProxy(const std::string &_domain,
+ const std::string &_interface,
+ const std::string &_instance,
+ std::shared_ptr<MainLoopContext> mainLoopContext) = 0;
+
+ virtual bool registerStub(const std::string &_domain,
+ const std::string &_interface,
+ const std::string &_instance,
+ std::shared_ptr<StubBase> _stub,
+ const ConnectionId_t &_connectionId) = 0;
+
+ virtual bool registerStub(const std::string &_domain,
+ const std::string &_interface,
+ const std::string &_instance,
+ std::shared_ptr<StubBase> _stub,
+ std::shared_ptr<MainLoopContext> mainLoopContext) = 0;
+
+ virtual bool unregisterStub(const std::string &_domain,
+ const std::string &_interface,
+ const std::string &_instance) = 0;
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_FACTORY_HPP_
diff --git a/include/CommonAPI/IniFileReader.hpp b/include/CommonAPI/IniFileReader.hpp
new file mode 100644
index 0000000..13b64c3
--- /dev/null
+++ b/include/CommonAPI/IniFileReader.hpp
@@ -0,0 +1,40 @@
+// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef COMMONAPI_INIFILEREADER_HPP_
+#define COMMONAPI_INIFILEREADER_HPP_
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include <CommonAPI/Export.hpp>
+
+namespace CommonAPI {
+
+class IniFileReader {
+public:
+ class Section {
+ public:
+ COMMONAPI_EXPORT const std::map<std::string, std::string> &getMappings() const;
+ COMMONAPI_EXPORT std::string getValue(const std::string &_key) const;
+ private:
+ std::map<std::string, std::string> mappings_;
+
+ friend class IniFileReader;
+ };
+
+ COMMONAPI_EXPORT bool load(const std::string &_path);
+
+ COMMONAPI_EXPORT const std::map<std::string, std::shared_ptr<Section>> &getSections() const;
+ COMMONAPI_EXPORT std::shared_ptr<Section> getSection(const std::string &_name) const;
+
+private:
+ std::map<std::string, std::shared_ptr<Section>> sections_;
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_INIFILEREADER_HPP_
diff --git a/include/CommonAPI/InputStream.hpp b/include/CommonAPI/InputStream.hpp
new file mode 100644
index 0000000..f5cbc12
--- /dev/null
+++ b/include/CommonAPI/InputStream.hpp
@@ -0,0 +1,241 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_INPUT_STREAM_HPP_
+#define COMMONAPI_INPUT_STREAM_HPP_
+
+#include <unordered_map>
+
+#include <CommonAPI/ByteBuffer.hpp>
+#include <CommonAPI/Deployable.hpp>
+#include <CommonAPI/Deployment.hpp>
+#include <CommonAPI/Enumeration.hpp>
+#include <CommonAPI/Struct.hpp>
+#include <CommonAPI/Variant.hpp>
+#include <CommonAPI/Version.hpp>
+
+namespace CommonAPI {
+
+template<class _Derived>
+class InputStream {
+public:
+ template<class _Deployment>
+ InputStream &readValue(bool &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ InputStream &readValue(int8_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ InputStream &readValue(int16_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ InputStream &readValue(int32_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ InputStream &readValue(int64_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ InputStream &readValue(uint8_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ InputStream &readValue(uint16_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ InputStream &readValue(uint32_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ InputStream &readValue(uint64_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ InputStream &readValue(float &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ InputStream &readValue(double &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ InputStream &readValue(std::string &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment, typename _Base>
+ InputStream &readValue(Enumeration<_Base> &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment, typename... _Types>
+ InputStream &readValue(Struct<_Types...> &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment, class _PolymorphicStruct>
+ InputStream &readValue(std::shared_ptr<_PolymorphicStruct> &_value,
+ const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment, typename... _Types>
+ InputStream &readValue(Variant<_Types...> &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment, typename _ElementType>
+ InputStream &readValue(std::vector<_ElementType> &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment, typename _KeyType, typename _ValueType, typename _HasherType>
+ InputStream &readValue(std::unordered_map<_KeyType, _ValueType, _HasherType> &_value,
+ const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ InputStream &readValue(Version &_value, const _Deployment *_depl = nullptr) {
+ return get()->readValue(_value, _depl);
+ }
+
+ bool hasError() const {
+ return get()->hasError();
+ }
+
+private:
+ inline _Derived *get() {
+ return static_cast<_Derived *>(this);
+ }
+
+ inline const _Derived *get() const {
+ return static_cast<const _Derived *>(this);
+ }
+};
+
+template<class _Derived>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, bool &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, int8_t &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, int16_t &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, int32_t &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, int64_t &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, uint8_t &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, uint16_t &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, uint32_t &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, uint64_t &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, float &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, double &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, std::string &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, Version &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, typename _Base>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, Enumeration<_Base> &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, typename... _Types>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, Struct<_Types...> &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, class _PolymorphicStruct>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, std::shared_ptr<_PolymorphicStruct> &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, typename... _Types>
+InputStream<_Derived> & operator>>(InputStream<_Derived> &_input, Variant<_Types...> &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, typename _ElementType>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, std::vector<_ElementType> &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, typename _KeyType, typename _ValueType, typename _HasherType>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, std::unordered_map<_KeyType, _ValueType, _HasherType> &_value) {
+ return _input.template readValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, typename _Type, typename _TypeDeployment>
+InputStream<_Derived> &operator>>(InputStream<_Derived> &_input, Deployable<_Type, _TypeDeployment> &_value) {
+ return _input.template readValue<_TypeDeployment>(_value.getValue(), _value.getDepl());
+}
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_INPUT_STREAM_HPP_
diff --git a/include/CommonAPI/Logger.hpp b/include/CommonAPI/Logger.hpp
new file mode 100644
index 0000000..d2761ac
--- /dev/null
+++ b/include/CommonAPI/Logger.hpp
@@ -0,0 +1,179 @@
+// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef COMMONAPI_LOGGER_HPP_
+#define COMMONAPI_LOGGER_HPP_
+
+#ifdef USE_DLT
+#include <dlt.h>
+#endif
+
+#include <cstdint>
+#include <fstream>
+#include <memory>
+#include <mutex>
+#include <sstream>
+
+#include <CommonAPI/Export.hpp>
+
+#define COMMONAPI_LOGLEVEL_FATAL 0
+#define COMMONAPI_LOGLEVEL_ERROR 1
+#define COMMONAPI_LOGLEVEL_WARNING 2
+#define COMMONAPI_LOGLEVEL_INFO 3
+#define COMMONAPI_LOGLEVEL_DEBUG 4
+#define COMMONAPI_LOGLEVEL_VERBOSE 5
+
+#ifndef COMMONAPI_LOGLEVEL
+#define COMMONAPI_LOGLEVEL COMMONAPI_LOGLEVEL_INFO
+#endif
+
+#ifdef WIN32
+
+#define COMMONAPI_FATAL(...) \
+ do { Logger::log(Logger::Level::LL_FATAL, __VA_ARGS__); } while (false);
+
+#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_ERROR
+#define COMMONAPI_ERROR(...) \
+ do { Logger::log(Logger::Level::LL_ERROR, __VA_ARGS__); } while (false);
+#else
+#define COMMONAPI_ERROR(...)
+#endif
+
+#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_WARNING
+#define COMMONAPI_WARNING(...) \
+ do { Logger::log(Logger::Level::LL_WARNING, __VA_ARGS__); } while (false);
+#else
+#define COMMONAPI_WARNING(...)
+#endif
+
+#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_INFO
+#define COMMONAPI_INFO(...) \
+ do { Logger::log(Logger::Level::LL_INFO, __VA_ARGS__); } while (false);
+#else
+#define COMMONAPI_INFO(...)
+#endif
+
+#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_DEBUG
+#define COMMONAPI_DEBUG(...) \
+ do { Logger::log(Logger::Level::LL_DEBUG, __VA_ARGS__); } while (false);
+#else
+#define COMMONAPI_DEBUG(...)
+#endif
+
+#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_VERBOSE
+#define COMMONAPI_VERBOSE(...) \
+ do { Logger::log(Logger::Level::LL_VERBOSE, __VA_ARGS__); } while (false);
+#else
+#define COMMONAPI_VERBOSE(...)
+#endif
+
+#else // !WIN32
+
+#define COMMONAPI_FATAL(params...) \
+ do { Logger::log(Logger::Level::LL_FATAL, params); } while (false);
+
+#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_ERROR
+ #define COMMONAPI_ERROR(params...) \
+ do { Logger::log(Logger::Level::LL_ERROR, params); } while (false);
+#else
+ #define COMMONAPI_ERROR(params...)
+#endif
+
+#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_WARNING
+ #define COMMONAPI_WARNING(params...) \
+ do { Logger::log(Logger::Level::LL_WARNING, params); } while (false);
+#else
+ #define COMMONAPI_WARNING(params...)
+#endif
+
+#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_INFO
+ #define COMMONAPI_INFO(params...) \
+ do { Logger::log(Logger::Level::LL_INFO, params); } while (false);
+#else
+ #define COMMONAPI_INFO(params...)
+#endif
+
+#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_DEBUG
+ #define COMMONAPI_DEBUG(params...) \
+ do { Logger::log(Logger::Level::LL_DEBUG, params); } while (false);
+#else
+ #define COMMONAPI_DEBUG(params...)
+#endif
+
+#if COMMONAPI_LOGLEVEL >= COMMONAPI_LOGLEVEL_VERBOSE
+ #define COMMONAPI_VERBOSE(params...) \
+ do { Logger::log(Logger::Level::LL_VERBOSE, params); } while (false);
+#else
+ #define COMMONAPI_VERBOSE(params...)
+#endif
+
+#endif // WIN32
+
+namespace CommonAPI {
+
+class Logger {
+public:
+ COMMONAPI_EXPORT enum class Level : uint8_t {
+ LL_FATAL = 0, LL_ERROR = 1, LL_WARNING = 2, LL_INFO = 3, LL_DEBUG = 4, LL_VERBOSE = 5
+ };
+
+ COMMONAPI_EXPORT Logger();
+
+ template<typename... _LogEntries>
+ COMMONAPI_EXPORT static void log(Level _level, _LogEntries... _entries) {
+ std::stringstream buffer;
+ log_intern(buffer, _entries...);
+ Logger::get()->doLog(_level, buffer.str());
+ }
+
+ COMMONAPI_EXPORT static void init(bool, const std::string &, bool = false, const std::string & = "");
+
+private:
+ COMMONAPI_EXPORT static inline std::shared_ptr<Logger> get() {
+ static std::shared_ptr<Logger> theLogger = std::make_shared<Logger>();
+ return theLogger;
+ }
+
+ COMMONAPI_EXPORT static void log_intern(std::stringstream &_buffer) {
+ }
+
+ template<typename _LogEntry, typename... _MoreLogEntries>
+ COMMONAPI_EXPORT static void log_intern(std::stringstream &_buffer, _LogEntry _entry, _MoreLogEntries... _moreEntries) {
+ _buffer << _entry;
+ log_intern(_buffer, _moreEntries...);
+ }
+
+ COMMONAPI_EXPORT void doLog(Level _level, const std::string &_message);
+
+#if defined(USE_CONSOLE) || defined(USE_FILE) || defined(USE_DLT)
+ static Level stringAsLevel(const std::string &_level);
+#endif
+#if defined(USE_CONSOLE) || defined(USE_FILE)
+ static std::string levelAsString(Level _level);
+#endif
+#ifdef USE_DLT
+ static DltLogLevelType levelAsDlt(Level _level);
+#endif
+#if defined(USE_CONSOLE) || defined(USE_FILE)
+ static std::mutex mutex_;
+#endif
+#if defined(USE_CONSOLE) || defined(USE_FILE) || defined(USE_DLT)
+ static Level maximumLogLevel_;
+#endif
+#ifdef USE_CONSOLE
+ static bool useConsole_;
+#endif
+#ifdef USE_FILE
+ static std::shared_ptr<std::ofstream> file_;
+#endif
+#ifdef USE_DLT
+ static bool useDlt_;
+ DLT_DECLARE_CONTEXT(dlt_);
+#endif
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_LOGGER_HPP_
diff --git a/include/CommonAPI/MainLoopContext.hpp b/include/CommonAPI/MainLoopContext.hpp
new file mode 100644
index 0000000..b2e1056
--- /dev/null
+++ b/include/CommonAPI/MainLoopContext.hpp
@@ -0,0 +1,299 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_MAINLOOPCONTEXT_HPP_
+#define COMMONAPI_MAINLOOPCONTEXT_HPP_
+
+#include <cstdint>
+
+#ifdef WIN32
+#include <WinSock2.h>
+#else
+#include <poll.h>
+#endif
+
+#ifdef WIN32
+#undef max
+#endif
+
+#include <limits>
+#include <vector>
+#include <chrono>
+#include <list>
+#include <functional>
+#include <string>
+
+#include <CommonAPI/Export.hpp>
+
+namespace CommonAPI {
+
+enum class DispatchPriority {
+ VERY_HIGH,
+ HIGH,
+ DEFAULT,
+ LOW,
+ VERY_LOW
+};
+
+
+int64_t COMMONAPI_EXPORT getCurrentTimeInMs();
+
+
+/**
+ * \brief Describes a basic element that periodically needs to be dispatched.
+ *
+ * A DispatchSource is not directly related to a file descriptor, but
+ * may be dependent on a watch that manages a file descriptor. If this
+ * is the case, the corresponding Watch will provide information about
+ * which DispatchSources are dependent.
+ */
+struct DispatchSource {
+ virtual ~DispatchSource() {}
+
+ /**
+ * Indicates whether this source is ready to be dispatched.
+ * "Prepare" will be called before polling the file descriptors.
+ *
+ * @return 'true' if the source is ready to be dispatched.
+ */
+ virtual bool prepare(int64_t& timeout) = 0;
+
+ /**
+ * Indicates whether this source is ready to be dispatched.
+ * "Check" will be called after polling the file descriptors.
+ *
+ * @return 'true' if the source is ready to be dispatched.
+ */
+ virtual bool check() = 0;
+
+ /**
+ * The return value indicates whether this dispatch source currently has
+ * more data to dispatch. The mainloop may chose to ignore the return value.
+ *
+ * @return 'true' if there currently is more to dispatch, 'false' if not.
+ */
+ virtual bool dispatch() = 0;
+};
+
+
+/**
+ * \brief Describes an element that manages a file descriptor.
+ *
+ * The watch is ready to be dispatched whenever it's managed file descriptor
+ * has events in it's revents-field.
+ *
+ * It is possible that there are DispatchSources of which the dispatch readiness
+ * directly depends on the dispatching of the watch. If this is the case, such
+ * DispatchSources can be retrieved from this Watch.
+ */
+struct Watch {
+ virtual ~Watch() {}
+
+ /**
+ * \brief Dispatches the watch.
+ *
+ * Should only be called once the associated file descriptor has events ready.
+ *
+ * @param eventFlags The events that shall be retrieved from the file descriptor.
+ */
+ virtual void dispatch(unsigned int eventFlags) = 0;
+
+ /**
+ * \brief Returns the file descriptor that is managed by this watch.
+ *
+ * @return The associated file descriptor.
+ */
+ virtual const pollfd& getAssociatedFileDescriptor() = 0;
+
+ /**
+ * \brief Returns a vector of all dispatch sources that depend on the watched file descriptor.
+ *
+ * The returned vector will not be empty if and only if there are any sources
+ * that depend on availability of data of the watched file descriptor. Whenever this
+ * Watch is dispatched, those sources likely also need to be dispatched.
+ */
+ virtual const std::vector<DispatchSource*>& getDependentDispatchSources() = 0;
+};
+
+const int64_t TIMEOUT_INFINITE = std::numeric_limits<int64_t>::max();
+const int64_t TIMEOUT_NONE = 0;
+
+
+/**
+ * \brief Describes a basic timeout.
+ *
+ * Timeouts will be taken into consideration when waiting in a call to poll
+ * for a file descriptor to become ready. When the lowest known timeout expires,
+ * the call to poll will return, regardless of whether a file descriptor was ready
+ * or not.
+ */
+struct Timeout {
+ virtual ~Timeout() {}
+
+ /**
+ * Needs to be called when this timeout is expired.
+ *
+ * @return 'true' if the timeout shall be rescheduled, 'false' if it shall be removed.
+ */
+ virtual bool dispatch() = 0;
+
+ /**
+ * \brief The timeout interval in milliseconds.
+ *
+ * Returns TIMEOUT_INFINITE for "dispatch never", TIMEOUT_NONE for "dispatch immediately",
+ * or any positive value as an interval of time in milliseconds that needs to pass before
+ * this timeout is to be dispatched.
+ */
+ virtual int64_t getTimeoutInterval() const = 0;
+
+ /**
+ * \brief Returns the point in time at which this timeout needs to be dispatched next.
+ *
+ * After a initialization and after each dispatch, this timeout will re-calculate it's next
+ * ready time. This value may be ignored if a different mechanism for monitoring timeout intervals
+ * is used.
+ */
+ virtual int64_t getReadyTime() const = 0;
+};
+
+
+typedef std::function<void(DispatchSource*, const DispatchPriority)> DispatchSourceAddedCallback;
+typedef std::function<void(DispatchSource*)> DispatchSourceRemovedCallback;
+typedef std::function<void(Watch*, const DispatchPriority)> WatchAddedCallback;
+typedef std::function<void(Watch*)> WatchRemovedCallback;
+typedef std::function<void(Timeout*, const DispatchPriority)> TimeoutSourceAddedCallback;
+typedef std::function<void(Timeout*)> TimeoutSourceRemovedCallback;
+typedef std::function<void()> WakeupCallback;
+
+typedef std::list<std::pair<DispatchSourceAddedCallback, DispatchSourceRemovedCallback>> DispatchSourceListenerList;
+typedef std::list<std::pair<WatchAddedCallback, WatchRemovedCallback>> WatchListenerList;
+typedef std::list<std::pair<TimeoutSourceAddedCallback, TimeoutSourceRemovedCallback>> TimeoutSourceListenerList;
+typedef std::list<WakeupCallback> WakeupListenerList;
+
+typedef DispatchSourceListenerList::iterator DispatchSourceListenerSubscription;
+typedef WatchListenerList::iterator WatchListenerSubscription;
+typedef TimeoutSourceListenerList::iterator TimeoutSourceListenerSubscription;
+typedef WakeupListenerList::iterator WakeupListenerSubscription;
+
+
+/**
+ * \brief Provides hooks for your Main Loop implementation.
+ *
+ * By registering callbacks with this class, you will be notified about all DispatchSources,
+ * Watches, Timeouts and Wakeup-Events that need to be handled by your Main Loop implementation.
+ *
+ */
+class MainLoopContext {
+public:
+ COMMONAPI_EXPORT MainLoopContext(const std::string &_name = "COMMONAPI_DEFAULT_MAINLOOP_CONTEXT")
+ : name_(_name){
+ }
+
+ COMMONAPI_EXPORT MainLoopContext(const MainLoopContext&) = delete;
+ COMMONAPI_EXPORT MainLoopContext& operator=(const MainLoopContext&) = delete;
+ COMMONAPI_EXPORT MainLoopContext(MainLoopContext&&) = delete;
+ COMMONAPI_EXPORT MainLoopContext& operator=(MainLoopContext&&) = delete;
+
+ COMMONAPI_EXPORT const std::string &getName() const;
+
+ /**
+ * \brief Registers for all DispatchSources that are added or removed.
+ */
+ COMMONAPI_EXPORT DispatchSourceListenerSubscription subscribeForDispatchSources(DispatchSourceAddedCallback dispatchAddedCallback, DispatchSourceRemovedCallback dispatchRemovedCallback);
+
+ /**
+ * \brief Registers for all Watches that are added or removed.
+ */
+ COMMONAPI_EXPORT WatchListenerSubscription subscribeForWatches(WatchAddedCallback watchAddedCallback, WatchRemovedCallback watchRemovedCallback);
+
+ /**
+ * \brief Registers for all Timeouts that are added or removed.
+ */
+ COMMONAPI_EXPORT TimeoutSourceListenerSubscription subscribeForTimeouts(TimeoutSourceAddedCallback timeoutAddedCallback, TimeoutSourceRemovedCallback timeoutRemovedCallback);
+
+ /**
+ * \brief Registers for all Wakeup-Events that need to interrupt a call to "poll".
+ */
+ COMMONAPI_EXPORT WakeupListenerSubscription subscribeForWakeupEvents(WakeupCallback wakeupCallback);
+
+ /**
+ * \brief Unsubscribes your listeners for DispatchSources.
+ */
+ COMMONAPI_EXPORT void unsubscribeForDispatchSources(DispatchSourceListenerSubscription subscription);
+
+ /**
+ * \brief Unsubscribes your listeners for Watches.
+ */
+ COMMONAPI_EXPORT void unsubscribeForWatches(WatchListenerSubscription subscription);
+
+ /**
+ * \brief Unsubscribes your listeners for Timeouts.
+ */
+ COMMONAPI_EXPORT void unsubscribeForTimeouts(TimeoutSourceListenerSubscription subscription);
+
+ /**
+ * \brief Unsubscribes your listeners for Wakeup-Events.
+ */
+ COMMONAPI_EXPORT void unsubscribeForWakeupEvents(WakeupListenerSubscription subscription);
+
+ /**
+ * \brief Notifies all listeners about a new DispatchSource.
+ */
+ COMMONAPI_EXPORT void registerDispatchSource(DispatchSource* dispatchSource, const DispatchPriority dispatchPriority = DispatchPriority::DEFAULT);
+
+ /**
+ * \brief Notifies all listeners about the removal of a DispatchSource.
+ */
+ COMMONAPI_EXPORT void deregisterDispatchSource(DispatchSource* dispatchSource);
+
+ /**
+ * \brief Notifies all listeners about a new Watch.
+ */
+ COMMONAPI_EXPORT void registerWatch(Watch* watch, const DispatchPriority dispatchPriority = DispatchPriority::DEFAULT);
+
+ /**
+ * \brief Notifies all listeners about the removal of a Watch.
+ */
+ COMMONAPI_EXPORT void deregisterWatch(Watch* watch);
+
+ /**
+ * \brief Notifies all listeners about a new Timeout.
+ */
+ COMMONAPI_EXPORT void registerTimeoutSource(Timeout* timeoutEvent, const DispatchPriority dispatchPriority = DispatchPriority::DEFAULT);
+
+ /**
+ * \brief Notifies all listeners about the removal of a Timeout.
+ */
+ COMMONAPI_EXPORT void deregisterTimeoutSource(Timeout* timeoutEvent);
+
+ /**
+ * \brief Notifies all listeners about a wakeup event that just happened.
+ */
+ COMMONAPI_EXPORT void wakeup();
+
+ /**
+ * \brief Will return true if at least one subscribe for DispatchSources or Watches has been called.
+ *
+ * This function will be used to prevent creation of a factory if a mainloop context is given, but
+ * no listeners have been registered. This is done in order to ensure correct use of the mainloop context.
+ */
+ COMMONAPI_EXPORT bool isInitialized();
+
+ private:
+ DispatchSourceListenerList dispatchSourceListeners_;
+ WatchListenerList watchListeners_;
+ TimeoutSourceListenerList timeoutSourceListeners_;
+ WakeupListenerList wakeupListeners_;
+
+ std::string name_;
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_MAINLOOPCONTEXT_HPP_
diff --git a/include/CommonAPI/OutputStream.hpp b/include/CommonAPI/OutputStream.hpp
new file mode 100644
index 0000000..1ca221c
--- /dev/null
+++ b/include/CommonAPI/OutputStream.hpp
@@ -0,0 +1,241 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_OUTPUTSTREAM_HPP_
+#define COMMONAPI_OUTPUTSTREAM_HPP_
+
+#include <unordered_map>
+
+#include <CommonAPI/ByteBuffer.hpp>
+#include <CommonAPI/Deployable.hpp>
+#include <CommonAPI/Deployment.hpp>
+#include <CommonAPI/Enumeration.hpp>
+#include <CommonAPI/Struct.hpp>
+#include <CommonAPI/Variant.hpp>
+#include <CommonAPI/Version.hpp>
+
+namespace CommonAPI {
+
+template<class _Derived>
+class OutputStream {
+public:
+ template<class _Deployment>
+ OutputStream &writeValue(const bool &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ OutputStream &writeValue(const int8_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ OutputStream &writeValue(const int16_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ OutputStream &writeValue(const int32_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ OutputStream &writeValue(const int64_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ OutputStream &writeValue(const uint8_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ OutputStream &writeValue(const uint16_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ OutputStream &writeValue(const uint32_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ OutputStream &writeValue(const uint64_t &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ OutputStream &writeValue(const float &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ OutputStream &writeValue(const double &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ OutputStream &writeValue(const std::string &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment>
+ OutputStream &writeValue(const Version &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment, typename _Base>
+ OutputStream &writeValue(const Enumeration<_Base> &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment, typename... _Types>
+ OutputStream &writeValue(const Struct<_Types...> &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment, class _PolymorphicStruct>
+ OutputStream &writeValue(const std::shared_ptr<_PolymorphicStruct> &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment, typename... _Types>
+ OutputStream &writeValue(const Variant<_Types...> &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment, typename _ElementType>
+ OutputStream &writeValue(const std::vector<_ElementType> &_value, const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ template<class _Deployment, typename _KeyType, typename _ValueType, typename _HasherType>
+ OutputStream &writeValue(const std::unordered_map<_KeyType, _ValueType, _HasherType> &_value,
+ const _Deployment *_depl = nullptr) {
+ return get()->writeValue(_value, _depl);
+ }
+
+ bool hasError() const {
+ return get()->hasError();
+ }
+
+private:
+ inline _Derived *get() {
+ return static_cast<_Derived *>(this);
+ }
+
+ inline const _Derived *get() const {
+ return static_cast<const _Derived *>(this);
+ }
+};
+
+template<class _Derived>
+inline OutputStream<_Derived> &operator<<(OutputStream<_Derived> &_output, const bool &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+inline OutputStream<_Derived>& operator<<(OutputStream<_Derived> &_output, const int8_t &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+inline OutputStream<_Derived>& operator<<(OutputStream<_Derived> &_output, const int16_t &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+inline OutputStream<_Derived>& operator<<(OutputStream<_Derived> &_output, const int32_t &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+inline OutputStream<_Derived>& operator<<(OutputStream<_Derived> &_output, const int64_t &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+inline OutputStream<_Derived>& operator<<(OutputStream<_Derived> &_output, const uint8_t &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+inline OutputStream<_Derived>& operator<<(OutputStream<_Derived> &_output, const uint16_t &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+inline OutputStream<_Derived>& operator<<(OutputStream<_Derived> &_output, const uint32_t &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+inline OutputStream<_Derived>& operator<<(OutputStream<_Derived> &_output, const uint64_t &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+inline OutputStream<_Derived>& operator<<(OutputStream<_Derived> &_output, const float &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+inline OutputStream<_Derived>& operator<<(OutputStream<_Derived> &_output, const double &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived>
+inline OutputStream<_Derived>& operator<<(OutputStream<_Derived> &_output, const std::string &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, typename _Type, typename _TypeDepl>
+inline OutputStream<_Derived> &operator<<(OutputStream<_Derived> &_output, const Deployable<_Type, _TypeDepl> &_value) {
+ return _output.template writeValue<_TypeDepl>(_value.getValue(), _value.getDepl());
+}
+
+template<class _Derived>
+inline OutputStream<_Derived>& operator<<(OutputStream<_Derived> &_output, const Version &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, typename _Base>
+OutputStream<_Derived> &operator<<(OutputStream<_Derived> &_output, const Enumeration<_Base> &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, typename... _Types>
+OutputStream<_Derived> &operator<<(OutputStream<_Derived> &_output, const Struct<_Types...> &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, class _PolymorphicStruct>
+OutputStream<_Derived> &operator<<(OutputStream<_Derived> &_output, const std::shared_ptr<_PolymorphicStruct> &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, typename... _Types>
+OutputStream<_Derived> &operator<<(OutputStream<_Derived> &_output, const Variant<_Types...> &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, typename _ElementType>
+OutputStream<_Derived> &operator<<(OutputStream<_Derived> &_output, const std::vector<_ElementType> &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+template<class _Derived, typename _KeyType, typename _ValueType, typename _HasherType>
+OutputStream<_Derived> &operator<<(OutputStream<_Derived> &_output,
+ const std::unordered_map<_KeyType, _ValueType, _HasherType> &_value) {
+ return _output.template writeValue<EmptyDeployment>(_value);
+}
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_OUTPUTSTREAM_HPP_
diff --git a/include/CommonAPI/Proxy.hpp b/include/CommonAPI/Proxy.hpp
new file mode 100644
index 0000000..5b7d745
--- /dev/null
+++ b/include/CommonAPI/Proxy.hpp
@@ -0,0 +1,47 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_PROXY_HPP_
+#define COMMONAPI_PROXY_HPP_
+
+#include <cstdint>
+#include <memory>
+#include <type_traits>
+
+#include <CommonAPI/Address.hpp>
+#include <CommonAPI/Attribute.hpp>
+#include <CommonAPI/Export.hpp>
+#include <CommonAPI/Version.hpp>
+
+namespace CommonAPI {
+
+typedef Event<AvailabilityStatus> ProxyStatusEvent;
+typedef ReadonlyAttribute<Version> InterfaceVersionAttribute;
+
+class Proxy {
+public:
+ COMMONAPI_EXPORT virtual ~Proxy() {}
+
+ COMMONAPI_EXPORT const Address &getAddress() const;
+
+ COMMONAPI_EXPORT virtual bool isAvailable() const = 0;
+
+ COMMONAPI_EXPORT virtual bool isAvailableBlocking() const = 0;
+
+ COMMONAPI_EXPORT virtual ProxyStatusEvent& getProxyStatusEvent() = 0;
+
+ COMMONAPI_EXPORT virtual InterfaceVersionAttribute& getInterfaceVersionAttribute() = 0;
+
+protected:
+ Address address_;
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_PROXY_HPP_
diff --git a/include/CommonAPI/ProxyManager.hpp b/include/CommonAPI/ProxyManager.hpp
new file mode 100644
index 0000000..571eb97
--- /dev/null
+++ b/include/CommonAPI/ProxyManager.hpp
@@ -0,0 +1,73 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_PROXY_MANAGER_HPP_
+#define COMMONAPI_PROXY_MANAGER_HPP_
+
+#include <functional>
+#include <future>
+#include <string>
+#include <vector>
+
+#include <CommonAPI/Event.hpp>
+#include <CommonAPI/Proxy.hpp>
+#include <CommonAPI/Types.hpp>
+
+namespace CommonAPI {
+
+class ProxyManager {
+public:
+ typedef std::function<void(const CallStatus &, const std::vector<std::string> &)> GetAvailableInstancesCallback;
+ typedef std::function<void(const CallStatus &, const AvailabilityStatus &)> GetInstanceAvailabilityStatusCallback;
+
+ typedef Event<std::string, AvailabilityStatus> InstanceAvailabilityStatusChangedEvent;
+
+ ProxyManager() = default;
+ ProxyManager(ProxyManager &&) = delete;
+ ProxyManager(const ProxyManager &) = delete;
+
+ virtual ~ProxyManager() {}
+
+ virtual const std::string &getDomain() const = 0;
+ virtual const std::string &getInterface() const = 0;
+ virtual const ConnectionId_t &getConnectionId() const = 0;
+
+ virtual void getAvailableInstances(CommonAPI::CallStatus&, std::vector<std::string>& availableInstances) = 0;
+ virtual std::future<CallStatus> getAvailableInstancesAsync(GetAvailableInstancesCallback callback) = 0;
+
+ virtual void getInstanceAvailabilityStatus(const std::string& instanceAddress,
+ CallStatus& callStatus,
+ AvailabilityStatus& availabilityStatus) = 0;
+
+ virtual std::future<CallStatus> getInstanceAvailabilityStatusAsync(const std::string&,
+ GetInstanceAvailabilityStatusCallback callback) = 0;
+
+ virtual InstanceAvailabilityStatusChangedEvent& getInstanceAvailabilityStatusChangedEvent() = 0;
+
+ template<template<typename ...> class _ProxyClass, typename ... _AttributeExtensions>
+ std::shared_ptr<_ProxyClass<_AttributeExtensions...> >
+ buildProxy(const std::string &_instance) {
+ std::shared_ptr<Proxy> proxy = createProxy(getDomain(), getInterface(), _instance, getConnectionId());
+ if (proxy) {
+ return std::make_shared<_ProxyClass<_AttributeExtensions...>>(proxy);
+ }
+ return NULL;
+
+ }
+
+protected:
+ std::shared_ptr<Proxy> createProxy(const std::string &,
+ const std::string &,
+ const std::string &,
+ const ConnectionId_t &_connection) const;
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_PROXY_MANAGER_HPP_
diff --git a/include/CommonAPI/Runtime.hpp b/include/CommonAPI/Runtime.hpp
new file mode 100644
index 0000000..1cb4f94
--- /dev/null
+++ b/include/CommonAPI/Runtime.hpp
@@ -0,0 +1,203 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_RUNTIME_HPP_
+#define COMMONAPI_RUNTIME_HPP_
+
+#include <map>
+#include <memory>
+#include <mutex>
+#include <set>
+
+#include <CommonAPI/Export.hpp>
+#include <CommonAPI/Factory.hpp>
+#include <CommonAPI/Types.hpp>
+
+namespace CommonAPI {
+
+static const ConnectionId_t DEFAULT_CONNECTION_ID = "";
+
+class MainLoopContext;
+class Proxy;
+class ProxyManager;
+class StubBase;
+
+template<template<typename ...> class _ProxyType, template<typename> class _AttributeExtension>
+struct DefaultAttributeProxyHelper;
+
+template<template<typename ...> class _ProxyClass, template<typename> class _AttributeExtension>
+std::shared_ptr<
+ typename DefaultAttributeProxyHelper<_ProxyClass, _AttributeExtension>::class_t
+> createProxyWithDefaultAttributeExtension(
+ const std::string &_domain, const std::string &_instance);
+
+class Runtime {
+public:
+ COMMONAPI_EXPORT static std::string getProperty(const std::string &_name);
+ COMMONAPI_EXPORT static void setProperty(const std::string &_name, const std::string &_value);
+
+ COMMONAPI_EXPORT static std::shared_ptr<Runtime> get();
+
+ COMMONAPI_EXPORT Runtime();
+ COMMONAPI_EXPORT virtual ~Runtime();
+
+ COMMONAPI_EXPORT void init();
+
+ template<template<typename ...> class _ProxyClass, typename ... _AttributeExtensions>
+ COMMONAPI_EXPORT std::shared_ptr<
+ _ProxyClass<_AttributeExtensions...>
+ >
+ buildProxy(const std::string &_domain,
+ const std::string &_instance,
+ const ConnectionId_t &_connectionId = DEFAULT_CONNECTION_ID) {
+ std::shared_ptr<Proxy> proxy
+ = createProxy(_domain,
+ _ProxyClass<_AttributeExtensions...>::getInterface(),
+ _instance,
+ _connectionId);
+
+ if (proxy) {
+ return std::make_shared<_ProxyClass<_AttributeExtensions...>>(proxy);
+ }
+ else {
+ return nullptr;
+ }
+ }
+
+ template<template<typename ...> class _ProxyClass, typename ... _AttributeExtensions>
+ COMMONAPI_EXPORT std::shared_ptr<
+ _ProxyClass<_AttributeExtensions...>
+ >
+ buildProxy(const std::string &_domain,
+ const std::string &_instance,
+ std::shared_ptr<MainLoopContext> _context) {
+ std::shared_ptr<Proxy> proxy
+ = createProxy(_domain,
+ _ProxyClass<_AttributeExtensions...>::getInterface(),
+ _instance,
+ _context);
+ if (proxy) {
+ return std::make_shared<_ProxyClass<_AttributeExtensions...>>(proxy);
+ }
+ else {
+ return nullptr;
+ }
+ }
+
+ template <template<typename ...> class _ProxyClass, template<typename> class _AttributeExtension>
+ COMMONAPI_EXPORT std::shared_ptr<typename DefaultAttributeProxyHelper<_ProxyClass, _AttributeExtension>::class_t>
+ buildProxyWithDefaultAttributeExtension(const std::string &_domain,
+ const std::string &_instance,
+ const ConnectionId_t &_connectionId = DEFAULT_CONNECTION_ID) {
+ std::shared_ptr<Proxy> proxy
+ = createProxy(_domain,
+ DefaultAttributeProxyHelper<_ProxyClass, _AttributeExtension>::class_t::getInterface(),
+ _instance,
+ _connectionId);
+ if (proxy) {
+ return std::make_shared<typename DefaultAttributeProxyHelper<_ProxyClass, _AttributeExtension>::class_t>(proxy);
+ }
+ return nullptr;
+ }
+
+ template <template<typename ...> class _ProxyClass, template<typename> class _AttributeExtension>
+ COMMONAPI_EXPORT std::shared_ptr<typename DefaultAttributeProxyHelper<_ProxyClass, _AttributeExtension>::class_t>
+ buildProxyWithDefaultAttributeExtension(const std::string &_domain,
+ const std::string &_instance,
+ std::shared_ptr<MainLoopContext> _context) {
+ std::shared_ptr<Proxy> proxy
+ = createProxy(_domain,
+ DefaultAttributeProxyHelper<_ProxyClass, _AttributeExtension>::class_t::getInterface(),
+ _instance,
+ _context);
+ if (proxy) {
+ return std::make_shared<typename DefaultAttributeProxyHelper<_ProxyClass, _AttributeExtension>::class_t>(proxy);
+ }
+ return nullptr;
+ }
+
+ template<typename _Stub>
+ COMMONAPI_EXPORT bool registerService(const std::string &_domain,
+ const std::string &_instance,
+ std::shared_ptr<_Stub> _service,
+ const ConnectionId_t &_connectionId = DEFAULT_CONNECTION_ID) {
+ return registerStub(_domain, _Stub::StubInterface::getInterface(), _instance, _service, _connectionId);
+ }
+
+ template<typename _Stub>
+ COMMONAPI_EXPORT bool registerService(const std::string &_domain,
+ const std::string &_instance,
+ std::shared_ptr<_Stub> _service,
+ std::shared_ptr<MainLoopContext> _context) {
+ return registerStub(_domain, _Stub::StubInterface::getInterface(), _instance, _service, _context);
+ }
+
+ COMMONAPI_EXPORT bool unregisterService(const std::string &_domain,
+ const std::string &_interface,
+ const std::string &_instance) {
+ return unregisterStub(_domain, _interface, _instance);
+ }
+
+ COMMONAPI_EXPORT bool registerFactory(const std::string &_ipc, std::shared_ptr<Factory> _factory);
+ COMMONAPI_EXPORT bool unregisterFactory(const std::string &_ipc);
+
+ inline const std::string &getDefaultBinding() const { return defaultBinding_; };
+
+private:
+ COMMONAPI_EXPORT bool readConfiguration();
+ COMMONAPI_EXPORT bool splitAddress(const std::string &, std::string &, std::string &, std::string &);
+
+ COMMONAPI_EXPORT std::shared_ptr<Proxy> createProxy(const std::string &, const std::string &, const std::string &,
+ const ConnectionId_t &);
+ COMMONAPI_EXPORT std::shared_ptr<Proxy> createProxy(const std::string &, const std::string &, const std::string &,
+ std::shared_ptr<MainLoopContext>);
+
+ COMMONAPI_EXPORT std::shared_ptr<Proxy> createProxyHelper(const std::string &, const std::string &, const std::string &,
+ const ConnectionId_t &);
+ COMMONAPI_EXPORT std::shared_ptr<Proxy> createProxyHelper(const std::string &, const std::string &, const std::string &,
+ std::shared_ptr<MainLoopContext>);
+
+
+ COMMONAPI_EXPORT bool registerStub(const std::string &, const std::string &, const std::string &,
+ std::shared_ptr<StubBase>, const ConnectionId_t &);
+ COMMONAPI_EXPORT bool registerStub(const std::string &, const std::string &, const std::string &,
+ std::shared_ptr<StubBase>, std::shared_ptr<MainLoopContext>);
+ COMMONAPI_EXPORT bool registerStubHelper(const std::string &, const std::string &, const std::string &,
+ std::shared_ptr<StubBase>, const ConnectionId_t &);
+ COMMONAPI_EXPORT bool registerStubHelper(const std::string &, const std::string &, const std::string &,
+ std::shared_ptr<StubBase>, std::shared_ptr<MainLoopContext>);
+
+ COMMONAPI_EXPORT bool unregisterStub(const std::string &, const std::string &, const std::string &);
+
+ COMMONAPI_EXPORT std::string getLibrary(const std::string &, const std::string &, const std::string &, bool);
+ COMMONAPI_EXPORT bool loadLibrary(const std::string &);
+
+private:
+ std::string defaultBinding_;
+ std::string defaultFolder_;
+ std::string defaultConfig_;
+
+ std::map<std::string, std::shared_ptr<Factory>> factories_;
+ std::shared_ptr<Factory> defaultFactory_;
+ std::map<std::string, std::map<bool, std::string>> libraries_;
+ std::set<std::string> loadedLibraries_; // Library name
+
+ std::mutex mutex_;
+ std::mutex factoriesMutex_;
+ std::mutex loadMutex_;
+
+ static std::map<std::string, std::string> properties_;
+ static std::shared_ptr<Runtime> theRuntime__;
+
+friend class ProxyManager;
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_RUNTIME_HPP_
diff --git a/include/CommonAPI/SelectiveEvent.hpp b/include/CommonAPI/SelectiveEvent.hpp
new file mode 100644
index 0000000..ffae1bf
--- /dev/null
+++ b/include/CommonAPI/SelectiveEvent.hpp
@@ -0,0 +1,28 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_SELECTIVEEVENT_HPP_
+#define COMMONAPI_SELECTIVEEVENT_HPP_
+
+#include <CommonAPI/Event.hpp>
+
+namespace CommonAPI {
+
+template<typename ... _Arguments>
+class SelectiveEvent: public Event<_Arguments...> {
+public:
+ typedef typename Event<_Arguments...>::Listener Listener;
+ typedef typename Event<_Arguments...>::Subscription Subscription;
+
+ virtual ~SelectiveEvent() {}
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_SELECTIVEEVENT_HPP_
diff --git a/include/CommonAPI/SerializableArguments.hpp b/include/CommonAPI/SerializableArguments.hpp
new file mode 100644
index 0000000..1f2af63
--- /dev/null
+++ b/include/CommonAPI/SerializableArguments.hpp
@@ -0,0 +1,62 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_SERIALIZABLEARGUMENTS_HPP_
+#define COMMONAPI_SERIALIZABLEARGUMENTS_HPP_
+
+#include <CommonAPI/InputStream.hpp>
+#include <CommonAPI/OutputStream.hpp>
+
+namespace CommonAPI {
+
+template<class _In, class _Out, typename... _Arguments>
+struct SerializableArguments;
+
+template<class _In, class _Out>
+struct SerializableArguments<_In, _Out> {
+ static bool serialize(OutputStream<_Out> &_output) {
+ return true;
+ }
+
+ static bool deserialize(InputStream<_In> &_input) {
+ return true;
+ }
+};
+
+template<class _In, class _Out, typename _ArgumentType>
+struct SerializableArguments<_In, _Out, _ArgumentType> {
+ static bool serialize(OutputStream<_Out> &_output, const _ArgumentType &_argument) {
+ _output << _argument;
+ return !_output.hasError();
+ }
+
+ static bool deserialize(InputStream<_In> &_input, _ArgumentType &_argument) {
+ _input >> _argument;
+ return !_input.hasError();
+ }
+};
+
+template <class _In, class _Out, typename _ArgumentType, typename ... _Rest>
+struct SerializableArguments<_In, _Out, _ArgumentType, _Rest...> {
+ static bool serialize(OutputStream<_Out> &_output, const _ArgumentType &_argument, const _Rest&... _rest) {
+ _output << _argument;
+ return !_output.hasError() ?
+ SerializableArguments<_In, _Out, _Rest...>::serialize(_output, _rest...) : false;
+ }
+
+ static bool deserialize(InputStream<_In> &_input, _ArgumentType &_argument, _Rest&... _rest) {
+ _input >> _argument;
+ return !_input.hasError() ?
+ SerializableArguments<_In, _Out, _Rest...>::deserialize(_input, _rest...) : false;
+ }
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_SERIALIZABLE_ARGUMENTS_HPP_
diff --git a/include/CommonAPI/Struct.hpp b/include/CommonAPI/Struct.hpp
new file mode 100644
index 0000000..c98b09e
--- /dev/null
+++ b/include/CommonAPI/Struct.hpp
@@ -0,0 +1,174 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_STRUCT_HPP_
+#define COMMONAPI_STRUCT_HPP_
+
+#include <iostream>
+#include <tuple>
+
+namespace CommonAPI {
+
+typedef uint32_t Serial;
+
+template<class _Derived>
+class InputStream;
+
+template<class _Derived>
+class OutputStream;
+
+template<class _Derived>
+class TypeOutputStream;
+
+template<int, class, class, class>
+struct StructReader;
+
+template<
+ int _Index, class _Input,
+ template<class...> class _V, class... _Values,
+ template<class...> class _D, class... _Depls>
+struct StructReader<_Index, _Input, _V<_Values...>, _D<_Depls...>> {
+ void operator()(InputStream<_Input> &_input,
+ _V<_Values...> &_values,
+ const _D<_Depls...> *_depls) {
+ StructReader<_Index-1, _Input, _V<_Values...>, _D<_Depls...>>{}(_input, _values, _depls);
+ _input.template readValue<>(std::get<_Index>(_values.values_),
+ (_depls ? std::get<_Index>(_depls->values_) : nullptr));
+ }
+};
+
+template<
+ int _Index, class _Input,
+ template<class...> class _V, class... _Values,
+ class _D>
+struct StructReader<_Index, _Input, _V<_Values...>, _D> {
+ void operator()(InputStream<_Input> &_input,
+ _V<_Values...> &_values,
+ const _D *_depls) {
+ StructReader<_Index-1, _Input, _V<_Values...>, _D>{}(_input, _values, _depls);
+ _input.template readValue<_D>(std::get<_Index>(_values.values_));
+ }
+};
+
+template<class _Input,
+ template<class...> class _V, class... _Values,
+ template<class...> class _D, class... _Depls>
+struct StructReader<0, _Input, _V<_Values...>, _D<_Depls...>> {
+ void operator()(InputStream<_Input> &_input,
+ _V<_Values...> &_values,
+ const _D<_Depls...> *_depls) {
+ _input.template readValue<>(std::get<0>(_values.values_),
+ (_depls ? std::get<0>(_depls->values_) : nullptr));
+ }
+};
+
+template<class _Input,
+ template<class...> class _V, class... _Values,
+ class _D>
+struct StructReader<0, _Input, _V<_Values...>, _D> {
+ void operator()(InputStream<_Input> &_input,
+ _V<_Values...> &_values,
+ const _D *_depls) {
+ _input.template readValue<_D>(std::get<0>(_values.values_));
+ }
+};
+
+
+template< int, class, class, class >
+struct StructWriter;
+
+template<
+ int _Index, class _Output,
+ template<class ...> class _V, class... _Values,
+ template <class...> class _D, class... _Depls>
+struct StructWriter<_Index, _Output, _V<_Values...>, _D<_Depls...>> {
+ void operator()(OutputStream<_Output> &_output,
+ const _V<_Values...> &_values,
+ const _D<_Depls...> *_depls) {
+ StructWriter<_Index-1, _Output, _V<_Values...>, _D<_Depls...>>{}(_output, _values, _depls);
+ _output.template writeValue<>(std::get<_Index>(_values.values_),
+ (_depls ? std::get<_Index>(_depls->values_) : nullptr));
+ }
+};
+
+template<
+ int _Index, class _Output,
+ template<class...> class _V, class... _Values,
+ class _D>
+struct StructWriter<_Index, _Output, _V<_Values...>, _D> {
+ void operator()(OutputStream<_Output> &_output,
+ const _V<_Values...> &_values,
+ const _D *_depls) {
+ StructWriter<_Index-1, _Output, _V<_Values...>, _D>{}(_output, _values, _depls);
+ _output.template writeValue<_D>(std::get<_Index>(_values.values_));
+ }
+};
+
+template<class _Output,
+ template<class...> class _V, class... _Values,
+ template<class...> class _D, class... _Depls>
+struct StructWriter<0, _Output, _V<_Values...>, _D<_Depls...>> {
+ void operator()(OutputStream<_Output> &_output,
+ const _V<_Values...> &_values,
+ const _D<_Depls...> *_depls) {
+ _output.template writeValue<>(std::get<0>(_values.values_),
+ (_depls ? std::get<0>(_depls->values_) : nullptr));
+ }
+};
+
+template<class _Output,
+ template<class...> class _V, class... _Values,
+ class _D>
+struct StructWriter<0, _Output, _V<_Values...>, _D> {
+ void operator()(OutputStream<_Output> &_output,
+ const _V<_Values...> &_values,
+ const _D *_depls) {
+ _output.template writeValue<_D>(std::get<0>(_values.values_));
+ }
+};
+
+template<int, class, class>
+struct StructTypeWriter;
+
+template<int _Index, class _TypeOutput,
+ template<class...> class _V, class... _Values>
+struct StructTypeWriter<_Index, _TypeOutput, _V<_Values...>> {
+ void operator()(TypeOutputStream<_TypeOutput> &_output,
+ const _V<_Values...> &_values) {
+ StructTypeWriter<_Index-1, _TypeOutput, _V<_Values...>>{}(_output, _values);
+ _output.template writeType(std::get<_Index>(_values.values_));
+ }
+};
+
+template<class _TypeOutput,
+ template<class...> class _V, class... _Values>
+struct StructTypeWriter<0, _TypeOutput, _V<_Values...>> {
+ void operator()(TypeOutputStream<_TypeOutput> &_output,
+ const _V<_Values...> &_values) {
+ _output.template writeType(std::get<0>(_values.values_));
+ }
+};
+
+// Structures are mapped to a (generated) struct which inherits from CommonAPI::Struct.
+// CommonAPI::Struct holds the structured data in a tuple. The generated class provides
+// getter- and setter-methods for the structure members.
+template<typename... _Types>
+struct Struct {
+ std::tuple<_Types...> values_;
+};
+
+// Polymorphic structs are mapped to an interface that is derived from the base class
+// PolymorphicStruct and contain their parameter in a Struct.
+struct PolymorphicStruct {
+ virtual const Serial getSerial() const = 0;
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_STRUCT_HPP_
diff --git a/include/CommonAPI/Stub.hpp b/include/CommonAPI/Stub.hpp
new file mode 100644
index 0000000..75ee4e0
--- /dev/null
+++ b/include/CommonAPI/Stub.hpp
@@ -0,0 +1,60 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_STUB_HPP_
+#define COMMONAPI_STUB_HPP_
+
+#include <memory>
+#include <string>
+#include <type_traits>
+
+#include <CommonAPI/Address.hpp>
+#include <CommonAPI/Types.hpp>
+
+namespace CommonAPI {
+
+class StubAdapter {
+public:
+ virtual ~StubAdapter() {}
+ inline const Address &getAddress() const { return address_; }
+
+protected:
+ Address address_;
+};
+
+class StubBase {
+public:
+ virtual ~StubBase() {}
+};
+
+template<typename _StubAdapter, typename _StubRemoteEventHandler>
+class Stub: public virtual StubBase {
+ static_assert(std::is_base_of<StubAdapter, _StubAdapter>::value, "Invalid StubAdapter Class!");
+public:
+ typedef _StubAdapter StubAdapterType;
+ typedef _StubRemoteEventHandler RemoteEventHandlerType;
+
+ virtual ~Stub() {}
+
+ virtual _StubRemoteEventHandler* initStubAdapter(const std::shared_ptr<_StubAdapter> &_stubAdapter) = 0;
+
+ inline const std::shared_ptr<_StubAdapter> getStubAdapter() const { return stubAdapter_; }
+
+protected:
+ std::shared_ptr<_StubAdapter> stubAdapter_;
+};
+
+enum SelectiveBroadcastSubscriptionEvent {
+ SUBSCRIBED,
+ UNSUBSCRIBED
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_STUB_HPP_
diff --git a/include/CommonAPI/TypeOutputStream.hpp b/include/CommonAPI/TypeOutputStream.hpp
new file mode 100644
index 0000000..ec44864
--- /dev/null
+++ b/include/CommonAPI/TypeOutputStream.hpp
@@ -0,0 +1,197 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_TYPEOUTPUTSTREAM_HPP_
+#define COMMONAPI_TYPEOUTPUTSTREAM_HPP_
+
+#include <unordered_map>
+
+#include <CommonAPI/Struct.hpp>
+#include <CommonAPI/Variant.hpp>
+#include <CommonAPI/Types.hpp>
+
+namespace CommonAPI {
+
+template<class _Derived>
+class TypeOutputStream {
+public:
+ inline TypeOutputStream &writeType(const bool &_value) {
+ return get()->writeType(_value);
+ }
+
+ inline TypeOutputStream &writeType(const int8_t &_value) {
+ return get()->writeType(_value);
+ }
+
+ inline TypeOutputStream &writeType(const int16_t &_value) {
+ return get()->writeType(_value);
+ }
+
+ inline TypeOutputStream &writeType(const int32_t &_value) {
+ return get()->writeType(_value);
+ }
+
+ inline TypeOutputStream &writeType(const int64_t &_value) {
+ return get()->writeType(_value);
+ }
+
+ inline TypeOutputStream &writeType(const uint8_t &_value) {
+ return get()->writeType(_value);
+ }
+
+ inline TypeOutputStream &writeType(const uint16_t &_value) {
+ return get()->writeType(_value);
+ }
+
+ inline TypeOutputStream &writeType(const uint32_t &_value) {
+ return get()->writeType(_value);
+ }
+
+ inline TypeOutputStream &writeType(const uint64_t &_value) {
+ return get()->writeType(_value);
+ }
+
+ inline TypeOutputStream &writeType(const float &_value) {
+ return get()->writeType(_value);
+ }
+
+ inline TypeOutputStream &writeType(const double &_value) {
+ return get()->writeType(_value);
+ }
+
+ inline TypeOutputStream &writeType(const std::string &_value) {
+ return get()->writeType(_value);
+ }
+
+ template<typename _Type>
+ TypeOutputStream &writeType(const Enumeration<_Type> &_value) {
+ _Type tmpValue;
+ return get()->writeType(tmpValue);
+ }
+
+ template<typename... _Types>
+ TypeOutputStream &writeType(const Struct<_Types...> &_value) {
+ return get()->writeType(_value);
+ }
+
+ template<typename... _Types>
+ TypeOutputStream &writeType(const Variant<_Types...> &_value) {
+ return get()->writeType(_value);
+ }
+
+ template<typename _ElementType>
+ TypeOutputStream &writeType(const std::vector<_ElementType> &_value) {
+ return get()->writeType(_value);
+ }
+
+ template<typename _KeyType, typename _ValueType, typename _HasherType>
+ TypeOutputStream &writeType(const std::unordered_map<_KeyType, _ValueType, _HasherType> &_value) {
+ return get()->writeType(_value);
+ }
+
+private:
+ inline _Derived *get() {
+ return static_cast<_Derived *>(this);
+ }
+};
+
+template<class _Derived>
+inline TypeOutputStream<_Derived> &operator<<(TypeOutputStream<_Derived> &_output, const bool &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived>
+inline TypeOutputStream<_Derived>& operator<<(TypeOutputStream<_Derived> &_output, const int8_t &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived>
+inline TypeOutputStream<_Derived>& operator<<(TypeOutputStream<_Derived> &_output, const int16_t &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived>
+inline TypeOutputStream<_Derived>& operator<<(TypeOutputStream<_Derived> &_output, const int32_t &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived>
+inline TypeOutputStream<_Derived>& operator<<(TypeOutputStream<_Derived> &_output, const int64_t &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived>
+inline TypeOutputStream<_Derived>& operator<<(TypeOutputStream<_Derived> &_output, const uint8_t &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived>
+inline TypeOutputStream<_Derived>& operator<<(TypeOutputStream<_Derived> &_output, const uint16_t &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived>
+inline TypeOutputStream<_Derived>& operator<<(TypeOutputStream<_Derived> &_output, const uint32_t &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived>
+inline TypeOutputStream<_Derived>& operator<<(TypeOutputStream<_Derived> &_output, const uint64_t &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived>
+inline TypeOutputStream<_Derived>& operator<<(TypeOutputStream<_Derived> &_output, const float &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived>
+inline TypeOutputStream<_Derived>& operator<<(TypeOutputStream<_Derived> &_output, const double &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived>
+inline TypeOutputStream<_Derived>& operator<<(TypeOutputStream<_Derived> &_output, const std::string &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived, typename _Type, typename _TypeDepl>
+inline TypeOutputStream<_Derived> &operator<<(TypeOutputStream<_Derived> &_output, const Deployable<_Type, _TypeDepl> &_value) {
+ return _output.writeType(_value.getValue());
+}
+
+template<class _Derived>
+inline TypeOutputStream<_Derived>& operator<<(TypeOutputStream<_Derived> &_output, const Version &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived, typename... _Types>
+TypeOutputStream<_Derived> &operator<<(TypeOutputStream<_Derived> &_output, const Struct<_Types...> &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived, typename... _Types>
+TypeOutputStream<_Derived> &operator<<(TypeOutputStream<_Derived> &_output, const Variant<_Types...> &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived, typename _ElementType>
+TypeOutputStream<_Derived> &operator<<(TypeOutputStream<_Derived> &_output, const std::vector<_ElementType> &_value) {
+ return _output.writeType(_value);
+}
+
+template<class _Derived, typename _KeyType, typename _ValueType, typename _HasherType>
+TypeOutputStream<_Derived> &operator<<(TypeOutputStream<_Derived> &_output,
+ const std::unordered_map<_KeyType, _ValueType, _HasherType> &_value) {
+ return _output.writeType(_value);
+}
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_TYPEOUTPUTSTREAM_HPP_
diff --git a/include/CommonAPI/Types.hpp b/include/CommonAPI/Types.hpp
new file mode 100644
index 0000000..de1d85a
--- /dev/null
+++ b/include/CommonAPI/Types.hpp
@@ -0,0 +1,116 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_TYPES_HPP_
+#define COMMONAPI_TYPES_HPP_
+
+#include <cstdint>
+#include <functional>
+#include <unordered_set>
+#include <memory>
+#include <tuple>
+
+#include <CommonAPI/ByteBuffer.hpp>
+#include <CommonAPI/ContainerUtils.hpp>
+#include <CommonAPI/Event.hpp>
+#include <CommonAPI/Export.hpp>
+#include <CommonAPI/Version.hpp>
+
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+# define COMMONAPI_DEPRECATED __attribute__ ((__deprecated__))
+#elif defined(_MSC_VER) && (_MSC_VER >= 1300)
+# define COMMONAPI_DEPRECATED __declspec(deprecated)
+#else
+# define COMMONAPI_DEPRECATED
+#endif
+
+
+#ifdef WIN32
+#define CCALL __cdecl
+#pragma section(".CRT$XCU",read)
+#define INITIALIZER(f) \
+ static void __cdecl f(void); \
+ __declspec(allocate(".CRT$XCU")) void(__cdecl*f##_)(void) = f; \
+ static void __cdecl f(void)
+#else
+#define CCALL
+#define INITIALIZER(f) \
+ static void f(void) __attribute__((constructor)); \
+ static void f(void)
+#endif
+
+#ifdef WIN32
+#define usleep(micSec) \
+ std::this_thread::sleep_for(std::chrono::microseconds(micSec))
+#endif
+
+namespace CommonAPI {
+
+enum class AvailabilityStatus {
+ UNKNOWN,
+ AVAILABLE,
+ NOT_AVAILABLE
+};
+
+enum class CallStatus {
+ SUCCESS,
+ OUT_OF_MEMORY,
+ NOT_AVAILABLE,
+ CONNECTION_FAILED,
+ REMOTE_ERROR,
+ UNKNOWN
+};
+
+typedef uint32_t CallId_t;
+typedef std::string ConnectionId_t;
+typedef int Timeout_t; // in ms, -1 means "forever"
+typedef uint32_t Sender_t;
+
+/**
+ * \brief Identifies a client sending a call to a stub.
+ *
+ * The ClientId is used to identify the caller within a stub.
+ * The ClientId is supposed to be added by the middleware and can be compared using the == operator.
+ */
+class ClientId {
+public:
+ virtual ~ClientId() { }
+ virtual bool operator==(ClientId& clientIdToCompare) = 0;
+ virtual std::size_t hashCode() = 0;
+};
+
+template <typename ... Args>
+struct SelectiveBroadcastFunctorHelper {
+ typedef std::function<void(Args...)> SelectiveBroadcastFunctor;
+};
+
+typedef std::unordered_set<
+ std::shared_ptr<CommonAPI::ClientId>,
+ SharedPointerClientIdContentHash,
+ SharedPointerClientIdContentEqual
+> ClientIdList;
+
+template<typename _EnumType>
+class EnumHasher {
+public:
+ size_t operator()(const _EnumType& testEnum) const {
+ return static_cast<int32_t>(testEnum);
+ }
+};
+
+// Type identifier for polymorphic structs
+typedef uint32_t Serial;
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_TYPES_HPP_
+
+#if defined(COMMONAPI_TYPES_LOCAL_INCLUDE)
+#include COMMONAPI_TYPES_LOCAL_INCLUDE
+#endif
diff --git a/include/CommonAPI/Utils.hpp b/include/CommonAPI/Utils.hpp
new file mode 100644
index 0000000..94891d5
--- /dev/null
+++ b/include/CommonAPI/Utils.hpp
@@ -0,0 +1,22 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef COMMONAPI_UTILS_HPP_
+#define COMMONAPI_UTILS_HPP_
+
+#include <string>
+#include <vector>
+
+#include <CommonAPI/Export.hpp>
+
+namespace CommonAPI {
+
+std::vector<std::string> COMMONAPI_EXPORT split(const std::string& s, char delim);
+void COMMONAPI_EXPORT trim(std::string &_s);
+
+
+} //namespace CommonAPI
+
+#endif /* COMMONAPI_UTILS_HPP_ */
diff --git a/include/CommonAPI/Variant.hpp b/include/CommonAPI/Variant.hpp
new file mode 100644
index 0000000..d7b1088
--- /dev/null
+++ b/include/CommonAPI/Variant.hpp
@@ -0,0 +1,746 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <cassert>
+#include <cstdint>
+#include <iostream>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <type_traits>
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#include <CommonAPI/Deployable.hpp>
+#include <CommonAPI/Deployment.hpp>
+
+#ifndef COMMONAPI_VARIANT_HPP_
+#define COMMONAPI_VARIANT_HPP_
+
+namespace CommonAPI {
+
+template<class _Derived>
+class InputStream;
+
+template<class _Derived>
+class OutputStream;
+
+template<typename... _Types>
+struct MaxSize;
+
+template<>
+struct MaxSize<> {
+ static const unsigned int value = 0;
+};
+
+template<typename _Type, typename... _Types>
+struct MaxSize<_Type, _Types...> {
+ static const unsigned int current_type_size = sizeof(_Type);
+ static const unsigned int next_type_size = MaxSize<_Types...>::value;
+ static const unsigned int value =
+ current_type_size > next_type_size ?
+ current_type_size : next_type_size;
+};
+
+template<typename _SearchType, typename... _RestTypes>
+struct VariantTypeSelector;
+
+template<typename _SearchType, typename... _RestTypes>
+struct VariantTypeSelector<_SearchType, _SearchType, _RestTypes...> {
+ typedef _SearchType type;
+};
+
+/**
+ * \brief A templated generic variant class which provides type safe access and operators
+ *
+ * A templated generic variant class which provides type safe access and operators
+ */
+template<typename... _Types>
+class Variant {
+private:
+ typedef std::tuple_size<std::tuple<_Types...>> TypesTupleSize;
+
+public:
+
+ static const unsigned int maxSize = MaxSize<_Types...>::value;
+
+ /**
+ * \brief Construct an empty variant
+ *
+ * Construct an empty variant
+ */
+ Variant();
+
+
+ /**
+ * \brief Copy constructor. Must have identical templates.
+ *
+ * Copy constructor. Must have identical templates.
+ *
+ * @param _source Variant to copy
+ */
+ Variant(const Variant &_source);
+
+ /**
+ * \brief Copy constructor. Must have identical templates.
+ *
+ * Copy constructor. Must have identical templates.
+ *
+ * @param _source Variant to copy
+ */
+ Variant(Variant &&_source);
+
+ ~Variant();
+
+ /**
+ * \brief Assignment of another variant. Must have identical templates.
+ *
+ * Assignment of another variant. Must have identical templates.
+ *
+ * @param _source Variant to assign
+ */
+ Variant &operator=(const Variant &_source);
+ /**
+ * \brief Assignment of another variant. Must have identical templates.
+ *
+ * Assignment of another variant. Must have identical templates.
+ *
+ * @param _source Variant to assign
+ */
+ Variant &operator=(Variant &&_source);
+
+ /**
+ * \brief Assignment of a contained type. Must be one of the valid templated types.
+ *
+ * Assignment of a contained type. Must be one of the valid templated types.
+ *
+ * @param _value Value to assign
+ */
+ template<typename _Type>
+ typename std::enable_if<!std::is_same<_Type, Variant<_Types...>>::value, Variant<_Types...>&>::type
+ operator=(const _Type &_value);
+
+ /**
+ * \brief Equality of another variant. Must have identical template list and content.
+ *
+ * Equality of another variant. Must have identical template list and content.
+ *
+ * @param _other Variant to compare
+ */
+ bool operator==(const Variant<_Types...> &_other) const;
+
+ /**
+ * \brief Not-Equality of another variant. Must have identical template list and content.
+ *
+ * Not-Equality of another variant. Must have identical template list and content.
+ *
+ * @param _other Variant to compare
+ */
+ bool operator!=(const Variant<_Types...> &_other) const;
+
+ /**
+ * \brief Testif the contained type is the same as the template on this method.
+ *
+ * Testif the contained type is the same as the template on this method.
+ *
+ * @return Is same type
+ */
+ template<typename _Type>
+ const bool isType() const;
+
+ /**
+ * \brief Construct variant with content type set to value.
+ *
+ * Construct variant with content type set to value.
+ *
+ * @param _value Value to place
+ */
+ template<typename _Type>
+ Variant(const _Type &_value,
+ typename std::enable_if<!std::is_const<_Type>::value>::type* = 0,
+ typename std::enable_if<!std::is_reference<_Type>::value>::type* = 0,
+ typename std::enable_if<!std::is_same<_Type, Variant>::value>::type* = 0);
+
+ /**
+ * \brief Construct variant with content type set to value.
+ *
+ * Construct variant with content type set to value.
+ *
+ * @param _value Value to place
+ */
+ template<typename _Type>
+ Variant(_Type &&_value,
+ typename std::enable_if<!std::is_const<_Type>::value>::type* = 0,
+ typename std::enable_if<!std::is_reference<_Type>::value>::type* = 0,
+ typename std::enable_if<!std::is_same<_Type, Variant>::value>::type* = 0);
+
+ /**
+ * \brief Get value of variant, template to content type. Throws exception if type is not contained.
+ *
+ * Get value of variant, template to content type. Throws exception if type is not contained.
+ */
+ template<typename _Type>
+ const _Type &get() const;
+
+ /**
+ * \brief Get index in template list of type actually contained, starting at 1 at the end of the template list
+ *
+ * Get index in template list of type actually contained, starting at 1 at the end of the template list
+ *
+ * @return Index of contained type
+ */
+ uint8_t getValueType() const {
+ return valueType_;
+ }
+
+private:
+ template<typename _Type>
+ void set(const _Type &_value, const bool clear);
+
+ template<typename _Type>
+ void set(_Type &&_value, const bool clear);
+
+ template<typename _FriendType>
+ friend struct TypeWriter;
+ template<typename ... _FriendTypes>
+ friend struct AssignmentVisitor;
+ template<typename _FriendType>
+ friend struct TypeEqualsVisitor;
+ template<typename ... _FriendTypes>
+ friend struct PartialEqualsVisitor;
+ template<class _Derived, typename ... _FriendTypes>
+ friend struct InputStreamReadVisitor;
+ template<class Variant, typename ... _FTypes>
+ friend struct ApplyVoidIndexVisitor;
+
+public:
+ inline bool hasValue() const {
+ return (valueType_ < TypesTupleSize::value);
+ }
+ typename std::aligned_storage<maxSize>::type valueStorage_;
+
+ uint8_t valueType_;
+};
+
+template<class _Variant, typename... _Types>
+struct ApplyVoidIndexVisitor;
+
+template<class _Variant>
+struct ApplyVoidIndexVisitor<_Variant> {
+ static const uint8_t index = 0;
+
+ static
+ void visit(_Variant &, uint8_t &) {
+ assert(false);
+ }
+};
+
+template<class _Variant, typename _Type, typename... _Types>
+struct ApplyVoidIndexVisitor<_Variant, _Type, _Types...> {
+ static const uint8_t index
+ = ApplyVoidIndexVisitor<_Variant, _Types...>::index + 1;
+
+ static void visit(_Variant &_variant, uint8_t &_index) {
+ if (index == _index) {
+ new (&_variant.valueStorage_) _Type();
+ _variant.valueType_ = index;
+ } else {
+ ApplyVoidIndexVisitor<
+ _Variant, _Types...
+ >::visit(_variant, _index);
+ }
+ }
+};
+
+template<class _Visitor, class _Variant, typename... _Types>
+struct ApplyVoidVisitor;
+
+template<class _Visitor, class _Variant>
+struct ApplyVoidVisitor<_Visitor, _Variant> {
+ static const uint8_t index = 0;
+
+ static
+ void visit(_Visitor &, _Variant &) {
+ assert(false);
+ }
+
+ static
+ void visit(_Visitor &, const _Variant &) {
+ assert(false);
+ }
+};
+
+template<class _Visitor, class _Variant, typename _Type, typename ... _Types>
+struct ApplyVoidVisitor<_Visitor, _Variant, _Type, _Types...> {
+ static const uint8_t index
+ = ApplyVoidVisitor<_Visitor, _Variant, _Types...>::index + 1;
+
+ static void visit(_Visitor &_visitor, _Variant &_variant) {
+ if (_variant.getValueType() == index) {
+ _visitor(_variant.template get<_Type>());
+ } else {
+ ApplyVoidVisitor<
+ _Visitor, _Variant, _Types...
+ >::visit(_visitor, _variant);
+ }
+ }
+
+ static void visit(_Visitor &_visitor, const _Variant &_variant) {
+ if (_variant.getValueType() == index) {
+ _visitor(_variant.template get<_Type>());
+ } else {
+ ApplyVoidVisitor<
+ _Visitor, _Variant, _Types...
+ >::visit(_visitor, _variant);
+ }
+ }
+};
+
+template<class _Visitor, class _Variant, typename ... _Types>
+struct ApplyBoolVisitor;
+
+template<class _Visitor, class _Variant>
+struct ApplyBoolVisitor<_Visitor, _Variant> {
+ static const uint8_t index = 0;
+
+ static bool visit(_Visitor &, _Variant &) {
+ assert(false);
+ return false;
+ }
+};
+
+template<class _Visitor, class _Variant, typename _Type, typename ... _Types>
+struct ApplyBoolVisitor<_Visitor, _Variant, _Type, _Types...> {
+ static const uint8_t index
+ = ApplyBoolVisitor<_Visitor, _Variant, _Types...>::index + 1;
+
+ static bool visit(_Visitor &_visitor, _Variant &_variant) {
+ if (_variant.getValueType() == index) {
+ return _visitor(_variant.template get<_Type>());
+ } else {
+ return ApplyBoolVisitor<
+ _Visitor, _Variant, _Types...
+ >::visit(_visitor, _variant);
+ }
+ }
+};
+
+template<class _Visitor, class _Variant, class _Deployment, typename ... _Types>
+struct ApplyStreamVisitor;
+
+template<class _Visitor, class _Variant, class _Deployment>
+struct ApplyStreamVisitor<_Visitor, _Variant, _Deployment> {
+ static const uint8_t index = 0;
+
+ static
+ void visit(_Visitor &, _Variant &, const _Deployment *) {
+ assert(false);
+ }
+
+ static
+ void visit(_Visitor &, const _Variant &, const _Deployment *) {
+ assert(false);
+ }
+};
+
+template<class _Visitor, class _Variant, class _Deployment, typename _Type, typename ... _Types>
+struct ApplyStreamVisitor<_Visitor, _Variant, _Deployment, _Type, _Types...> {
+ static const uint8_t index
+ = ApplyStreamVisitor<_Visitor, _Variant, _Deployment, _Types...>::index + 1;
+
+ static void visit(_Visitor &_visitor, _Variant &_variant, const _Deployment *_depl) {
+ if (_variant.getValueType() == index) {
+ _visitor(_variant.template get<_Type>(),
+ (_depl ? std::get<std::tuple_size<decltype(_depl->values_)>::value-index>(_depl->values_)
+ : nullptr));
+ } else {
+ ApplyStreamVisitor<
+ _Visitor, _Variant, _Deployment, _Types...
+ >::visit(_visitor, _variant, _depl);
+ }
+ }
+
+ static void visit(_Visitor &_visitor, const _Variant &_variant, const _Deployment *_depl) {
+ if (_variant.getValueType() == index) {
+ _visitor(_variant.template get<_Type>(),
+ (_depl ? std::get<std::tuple_size<decltype(_depl->values_)>::value-index>(_depl->values_)
+ : nullptr));
+ } else {
+ ApplyStreamVisitor<
+ _Visitor, _Variant, _Deployment, _Types...
+ >::visit(_visitor, _variant, _depl);
+ }
+ }
+};
+
+template<uint32_t _Size>
+struct DeleteVisitor {
+public:
+ DeleteVisitor(typename std::aligned_storage<_Size>::type &_storage)
+ : storage_(_storage) {
+ }
+
+ template<typename _Type>
+ void operator()(const _Type &) const {
+ (reinterpret_cast<const _Type *>(&storage_))->~_Type();
+ }
+
+private:
+ typename std::aligned_storage<_Size>::type &storage_;
+};
+
+template<class _Derived>
+struct OutputStreamWriteVisitor {
+public:
+ OutputStreamWriteVisitor(OutputStream<_Derived> &_output)
+ : output_(_output) {
+ }
+
+ template<typename _Type, typename _Deployment = EmptyDeployment>
+ void operator()(const _Type &_value, const _Deployment *_depl = nullptr) const {
+ Deployable<_Type, _Deployment> itsValue(_value, _depl);
+ output_ << itsValue;
+ }
+
+private:
+ OutputStream<_Derived> &output_;
+};
+
+template<class _Derived, typename ... _Types>
+struct InputStreamReadVisitor {
+public:
+ InputStreamReadVisitor(InputStream<_Derived> &_input, Variant<_Types...> &_target)
+ : input_(_input), target_(_target) {
+ }
+
+ template<typename _Type, typename _Deployment = EmptyDeployment>
+ void operator()(const _Type &_value, const _Deployment *_depl = nullptr) {
+ Deployable<_Type, _Deployment> itsValue(_depl);
+ input_ >> itsValue;
+ target_.Variant<_Types...>::template set<_Type>(std::move(itsValue.getValue()), false);
+ }
+
+private:
+ InputStream<_Derived> &input_;
+ Variant<_Types...> &target_;
+};
+
+template<class _Derived>
+struct TypeOutputStreamWriteVisitor {
+public:
+ TypeOutputStreamWriteVisitor(_Derived &_output)
+ : output_(_output) {
+ }
+
+ template<typename _Type>
+ void operator()(const _Type &_value) const {
+ output_ << _value;
+ }
+
+private:
+ _Derived &output_;
+};
+
+template<typename _Type>
+struct TypeEqualsVisitor
+{
+public:
+ TypeEqualsVisitor(const _Type &_me)
+ : me_(_me) {
+ }
+
+ bool operator()(const _Type &_other) const {
+ return (me_ == _other);
+ }
+
+ template<typename _OtherType>
+ bool operator()(const _OtherType &) const {
+ return false;
+ }
+
+private:
+ const _Type& me_;
+};
+
+template<typename ... _Types>
+struct PartialEqualsVisitor
+{
+public:
+ PartialEqualsVisitor(const Variant<_Types...> &_me)
+ : me_(_me) {
+ }
+
+ template<typename _Type>
+ bool operator()(const _Type &_other) const {
+ TypeEqualsVisitor<_Type> visitor(_other);
+ return ApplyBoolVisitor<
+ TypeEqualsVisitor<_Type>, const Variant<_Types...>, _Types...
+ >::visit(visitor, me_);
+ }
+
+private:
+ const Variant<_Types...> &me_;
+};
+
+template<typename ... _Types>
+struct AssignmentVisitor {
+public:
+ AssignmentVisitor(Variant<_Types...> &_me, const bool _clear = true)
+ : me_(_me), clear_(_clear) {
+ }
+
+ template<typename _Type>
+ void operator()(const _Type &_value) const {
+ me_.Variant<_Types...>::template set<_Type>(_value, clear_);
+ }
+
+ template<typename _Type>
+ void operator()(_Type &_value) const {
+ me_.Variant<_Types...>::template set<_Type>(_value, clear_);
+ }
+
+private:
+ Variant<_Types...> &me_;
+ const bool clear_;
+};
+
+template<typename... _Types>
+struct TypeSelector;
+
+template<typename _Type>
+struct TypeSelector<_Type> {
+};
+
+template<typename _Type, typename... _Types>
+struct TypeSelector<_Type, _Type, _Types...> {
+ typedef _Type type;
+};
+
+template<typename _Type, typename... _Types>
+struct TypeSelector<_Type, _Type &, _Types...> {
+ typedef _Type& type;
+};
+
+template<typename _Type, typename... _Types>
+struct TypeSelector<_Type &, _Type, _Types...> {
+ typedef _Type type;
+};
+
+template<typename _Type, typename... _Types>
+struct TypeSelector<_Type, const _Type &, _Types...> {
+ typedef const _Type &type;
+};
+
+template<typename _Type, typename... _Types>
+struct TypeSelector<const _Type&, _Type, _Types...> {
+ typedef _Type type;
+};
+
+template<typename _Type, typename... _Types>
+struct TypeSelector<_Type*, const _Type*, _Types...> {
+ typedef const _Type *type;
+};
+
+template<typename _Type, typename... _Types>
+struct TypeSelector<_Type &, const _Type &, _Types...> {
+ typedef const _Type &type;
+};
+
+template<typename _U, typename _Type, typename... _Types>
+struct TypeSelector<_U, _Type, _Types...> {
+ typedef typename TypeSelector<_U, _Types...>::type type;
+};
+
+template<typename... _Types>
+struct TypeIndex;
+
+template<>
+struct TypeIndex<> {
+ static const uint8_t index = 0;
+
+ template<typename _U>
+ static uint8_t get() {
+ return 0;
+ }
+};
+
+template<typename _Type, typename ... _Types>
+struct TypeIndex<_Type, _Types...> {
+ static const uint8_t index = TypeIndex<_Types...>::index + 1;
+
+ template<typename _U>
+ static uint8_t get(typename std::enable_if<std::is_same<_Type, _U>::value>::type* = 0) {
+ return index;
+ }
+
+ template<typename _U>
+ static uint8_t get(typename std::enable_if<!std::is_same<_Type, _U>::value>::type* = 0) {
+ return TypeIndex<_Types...>::template get<_U>();
+ }
+};
+
+template<typename... _Types>
+Variant<_Types...>::Variant()
+ : valueType_(TypesTupleSize::value) {
+ ApplyVoidIndexVisitor<Variant<_Types...>, _Types...>::visit(*this, valueType_);
+}
+
+template<typename... _Types>
+Variant<_Types...>::Variant(const Variant &_source) {
+ AssignmentVisitor<_Types...> visitor(*this, false);
+ ApplyVoidVisitor<
+ AssignmentVisitor<_Types...> , Variant<_Types...>, _Types...
+ >::visit(visitor, _source);
+}
+
+template<typename... _Types>
+Variant<_Types...>::Variant(Variant &&_source)
+{
+ AssignmentVisitor<_Types...> visitor(*this, false);
+ ApplyVoidVisitor<
+ AssignmentVisitor<_Types...> , Variant<_Types...>, _Types...
+ >::visit(visitor, _source);
+}
+
+template<typename... _Types>
+Variant<_Types...>::~Variant() {
+ if (hasValue()) {
+ DeleteVisitor<maxSize> visitor(valueStorage_);
+ ApplyVoidVisitor<
+ DeleteVisitor<maxSize>, Variant<_Types...>, _Types...
+ >::visit(visitor, *this);
+ }
+}
+
+template<typename... _Types>
+Variant<_Types...>& Variant<_Types...>::operator=(const Variant<_Types...> &_source) {
+ AssignmentVisitor<_Types...> visitor(*this, hasValue());
+ ApplyVoidVisitor<
+ AssignmentVisitor<_Types...>, Variant<_Types...>, _Types...
+ >::visit(visitor, _source);
+ return *this;
+}
+
+template<typename... _Types>
+Variant<_Types...>& Variant<_Types...>::operator=(Variant<_Types...> &&_source) {
+ AssignmentVisitor<_Types...> visitor(*this, hasValue());
+ ApplyVoidVisitor<
+ AssignmentVisitor<_Types...>, Variant<_Types...>, _Types...
+ >::visit(visitor, _source);
+ return *this;
+}
+
+template<typename ... _Types>
+template<typename _Type>
+typename std::enable_if<!std::is_same<_Type, Variant<_Types...>>::value, Variant<_Types...>&>::type
+Variant<_Types...>::operator=(const _Type &_value) {
+ set<typename TypeSelector<_Type, _Types...>::type>(_value, hasValue());
+ return *this;
+}
+
+template<typename ... _Types>
+template<typename _Type>
+const bool Variant<_Types...>::isType() const {
+ typedef typename TypeSelector<_Type, _Types...>::type selected_type_t;
+ uint8_t itsType = TypeIndex<_Types...>::template get<selected_type_t>();
+ if (itsType == valueType_) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+template<typename ... _Types>
+template<typename _Type>
+Variant<_Types...>::Variant(const _Type &_value,
+ typename std::enable_if<!std::is_const<_Type>::value>::type*,
+ typename std::enable_if<!std::is_reference<_Type>::value>::type*,
+ typename std::enable_if<!std::is_same<_Type, Variant<_Types...>>::value>::type*) {
+ set<typename TypeSelector<_Type, _Types...>::type>(_value, false);
+}
+
+template<typename ... _Types>
+template<typename _Type>
+Variant<_Types...>::Variant(_Type &&_value,
+typename std::enable_if<!std::is_const<_Type>::value>::type*,
+typename std::enable_if<!std::is_reference<_Type>::value>::type*,
+typename std::enable_if<!std::is_same<_Type, Variant<_Types...>>::value>::type*) {
+ set<typename TypeSelector<_Type, _Types...>::type>(std::move(_value), false);
+}
+
+
+template<typename ... _Types>
+template<typename _Type>
+const _Type & Variant<_Types...>::get() const {
+ typedef typename TypeSelector<_Type, _Types...>::type selected_type_t;
+ uint8_t itsType = TypeIndex<_Types...>::template get<selected_type_t>();
+ if (itsType == valueType_) {
+ return *(reinterpret_cast<const _Type *>(&valueStorage_));
+ } else {
+#ifdef __EXCEPTIONS
+ std::bad_cast toThrow;
+ throw toThrow;
+#else
+ printf("SerializableVariant.hpp:%i %s: Incorrect access to variant; attempting to get type not currently contained", __LINE__, __FUNCTION__);
+ abort();
+#endif
+ }
+}
+
+
+template<typename ... _Types>
+template<typename _U>
+void Variant<_Types...>::set(const _U &_value, const bool _clear) {
+ typedef typename TypeSelector<_U, _Types...>::type selected_type_t;
+
+ if (_clear) {
+ DeleteVisitor<maxSize> visitor(valueStorage_);
+ ApplyVoidVisitor<
+ DeleteVisitor<maxSize>, Variant<_Types...>, _Types...
+ >::visit(visitor, *this);
+ }
+ new (&valueStorage_) selected_type_t(std::move(_value));
+ valueType_ = TypeIndex<_Types...>::template get<selected_type_t>();
+}
+
+template<typename ... _Types>
+template<typename _U>
+void Variant<_Types...>::set(_U &&_value, const bool _clear) {
+ typedef typename TypeSelector<_U, _Types...>::type selected_type_t;
+
+ selected_type_t&& any_container_value = std::move(_value);
+ if(_clear)
+ {
+ DeleteVisitor<maxSize> visitor(valueStorage_);
+ ApplyVoidVisitor<
+ DeleteVisitor<maxSize>, Variant<_Types...>, _Types...
+ >::visit(visitor, *this);
+ } else {
+ new (&valueStorage_) selected_type_t(std::move(any_container_value));
+ }
+
+ valueType_ = TypeIndex<_Types...>::template get<selected_type_t>();
+}
+
+template<typename ... _Types>
+bool Variant<_Types...>::operator==(const Variant<_Types...> &_other) const
+{
+ PartialEqualsVisitor<_Types...> visitor(*this);
+ return ApplyBoolVisitor<
+ PartialEqualsVisitor<_Types...>, const Variant<_Types...>, _Types...
+ >::visit(visitor, _other);
+}
+
+template<typename ... _Types>
+bool Variant<_Types...>::operator!=(const Variant<_Types...> &_other) const
+{
+ return !(*this == _other);
+}
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_VARIANT_HPP_
diff --git a/include/CommonAPI/Version.hpp b/include/CommonAPI/Version.hpp
new file mode 100644
index 0000000..97534b0
--- /dev/null
+++ b/include/CommonAPI/Version.hpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_VERSION_HPP_
+#define COMMONAPI_VERSION_HPP_
+
+#include <cstdint>
+
+namespace CommonAPI {
+
+struct Version {
+ Version() = default;
+ Version(const uint32_t &majorValue, const uint32_t &minorValue)
+ : Major(majorValue), Minor(minorValue) {
+ }
+
+ uint32_t Major;
+ uint32_t Minor;
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_STRUCT_HPP_