Initial import to Git
authorJohannes Schanda <schanda@itestra.de>
Fri, 11 Jan 2013 09:41:12 +0000 (10:41 +0100)
committerJohannes Schanda <schanda@itestra.de>
Fri, 11 Jan 2013 09:41:12 +0000 (10:41 +0100)
83 files changed:
CommonAPI-DBus/AUTHORS [new file with mode: 0644]
CommonAPI-DBus/CommonAPI-DBus-uninstalled.pc.in [new file with mode: 0644]
CommonAPI-DBus/CommonAPI-DBus.pc.in [new file with mode: 0644]
CommonAPI-DBus/LICENSE [new file with mode: 0644]
CommonAPI-DBus/Makefile.am [new file with mode: 0644]
CommonAPI-DBus/TODO [new file with mode: 0644]
CommonAPI-DBus/aminclude.am [new file with mode: 0644]
CommonAPI-DBus/configure.ac [new file with mode: 0644]
CommonAPI-DBus/dbus-DBusMessage-add-support-for-custom-marshaling.patch [new file with mode: 0644]
CommonAPI-DBus/dbus-DBusMessage-disable-data-validation.patch [new file with mode: 0644]
CommonAPI-DBus/doxygen.cfg [new file with mode: 0644]
CommonAPI-DBus/eclipse-code-style-formatter.xml [new file with mode: 0644]
CommonAPI-DBus/m4/ax_cxx_compile_stdcxx_11.m4 [new file with mode: 0644]
CommonAPI-DBus/m4/ax_prog_doxygen.m4 [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusAttribute.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusConnection.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusConnection.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusDaemonProxy.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusDaemonProxy.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusError.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusError.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusEvent.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusFactory.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusFactory.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusFunctionalHash.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusFunctionalHash.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusHelper.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusInputStream.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusInputStream.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusMessage.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusMessage.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusMultiEvent.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusObjectManager.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusObjectManager.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusOutputStream.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusOutputStream.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusProxy.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusProxy.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusProxyConnection.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusProxyHelper.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusRuntime.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusRuntime.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusSerializableArguments.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusServiceRegistry.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusServiceRegistry.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusServiceStatusEvent.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusServiceStatusEvent.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusStubAdapter.cpp [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusStubAdapter.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusStubAdapterHelper.h [new file with mode: 0644]
CommonAPI-DBus/src/CommonAPI/DBus/DBusUtils.h [new file with mode: 0644]
CommonAPI-DBus/src/murmurhash/MurmurHash3.cpp [new file with mode: 0644]
CommonAPI-DBus/src/murmurhash/MurmurHash3.h [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusBenchmarkingTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusCommunicationTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusConnectionTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusDaemonProxyTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusFactoryTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusInputStreamTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusMultipleConnectionTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusNameCacheTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusOutputStreamTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusProxyTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusRuntimeTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusSerializableStructTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusSerializableStructTest.h [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusServiceRegistryTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusStubAdapterTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/DBusVariantTest.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/commonapi/tests/DerivedTypeCollection.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/commonapi/tests/DerivedTypeCollection.h [new file with mode: 0644]
CommonAPI-DBus/src/test/commonapi/tests/PredefinedTypeCollection.h [new file with mode: 0644]
CommonAPI-DBus/src/test/commonapi/tests/TestInterface.h [new file with mode: 0644]
CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceDBusProxy.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceDBusProxy.h [new file with mode: 0644]
CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceDBusStubAdapter.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceDBusStubAdapter.h [new file with mode: 0644]
CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceProxy.h [new file with mode: 0644]
CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceProxyBase.h [new file with mode: 0644]
CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceStub.h [new file with mode: 0644]
CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceStubDefault.cpp [new file with mode: 0644]
CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceStubDefault.h [new file with mode: 0644]

diff --git a/CommonAPI-DBus/AUTHORS b/CommonAPI-DBus/AUTHORS
new file mode 100644 (file)
index 0000000..a0d3b96
--- /dev/null
@@ -0,0 +1,4 @@
+BMW AG
+Aleksandar Kanchev <kanchev@itestra.com>
+Philip Rauwolf <rauwolf@itestra.com>
+Johannes Schanda <schanda@itestra.com>
diff --git a/CommonAPI-DBus/CommonAPI-DBus-uninstalled.pc.in b/CommonAPI-DBus/CommonAPI-DBus-uninstalled.pc.in
new file mode 100644 (file)
index 0000000..4d522e6
--- /dev/null
@@ -0,0 +1,11 @@
+abs_top_builddir=@abs_top_builddir@
+abs_top_srcdir=@abs_top_srcdir@
+prefix=
+exec_prefix=
+
+Name: Common API C++ D-Bus Middleware
+Description: GENIVI Common API C++ D-Bus Middleware (uninstalled copy)
+Version: @PACKAGE_VERSION@
+Requires: CommonAPI dbus-1
+Libs: ${abs_top_builddir}/libCommonAPI-DBus.la
+Cflags: -I${abs_top_srcdir}/src
\ No newline at end of file
diff --git a/CommonAPI-DBus/CommonAPI-DBus.pc.in b/CommonAPI-DBus/CommonAPI-DBus.pc.in
new file mode 100644 (file)
index 0000000..d59dfd4
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Common API C++ D-Bus Middleware
+Description: GENIVI Common API C++ D-Bus Middleware
+Version: @PACKAGE_VERSION@
+Requires: CommonAPI dbus-1
+Libs: -L${libdir} -lCommonAPI-DBus
+Cflags: -I${includedir}/CommonAPI-@PACKAGE_VERSION@
\ No newline at end of file
diff --git a/CommonAPI-DBus/LICENSE b/CommonAPI-DBus/LICENSE
new file mode 100644 (file)
index 0000000..14e2f77
--- /dev/null
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+    means each individual or legal entity that creates, contributes to
+    the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+    means the combination of the Contributions of others (if any) used
+    by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+    means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+    means Source Code Form to which the initial Contributor has attached
+    the notice in Exhibit A, the Executable Form of such Source Code
+    Form, and Modifications of such Source Code Form, in each case
+    including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+    means
+
+    (a) that the initial Contributor has attached the notice described
+        in Exhibit B to the Covered Software; or
+
+    (b) that the Covered Software was made available under the terms of
+        version 1.1 or earlier of the License, but not also under the
+        terms of a Secondary License.
+
+1.6. "Executable Form"
+    means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+    means a work that combines Covered Software with other material, in 
+    a separate file or files, that is not Covered Software.
+
+1.8. "License"
+    means this document.
+
+1.9. "Licensable"
+    means having the right to grant, to the maximum extent possible,
+    whether at the time of the initial grant or subsequently, any and
+    all of the rights conveyed by this License.
+
+1.10. "Modifications"
+    means any of the following:
+
+    (a) any file in Source Code Form that results from an addition to,
+        deletion from, or modification of the contents of Covered
+        Software; or
+
+    (b) any new file in Source Code Form that contains any Covered
+        Software.
+
+1.11. "Patent Claims" of a Contributor
+    means any patent claim(s), including without limitation, method,
+    process, and apparatus claims, in any patent Licensable by such
+    Contributor that would be infringed, but for the grant of the
+    License, by the making, using, selling, offering for sale, having
+    made, import, or transfer of either its Contributions or its
+    Contributor Version.
+
+1.12. "Secondary License"
+    means either the GNU General Public License, Version 2.0, the GNU
+    Lesser General Public License, Version 2.1, the GNU Affero General
+    Public License, Version 3.0, or any later versions of those
+    licenses.
+
+1.13. "Source Code Form"
+    means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+    means an individual or a legal entity exercising rights under this
+    License. For legal entities, "You" includes any entity that
+    controls, is controlled by, or is under common control with You. For
+    purposes of this definition, "control" means (a) the power, direct
+    or indirect, to cause the direction or management of such entity,
+    whether by contract or otherwise, or (b) ownership of more than
+    fifty percent (50%) of the outstanding shares or beneficial
+    ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+    Licensable by such Contributor to use, reproduce, make available,
+    modify, display, perform, distribute, and otherwise exploit its
+    Contributions, either on an unmodified basis, with Modifications, or
+    as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+    for sale, have made, import, and otherwise transfer either its
+    Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+    or
+
+(b) for infringements caused by: (i) Your and any other third party's
+    modifications of Covered Software, or (ii) the combination of its
+    Contributions with other software (except as part of its Contributor
+    Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+    its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+    Form, as described in Section 3.1, and You must inform recipients of
+    the Executable Form how they can obtain a copy of such Source Code
+    Form by reasonable means in a timely manner, at a charge no more
+    than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+    License, or sublicense it under different terms, provided that the
+    license for the Executable Form does not attempt to limit or alter
+    the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+*                                                                      *
+*  6. Disclaimer of Warranty                                           *
+*  -------------------------                                           *
+*                                                                      *
+*  Covered Software is provided under this License on an "as is"       *
+*  basis, without warranty of any kind, either expressed, implied, or  *
+*  statutory, including, without limitation, warranties that the       *
+*  Covered Software is free of defects, merchantable, fit for a        *
+*  particular purpose or non-infringing. The entire risk as to the     *
+*  quality and performance of the Covered Software is with You.        *
+*  Should any Covered Software prove defective in any respect, You     *
+*  (not any Contributor) assume the cost of any necessary servicing,   *
+*  repair, or correction. This disclaimer of warranty constitutes an   *
+*  essential part of this License. No use of any Covered Software is   *
+*  authorized under this License except under this disclaimer.         *
+*                                                                      *
+************************************************************************
+
+************************************************************************
+*                                                                      *
+*  7. Limitation of Liability                                          *
+*  --------------------------                                          *
+*                                                                      *
+*  Under no circumstances and under no legal theory, whether tort      *
+*  (including negligence), contract, or otherwise, shall any           *
+*  Contributor, or anyone who distributes Covered Software as          *
+*  permitted above, be liable to You for any direct, indirect,         *
+*  special, incidental, or consequential damages of any character      *
+*  including, without limitation, damages for lost profits, loss of    *
+*  goodwill, work stoppage, computer failure or malfunction, or any    *
+*  and all other commercial damages or losses, even if such party      *
+*  shall have been informed of the possibility of such damages. This   *
+*  limitation of liability shall not apply to liability for death or   *
+*  personal injury resulting from such party's negligence to the       *
+*  extent applicable law prohibits such limitation. Some               *
+*  jurisdictions do not allow the exclusion or limitation of           *
+*  incidental or consequential damages, so this exclusion and          *
+*  limitation may not apply to You.                                    *
+*                                                                      *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+  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 it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+  This Source Code Form is "Incompatible With Secondary Licenses", as
+  defined by the Mozilla Public License, v. 2.0.
diff --git a/CommonAPI-DBus/Makefile.am b/CommonAPI-DBus/Makefile.am
new file mode 100644 (file)
index 0000000..4fa9c6b
--- /dev/null
@@ -0,0 +1,183 @@
+ACLOCAL_AMFLAGS = -I m4
+
+EXTRA_DIST =
+MOSTLYCLEANFILES =
+
+AM_CPPFLAGS = \
+               ${COMMONAPI_CFLAGS} \
+               ${DBUS_CFLAGS} \
+               -I$(top_srcdir)/src
+
+LDADD = \
+               ${COMMONAPI_LIBS} \
+               ${DBUS_LIBS}
+
+lib_LTLIBRARIES =
+lib_LIBRARIES = 
+
+# ------------------------------------------------------------------------------
+lib_LTLIBRARIES += libmurmurhash-internal.la
+
+libmurmurhash_internal_la_SOURCES = \
+               src/murmurhash/MurmurHash3.h \
+               src/murmurhash/MurmurHash3.cpp
+
+# ------------------------------------------------------------------------------
+lib_LTLIBRARIES += libCommonAPI-DBus.la
+
+libCommonAPI_DBus_la_SOURCES = \
+               src/CommonAPI/DBus/DBusConnection.cpp \
+               src/CommonAPI/DBus/DBusDaemonProxy.cpp \
+               src/CommonAPI/DBus/DBusError.cpp \
+               src/CommonAPI/DBus/DBusFunctionalHash.cpp \
+               src/CommonAPI/DBus/DBusInputStream.cpp \
+               src/CommonAPI/DBus/DBusMessage.cpp \
+               src/CommonAPI/DBus/DBusObjectManager.cpp \
+               src/CommonAPI/DBus/DBusOutputStream.cpp \
+               src/CommonAPI/DBus/DBusProxy.cpp \
+               src/CommonAPI/DBus/DBusFactory.cpp \
+               src/CommonAPI/DBus/DBusRuntime.cpp \
+               src/CommonAPI/DBus/DBusServiceRegistry.cpp \
+               src/CommonAPI/DBus/DBusServiceStatusEvent.cpp \
+               src/CommonAPI/DBus/DBusStubAdapter.cpp
+
+libCommonAPI_DBus_la_LIBADD = \
+               libmurmurhash-internal.la \
+               ${COMMONAPI_LIBS}
+
+CommonAPI_DBus_includedir=$(includedir)/CommonAPI-${VERSION}/CommonAPI/DBus
+CommonAPI_DBus_include_HEADERS = \
+               src/CommonAPI/DBus/DBusAttribute.h \
+        src/CommonAPI/DBus/DBusConnection.h \
+        src/CommonAPI/DBus/DBusDaemonProxy.h \
+        src/CommonAPI/DBus/DBusError.h \
+        src/CommonAPI/DBus/DBusEvent.h \
+        src/CommonAPI/DBus/DBusFunctionalHash.h \
+        src/CommonAPI/DBus/DBusHelper.h \
+        src/CommonAPI/DBus/DBusInputStream.h \
+        src/CommonAPI/DBus/DBusMessage.h \
+        src/CommonAPI/DBus/DBusMultiEvent.h \
+        src/CommonAPI/DBus/DBusObjectManager.h \
+        src/CommonAPI/DBus/DBusOutputStream.h \
+        src/CommonAPI/DBus/DBusProxy.h \
+        src/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.h \
+        src/CommonAPI/DBus/DBusProxyConnection.h \
+               src/CommonAPI/DBus/DBusFactory.h \
+               src/CommonAPI/DBus/DBusProxyHelper.h \
+               src/CommonAPI/DBus/DBusRuntime.h \
+               src/CommonAPI/DBus/DBusSerializableArguments.h \
+               src/CommonAPI/DBus/DBusServiceRegistry.h \
+               src/CommonAPI/DBus/DBusServiceStatusEvent.h \
+               src/CommonAPI/DBus/DBusStubAdapter.h \
+               src/CommonAPI/DBus/DBusStubAdapterHelper.h \
+               src/CommonAPI/DBus/DBusUtils.h
+
+pkgconfigdir = ${libdir}/pkgconfig
+pkgconfig_DATA = CommonAPI-DBus.pc
+
+# ------------------------------------------------------------------------------
+if ENABLE_TESTS
+
+TestInterfaceSources = \
+               src/test/commonapi/tests/DerivedTypeCollection.cpp \
+               src/test/commonapi/tests/TestInterfaceDBusProxy.cpp \
+               src/test/commonapi/tests/TestInterfaceDBusStubAdapter.cpp \
+               src/test/commonapi/tests/TestInterfaceStubDefault.cpp
+
+check_PROGRAMS = \
+               DBusCommunicationTest \
+               DBusMultipleConnectionTest \
+               DBusDaemonProxyTest \
+               DBusInputStreamTest \
+               DBusOutputStreamTest \
+               DBusRuntimeTest \
+               DBusFactoryTest \
+               DBusProxyTest \
+               DBusVariantTest \
+               DBusBenchmarkingTest
+
+TESTS =        ${check_PROGRAMS}
+
+DBusBenchmarkingTest_SOURCES = src/test/DBusBenchmarkingTest.cpp
+DBusBenchmarkingTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS}
+DBusBenchmarkingTest_CXXFLAGS = ${GTEST_CXXFLAGS}
+DBusBenchmarkingTest_LDADD = ${LDADD} ${GTEST_LIBS} libCommonAPI-DBus.la
+
+DBusCommunicationTest_SOURCES = \
+               src/test/DBusCommunicationTest.cpp \
+               ${TestInterfaceSources}
+DBusCommunicationTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS}
+DBusCommunicationTest_CXXFLAGS = ${GTEST_CXXFLAGS}
+DBusCommunicationTest_LDADD = ${LDADD} ${GTEST_LIBS} libCommonAPI-DBus.la
+
+DBusDaemonProxyTest_SOURCES = src/test/DBusDaemonProxyTest.cpp
+DBusDaemonProxyTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS}
+DBusDaemonProxyTest_CXXFLAGS = ${GTEST_CXXFLAGS}
+DBusDaemonProxyTest_LDADD = ${LDADD} ${GTEST_LIBS} libCommonAPI-DBus.la
+
+DBusInputStreamTest_SOURCES = src/test/DBusInputStreamTest.cpp
+DBusInputStreamTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS}
+DBusInputStreamTest_CXXFLAGS = ${GTEST_CXXFLAGS}
+DBusInputStreamTest_LDADD = ${LDADD} ${GTEST_LIBS} libCommonAPI-DBus.la
+
+DBusOutputStreamTest_SOURCES = src/test/DBusOutputStreamTest.cpp
+DBusOutputStreamTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS}
+DBusOutputStreamTest_CXXFLAGS = ${GTEST_CXXFLAGS}
+DBusOutputStreamTest_LDADD = ${LDADD} ${GTEST_LIBS} libCommonAPI-DBus.la
+
+DBusFactoryTest_SOURCES = \
+               src/test/DBusFactoryTest.cpp \
+               ${TestInterfaceSources}
+DBusFactoryTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS}
+DBusFactoryTest_CXXFLAGS = ${GTEST_CXXFLAGS}
+DBusFactoryTest_LDADD = ${LDADD} ${GTEST_LIBS} libCommonAPI-DBus.la
+
+DBusRuntimeTest_SOURCES = src/test/DBusRuntimeTest.cpp
+DBusRuntimeTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS}
+DBusRuntimeTest_CXXFLAGS = ${GTEST_CXXFLAGS}
+DBusRuntimeTest_LDADD = ${LDADD} ${GTEST_LIBS} libCommonAPI-DBus.la
+
+#DBusStubAdapterTest_SOURCES = src/test/DBusStubAdapterTest.cpp
+#DBusStubAdapterTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS}
+#DBusStubAdapterTest_CXXFLAGS = ${GTEST_CXXFLAGS}
+#DBusStubAdapterTest_LDADD = ${LDADD} ${GTEST_LIBS} libCommonAPI-DBus.la
+
+DBusMultipleConnectionTest_SOURCES = src/test/DBusMultipleConnectionTest.cpp \
+                                                                        ${TestInterfaceSources}
+DBusMultipleConnectionTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS}
+DBusMultipleConnectionTest_CXXFLAGS = ${GTEST_CXXFLAGS}
+DBusMultipleConnectionTest_LDADD = ${LDADD} ${GTEST_LIBS} libCommonAPI-DBus.la
+
+DBusProxyTest_SOURCES = src/test/DBusProxyTest.cpp
+DBusProxyTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS}
+DBusProxyTest_CXXFLAGS = ${GTEST_CXXFLAGS}
+DBusProxyTest_LDADD = ${LDADD} ${GTEST_LIBS} libCommonAPI-DBus.la
+
+DBusVariantTest_SOURCES = src/test/DBusVariantTest.cpp
+DBusVariantTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS}
+DBusVariantTest_CXXFLAGS = ${GTEST_CXXFLAGS}
+DBusVariantTest_LDADD = ${LDADD} ${GTEST_LIBS} libCommonAPI-DBus.la
+
+endif
+
+
+# ------------------------------------------------------------------------------
+# Doxygen
+include $(top_srcdir)/aminclude.am 
+EXTRA_DIST += doxygen.cfg
+MOSTLYCLEANFILES += ${DX_CLEANFILES}
+
+# ------------------------------------------------------------------------------
+MAINTAINERCLEANFILES = \
+               Makefile.in \
+               aclocal.m4 \
+               configure
+
+clean-local:
+       -rm -rf src-gen
+
+maintainer-clean-local:
+       -rm -rf build-aux
+       -rm -f config.h.in*
+       -rm -f m4/libtool*.m4
+       -rm -f m4/lt*.m4
diff --git a/CommonAPI-DBus/TODO b/CommonAPI-DBus/TODO
new file mode 100644 (file)
index 0000000..d1331ca
--- /dev/null
@@ -0,0 +1,84 @@
+* Move Version checking to the ServiceRegistry:
+       Currently, ensuring the interface-version based compatibility of the local proxy and
+       a given remote service would be done asynchronously within the proxy right after its creation.
+       The check should be moved to the service registry, so that a proxy only needs to ask
+       for the locally cached version information of the remote service.
+       According to the current CommonAPI Spec, it is required that a proxy remains "unavailable" when
+       it's counterpart has an incompatible interface version.
+       Feasibility of and alternatives to this approach remain to be determined.
+
+* Performance:
+       Check especially message dispatching! Is it possible to do the dispatching without copying
+       the interface name and object path strings?
+       Check (de)serialization, improve where possible.
+
+* Implementation of Variants.
+
+* Dedicated Test of multiple connect/disconnect cycles
+
+* Life Cycle of connections: Disconnect/Destroy with ProxyFactory, how to do this otherwise?
+
+* DBusProxyHelper.h:
+  // TODO: Must implement available checks on method calls, and wait for valid avalable status in sync case
+  /*
+   * XXX DBusProxy declares a private DBusReadonlyAttribute variable, which
+   * cuases a circular dependency. As a workaround the DBusProxy must be
+   * forward declared and set as default parameter to the template attribute
+   * classes.
+   *
+   * Since DBus*Attribute use the DBusProxyHelper, we have to use the
+   * DBusProxy class as a template typename.
+   */
+
+* DBusMultiEvent.h:
+  /*
+   * XXX DBusProxy declares a private DBusReadonlyAttribute variable, which
+   * cuases a circular dependency. As a workaround the DBusProxy must be
+   * forward declared and set as default parameter to the template attribute
+   * classes.
+   *
+   * Since DBus*Attribute use the DBusProxyHelper, we have to use the
+   * DBusProxy class as a template typename.
+   */
+  //TODO: if rehashing occurs, then all iterators are invalidated.
+  //TODO: rework with pointers, since this is D-Bus only
+  typedef typename ListenersMap::iterator Subscription;
+
+* DBusAttribute.h:
+  /*
+   * XXX DBusProxy declares a private DBusReadonlyAttribute variable, which
+   * causes a circular dependency. As a workaround the DBusProxy must be
+   * forward declared and set as default parameter to the template attribute
+   * classes.
+   */
+
+* DBusServiceRegistry.h:
+  isServiceInstanceAlive: //TODO Fallback for services not in dbus object manager
+
+* DBus Generator: implizite Array-Deklaration via "[]" (z.B. UInt32[] in Methoden-Aufruf) unterstützen!
+
+
+
+
+Future development (2.1):
+
+* Request Name for DBusStubAdapter:
+       The D-Bus specification states that a single D-Bus connection might own multiple names.
+       We have to make sure that when a register request comes from the CommonAPI StubAdapter
+       Factory that we make sure that the name is already owned by our DBusConnection.
+       Probably we'll have to keep a list of all owned names and request a new one on registration
+       if required.
+
+* Check static/dynamic loading of libraries, make it work. 
+
+* Doxygen in CommonAPI source code.
+
+* Main Loop Integration
+       - Per Factory or on Runtime level?
+       - Which functions are needed?
+       - Example with Glib on CommonAPI base (not D-Bus specific)
+       - Christian Linke has some ideas
+
+- Handling of D-Bus properties!! Sollte auf Franca attributes gemapped sein (Grund: Interoperabilität)
+
+* getValue on attributes is inconsisten with other methods, CallStatus should be in signature not return
\ No newline at end of file
diff --git a/CommonAPI-DBus/aminclude.am b/CommonAPI-DBus/aminclude.am
new file mode 100644 (file)
index 0000000..7dfed8d
--- /dev/null
@@ -0,0 +1,168 @@
+#   Copyright (c) 2009 Oren Ben-Kiki <oren@ben-kiki.org>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+#
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_prog_doxygen.html
+# ===========================================================================
+#
+
+## --------------------------------- ##
+## Format-independent Doxygen rules. ##
+## --------------------------------- ##
+
+if DX_COND_doc
+
+## ------------------------------- ##
+## Rules specific for HTML output. ##
+## ------------------------------- ##
+
+if DX_COND_html
+
+DX_CLEAN_HTML = @DX_DOCDIR@/html
+
+endif # DX_COND_html
+
+## ------------------------------ ##
+## Rules specific for CHM output. ##
+## ------------------------------ ##
+
+if DX_COND_chm
+
+DX_CLEAN_CHM = @DX_DOCDIR@/chm
+
+if DX_COND_chi
+
+DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi
+
+endif # DX_COND_chi
+
+endif # DX_COND_chm
+
+## ------------------------------ ##
+## Rules specific for MAN output. ##
+## ------------------------------ ##
+
+if DX_COND_man
+
+DX_CLEAN_MAN = @DX_DOCDIR@/man
+
+endif # DX_COND_man
+
+## ------------------------------ ##
+## Rules specific for RTF output. ##
+## ------------------------------ ##
+
+if DX_COND_rtf
+
+DX_CLEAN_RTF = @DX_DOCDIR@/rtf
+
+endif # DX_COND_rtf
+
+## ------------------------------ ##
+## Rules specific for XML output. ##
+## ------------------------------ ##
+
+if DX_COND_xml
+
+DX_CLEAN_XML = @DX_DOCDIR@/xml
+
+endif # DX_COND_xml
+
+## ----------------------------- ##
+## Rules specific for PS output. ##
+## ----------------------------- ##
+
+if DX_COND_ps
+
+DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps
+
+DX_PS_GOAL = doxygen-ps
+
+doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
+
+@DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag
+    cd @DX_DOCDIR@/latex; \
+    rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
+    $(DX_LATEX) refman.tex; \
+    $(MAKEINDEX_PATH) refman.idx; \
+    $(DX_LATEX) refman.tex; \
+    countdown=5; \
+    while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
+                                               refman.log > /dev/null 2>&1 \
+               && test $$countdown -gt 0; do \
+               $(DX_LATEX) refman.tex; \
+               countdown=`expr $$countdown - 1`; \
+       done; \
+       $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
+
+endif # DX_COND_ps
+
+## ------------------------------ ##
+## Rules specific for PDF output. ##
+## ------------------------------ ##
+
+if DX_COND_pdf
+
+DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf
+
+DX_PDF_GOAL = doxygen-pdf
+
+doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf
+
+@DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag
+       cd @DX_DOCDIR@/latex; \
+       rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
+       $(DX_PDFLATEX) refman.tex; \
+       $(DX_MAKEINDEX) refman.idx; \
+       $(DX_PDFLATEX) refman.tex; \
+       countdown=5; \
+       while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
+                      refman.log > /dev/null 2>&1 \
+       && test $$countdown -gt 0; do \
+        $(DX_PDFLATEX) refman.tex; \
+        countdown=`expr $$countdown - 1`; \
+       done; \
+       mv refman.pdf ../@PACKAGE@.pdf
+
+endif # DX_COND_pdf
+
+## ------------------------------------------------- ##
+## Rules specific for LaTeX (shared for PS and PDF). ##
+## ------------------------------------------------- ##
+
+if DX_COND_latex
+
+DX_CLEAN_LATEX = @DX_DOCDIR@/latex
+
+endif # DX_COND_latex
+
+.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag
+
+doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+@DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
+       rm -rf @DX_DOCDIR@
+       $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
+
+DX_CLEANFILES = \
+    @DX_DOCDIR@/@PACKAGE@.tag \
+    -r \
+    $(DX_CLEAN_HTML) \
+    $(DX_CLEAN_CHM) \
+    $(DX_CLEAN_CHI) \
+    $(DX_CLEAN_MAN) \
+    $(DX_CLEAN_RTF) \
+    $(DX_CLEAN_XML) \
+    $(DX_CLEAN_PS) \
+    $(DX_CLEAN_PDF) \
+    $(DX_CLEAN_LATEX)
+
+endif # DX_COND_doc
\ No newline at end of file
diff --git a/CommonAPI-DBus/configure.ac b/CommonAPI-DBus/configure.ac
new file mode 100644 (file)
index 0000000..e09f244
--- /dev/null
@@ -0,0 +1,97 @@
+AC_PREREQ(2.61)
+AC_INIT([GENIVI Common API DBus C++ Library],
+        [0.7],
+        [],
+        [CommonAPI-DBus])
+
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_HEADERS([build-aux/config.h])
+AC_CONFIG_FILES([
+               Makefile
+               CommonAPI-DBus.pc
+       CommonAPI-DBus-uninstalled.pc])
+
+AC_CANONICAL_SYSTEM
+
+AM_INIT_AUTOMAKE([foreign 1.11 silent-rules subdir-objects color-tests -Wall -Werror])
+AM_SILENT_RULES
+AM_MAINTAINER_MODE
+
+AC_PROG_CXX
+AC_LANG([C++])
+AX_CXX_COMPILE_STDCXX_11([noext])
+
+AC_ARG_VAR([GTEST_CONFIG], [The exact path of Google Test's 'gtest-config' script.])
+
+LT_PREREQ(2.2)
+LT_INIT
+
+PKG_PROG_PKG_CONFIG
+PKG_CHECK_MODULES(COMMONAPI, [CommonAPI >= 0.7])
+PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.4.6])
+
+GTEST_MIN_VERSION="1.6.0"
+GTEST_URL="http://code.google.com/p/googletest"
+
+
+AC_ARG_VAR([GTEST_CONFIG], [The exact path of Google Test's 'gtest-config' script.])
+AC_ARG_VAR([GTEST_CPPFLAGS], [C-like preprocessor flags for Google Test.])
+AC_ARG_VAR([GTEST_CXXFLAGS], [C++ compile flags for Google Test.])
+AC_ARG_VAR([GTEST_LDFLAGS], [Linker path and option flags for Google Test.])
+AC_ARG_VAR([GTEST_LIBS], [Library linking flags for Google Test.])
+AC_ARG_VAR([GTEST_VERSION], [The available version of Google Test.])
+
+AS_IF([test -f "${GTEST_CONFIG}"],
+      [AS_IF([${GTEST_CONFIG} --min-version=${GTEST_MIN_VERSION}],
+             [],
+             [AC_MSG_ERROR([dnl
+                            Found Google Test Version ${GTEST_VERSION}. However ${GTEST_MIN_VERSION} is
+                            required. Please refer to ${GTEST_URL} for a more recent version.])])
+       [GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags`]
+       [GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags`]
+       [GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags`]
+       [GTEST_LIBS=`${GTEST_CONFIG} --libs`]
+       [GTEST_VERSION=`${GTEST_CONFIG} --version`]
+      ]
+      []
+)
+
+AM_CONDITIONAL(ENABLE_TESTS, [test -f "${GTEST_CONFIG}"])
+
+
+# Doxygen support
+DX_HTML_FEATURE(ON)
+DX_CHM_FEATURE(OFF)
+DX_CHI_FEATURE(OFF)
+DX_MAN_FEATURE(OFF)
+DX_RTF_FEATURE(OFF)
+DX_XML_FEATURE(OFF)
+DX_PDF_FEATURE(OFF)
+DX_PS_FEATURE(OFF)
+DX_INIT_DOXYGEN(${PACKAGE_NAME}, doxygen.cfg, doc)
+    
+AC_MSG_RESULT([
+        $PACKAGE_NAME v$VERSION
+
+        enable docs:       ${ENABLE_DOCS}
+
+               COMMONAPI_CFLAGS:  ${COMMONAPI_CFLAGS}
+               COMMONAPI_LIBS:    ${COMMONAPI_LIBS}
+
+               DBUS_CFLAGS:       ${DBUS_CFLAGS}
+               DBUS_LIBS:         ${DBUS_LIBS}
+
+        GTEST_CONFIG:      ${GTEST_CONFIG}
+        GTEST_CPPFLAGS:    ${GTEST_CPPFLAGS}
+        GTEST_CXXFLAGS:    ${GTEST_CXXFLAGS}
+        GTEST_LDFLAGS:     ${GTEST_LDFLAGS}
+        GTEST_LIBS:        ${GTEST_LIBS}
+        GTEST_VERSION:     ${GTEST_VERSION}
+
+        prefix:            ${prefix}
+        CXXFLAGS:          ${CXXFLAGS}
+        LDFLAGS:           ${LDFLAGS}
+])
+
+AC_OUTPUT
\ No newline at end of file
diff --git a/CommonAPI-DBus/dbus-DBusMessage-add-support-for-custom-marshaling.patch b/CommonAPI-DBus/dbus-DBusMessage-add-support-for-custom-marshaling.patch
new file mode 100644 (file)
index 0000000..5f225f3
--- /dev/null
@@ -0,0 +1,267 @@
+From 467a2e307462b02865b35397c572b6048c2934e2 Mon Sep 17 00:00:00 2001
+From: Aleksandar Kanchev <kanchev@itestra.com>
+Date: Mon, 9 Jul 2012 18:09:04 +0200
+Subject: [PATCH] DBusMessage: add support for custom marshaling
+
+Add functions to support querying and manipulating the message body and
+signature. This is useful for code generators, which can generate custom
+marshaling functions based on a given IDL. Those functions tend to be
+optimized and faster than the generic iterator based marshaling.
+---
+ dbus/dbus-message.c |  143 +++++++++++++++++++++++++++++++++++----------------
+ dbus/dbus-message.h |   13 +++++
+ dbus/dbus-string.c  |   16 ++++++
+ dbus/dbus-string.h  |    4 ++
+ 4 files changed, 132 insertions(+), 44 deletions(-)
+
+diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
+index 24ef5ac..fbacfba 100644
+--- a/dbus/dbus-message.c
++++ b/dbus/dbus-message.c
+@@ -356,50 +356,6 @@ set_or_delete_string_field (DBusMessage *message,
+                                          &value);
+ }
+-#if 0
+-/* Probably we don't need to use this */
+-/**
+- * Sets the signature of the message, i.e. the arguments in the
+- * message payload. The signature includes only "in" arguments for
+- * #DBUS_MESSAGE_TYPE_METHOD_CALL and only "out" arguments for
+- * #DBUS_MESSAGE_TYPE_METHOD_RETURN, so is slightly different from
+- * what you might expect (it does not include the signature of the
+- * entire C++-style method).
+- *
+- * The signature is a string made up of type codes such as
+- * #DBUS_TYPE_INT32. The string is terminated with nul (nul is also
+- * the value of #DBUS_TYPE_INVALID). The macros such as
+- * #DBUS_TYPE_INT32 evaluate to integers; to assemble a signature you
+- * may find it useful to use the string forms, such as
+- * #DBUS_TYPE_INT32_AS_STRING.
+- *
+- * An "unset" or #NULL signature is considered the same as an empty
+- * signature. In fact dbus_message_get_signature() will never return
+- * #NULL.
+- *
+- * @param message the message
+- * @param signature the type signature or #NULL to unset
+- * @returns #FALSE if no memory
+- */
+-static dbus_bool_t
+-_dbus_message_set_signature (DBusMessage *message,
+-                             const char  *signature)
+-{
+-  _dbus_return_val_if_fail (message != NULL, FALSE);
+-  _dbus_return_val_if_fail (!message->locked, FALSE);
+-  _dbus_return_val_if_fail (signature == NULL ||
+-                            _dbus_check_is_valid_signature (signature));
+-  /* can't delete the signature if you have a message body */
+-  _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
+-                            signature != NULL);
+-
+-  return set_or_delete_string_field (message,
+-                                     DBUS_HEADER_FIELD_SIGNATURE,
+-                                     DBUS_TYPE_SIGNATURE,
+-                                     signature);
+-}
+-#endif
+-
+ /* Message Cache
+  *
+  * We cache some DBusMessage to reduce the overhead of allocating
+@@ -3370,6 +3326,47 @@ dbus_message_get_sender (DBusMessage *message)
+ }
+ /**
++ * Sets the signature of the message, i.e. the arguments in the
++ * message payload. The signature includes only "in" arguments for
++ * #DBUS_MESSAGE_TYPE_METHOD_CALL and only "out" arguments for
++ * #DBUS_MESSAGE_TYPE_METHOD_RETURN, so is slightly different from
++ * what you might expect (it does not include the signature of the
++ * entire C++-style method).
++ *
++ * The signature is a string made up of type codes such as
++ * #DBUS_TYPE_INT32. The string is terminated with nul (nul is also
++ * the value of #DBUS_TYPE_INVALID). The macros such as
++ * #DBUS_TYPE_INT32 evaluate to integers; to assemble a signature you
++ * may find it useful to use the string forms, such as
++ * #DBUS_TYPE_INT32_AS_STRING.
++ *
++ * An "unset" or #NULL signature is considered the same as an empty
++ * signature. In fact dbus_message_get_signature() will never return
++ * #NULL.
++ *
++ * @param message the message
++ * @param signature the type signature or #NULL to unset
++ * @returns #FALSE if no memory
++ */
++dbus_bool_t
++dbus_message_set_signature (DBusMessage *message,
++                            const char  *signature)
++{
++  _dbus_return_val_if_fail (message != NULL, FALSE);
++  _dbus_return_val_if_fail (!message->locked, FALSE);
++  _dbus_return_val_if_fail (signature == NULL ||
++                            _dbus_check_is_valid_signature (signature), FALSE);
++  /* can't delete the signature if you have a message body */
++  _dbus_return_val_if_fail (_dbus_string_get_length (&message->body) == 0 ||
++                            signature != NULL, FALSE);
++
++  return set_or_delete_string_field (message,
++                                     DBUS_HEADER_FIELD_SIGNATURE,
++                                     DBUS_TYPE_SIGNATURE,
++                                     signature);
++}
++
++/**
+  * Gets the type signature of the message, i.e. the arguments in the
+  * message payload. The signature includes only "in" arguments for
+  * #DBUS_MESSAGE_TYPE_METHOD_CALL and only "out" arguments for
+@@ -4519,6 +4516,64 @@ dbus_message_type_to_string (int type)
+ }
+ /**
++ * Returns pointer to the buffer used to store the message body.
++ *
++ * @param message the message
++ * @return pointer to the message body memory
++ */
++char*
++dbus_message_get_body (DBusMessage *message) {
++  _dbus_return_val_if_fail (message != NULL, NULL);
++
++  return _dbus_string_get_data(&(message->body));
++}
++
++/**
++ * Adjust the length of the message body buffer. The memory will be reallocated
++ * if the new length is bigger than the already allocated size.
++ *
++ * @see dbus_message_get_body_allocated
++ * @param message the message
++ * @param length the new length of the body
++ * @return #TRUE if successful
++ */
++dbus_bool_t
++dbus_message_set_body_length (DBusMessage *message,
++                              int length) {
++  _dbus_return_val_if_fail (message != NULL, FALSE);
++  _dbus_return_val_if_fail (length >= 0, FALSE);
++
++  return _dbus_string_set_length(&(message->body), length);
++}
++
++/**
++ * Gets the length of the message body buffer.
++ *
++ * @param message the message
++ * @param length the new length of the body
++ * @return the length of the body buffer
++ */
++int
++dbus_message_get_body_length (DBusMessage *message) {
++  _dbus_return_val_if_fail (message != NULL, 0);
++
++  return _dbus_string_get_length(&(message->body));
++}
++
++/**
++ * Gets the allocated memory size used to hold the message body.
++ *
++ * @param message the message
++ * @return size of the allocated message body memory
++ */
++int
++dbus_message_get_body_allocated (DBusMessage *message) {
++  _dbus_return_val_if_fail (message != NULL, 0);
++
++  return _dbus_string_get_allocated(&(message->body));
++}
++
++/**
+  * Turn a DBusMessage into the marshalled form as described in the D-Bus
+  * specification.
+  *
+diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h
+index 5500492..55388ac 100644
+--- a/dbus/dbus-message.h
++++ b/dbus/dbus-message.h
+@@ -138,6 +138,9 @@ dbus_bool_t   dbus_message_set_sender       (DBusMessage   *message,
+ DBUS_EXPORT
+ const char*   dbus_message_get_sender       (DBusMessage   *message);
+ DBUS_EXPORT
++dbus_bool_t   dbus_message_set_signature    (DBusMessage   *message,
++                                             const char    *signature);
++DBUS_EXPORT
+ const char*   dbus_message_get_signature    (DBusMessage   *message);
+ DBUS_EXPORT
+ void          dbus_message_set_no_reply     (DBusMessage   *message,
+@@ -264,6 +267,16 @@ void        dbus_message_iter_abandon_container  (DBusMessageIter *iter,
+                                                   DBusMessageIter *sub);
+ DBUS_EXPORT
++char*       dbus_message_get_body           (DBusMessage   *message);
++DBUS_EXPORT
++dbus_bool_t dbus_message_set_body_length    (DBusMessage   *message,
++                                             int length);
++DBUS_EXPORT
++int         dbus_message_get_body_length    (DBusMessage   *message);
++DBUS_EXPORT
++int         dbus_message_get_body_allocated (DBusMessage   *message);
++
++DBUS_EXPORT
+ void dbus_message_lock    (DBusMessage  *message);
+ DBUS_EXPORT
+diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c
+index e2eb93b..d8628ba 100644
+--- a/dbus/dbus-string.c
++++ b/dbus/dbus-string.c
+@@ -848,6 +848,22 @@ _dbus_string_get_length (const DBusString  *str)
+ }
+ #endif /* !_dbus_string_get_length */
++/* Only have the function if we don't have the macro */
++#ifndef _dbus_string_get_allocated
++/**
++ * Gets the allocated length of a string (not including nul termination).
++ *
++ * @returns the allocated length.
++ */
++int
++_dbus_string_get_allocated(const DBusString  *str)
++{
++  DBUS_CONST_STRING_PREAMBLE (str);
++
++  return real->allocated;
++}
++#endif /* !_dbus_string_get_allocated */
++
+ /**
+  * Makes a string longer by the given number of bytes.  Checks whether
+  * adding additional_length to the current length would overflow an
+diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h
+index 2f1ed31..490aea6 100644
+--- a/dbus/dbus-string.h
++++ b/dbus/dbus-string.h
+@@ -62,6 +62,7 @@ struct DBusString
+  */
+ #define _dbus_string_get_data(s) ((char*)(((DBusString*)(s))->dummy1))
+ #define _dbus_string_get_length(s) (((DBusString*)(s))->dummy2)
++#define _dbus_string_get_allocated(s) (((DBusString*)(s))->dummy3 - _DBUS_STRING_ALLOCATION_PADDING)
+ #define _dbus_string_set_byte(s, i, b) ((((unsigned char*)(((DBusString*)(s))->dummy1))[(i)]) = (unsigned char) (b))
+ #define _dbus_string_get_byte(s, i) (((const unsigned char*)(((DBusString*)(s))->dummy1))[(i)])
+ #define _dbus_string_get_const_data(s) ((const char*)(((DBusString*)(s))->dummy1))
+@@ -131,6 +132,9 @@ void          _dbus_string_copy_to_buffer_with_nul (const DBusString  *str,
+ #ifndef _dbus_string_get_length
+ int           _dbus_string_get_length            (const DBusString  *str);
+ #endif /* !_dbus_string_get_length */
++#ifndef _dbus_string_get_allocated
++int           _dbus_string_get_allocated         (const DBusString  *str);
++#endif /* !_dbus_string_get_allocated */
+ dbus_bool_t   _dbus_string_lengthen              (DBusString        *str,
+                                                   int                additional_length);
+-- 
+1.7.10.2
+
diff --git a/CommonAPI-DBus/dbus-DBusMessage-disable-data-validation.patch b/CommonAPI-DBus/dbus-DBusMessage-disable-data-validation.patch
new file mode 100644 (file)
index 0000000..4983900
--- /dev/null
@@ -0,0 +1,25 @@
+From 762a0ceb1ff6b4c69eced23902fbc404870f21ca Mon Sep 17 00:00:00 2001
+From: Philip Rauwolf <rauwolf@itestra.de>
+Date: Fri, 3 Aug 2012 16:34:59 +0200
+Subject: [PATCH] Disabled all data checks in DBUS
+
+---
+ dbus/dbus-message.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
+index 5e570bd..9883e70 100644
+--- a/dbus/dbus-message.c
++++ b/dbus/dbus-message.c
+@@ -3960,7 +3960,7 @@ load_message (DBusMessageLoader *loader,
+   DBusValidationMode mode;
+   dbus_uint32_t n_unix_fds = 0;
+-  mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
++  mode = DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY;
+   
+   oom = FALSE;
+-- 
+1.7.10.4
+
diff --git a/CommonAPI-DBus/doxygen.cfg b/CommonAPI-DBus/doxygen.cfg
new file mode 100644 (file)
index 0000000..ec60bb2
--- /dev/null
@@ -0,0 +1,1794 @@
+# Doxyfile 1.8.1.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME           = $(PROJECT)-$(VERSION)
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER         =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO           =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = $(DOCDIR)
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH        = $(SRCDIR)
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this
+# tag. The format is ext=language, where ext is a file extension, and language
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
+# comments according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you
+# can mix doxygen, HTML, and XML commands with Markdown formatting.
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penalty.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will roughly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+SYMBOL_CACHE_SIZE      = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 0
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE            =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT                  = $(SRCDIR)
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS          =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML          = $(GENERATE_HTML)
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+#  for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# style sheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+# entries shown in the various tree structured indices initially; the user
+# can expand and collapse entries dynamically later on. Doxygen will expand
+# the tree to such a level that at most the specified number of entries are
+# visible (unless a fully collapsed tree already exceeds this amount).
+# So setting the number of entries 1 will produce a full collapsed tree by
+# default. 0 is a special value representing an infinite number of entries
+# and will result in a full expanded tree by default.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = $(GENERATE_HTMLHELP)
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE               = ../$(PROJECT).chm
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = $(HHC_PATH)
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = $(GENERATE_CHI)
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING     =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = YES
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+#  will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW      = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you may also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to
+# the MathJax Content Delivery Network so you can quickly see the result without
+# installing MathJax.
+# However, it is strongly recommended to install a local
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS     =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX         = $(GENERATE_LATEX)
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         =
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME     =
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX          = YES
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = $(PAPER_SIZE)
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER           =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = $(GENERATE_PDF)
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = YES
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF           = $(GENERATE_RTF)
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF            = YES
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN           = $(GENERATE_MAN)
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML           = $(GENERATE_XML)
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA             =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD                =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH           = .
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS  =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED             = _DOXYGEN
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED      = EASY_TYPE \
+                         EASY_DESTRUCTOR \
+                         EASY_METHOD
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each
+# tag file the location of the external documentation should be added. The
+# format of a tag file without this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths
+# or URLs. Note that each tag file must have a unique name (where the name does
+# NOT include the path). If a tag file is not located in the directory in which
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = $(DOCDIR)/$(PROJECT).tag
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/false
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = $(HAVE_DOT)
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS        = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside
+# the class node. If there are many fields or methods and many nodes the
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
+# threshold limits the number of items for each type to make the size more
+# managable. Set this to 0 for no limit. Note that the threshold may be
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG        = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = $(DOT_PATH)
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS           =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP            = YES
diff --git a/CommonAPI-DBus/eclipse-code-style-formatter.xml b/CommonAPI-DBus/eclipse-code-style-formatter.xml
new file mode 100644 (file)
index 0000000..8be3b29
--- /dev/null
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<profiles version="1">
+<profile kind="CodeFormatterProfile" name="C++ Itestra" version="1">
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.lineSplit" value="120"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_member_access" value="0"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_constructor_initializer_list" value="82"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_exception_specification" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_exception_specification" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.comment.min_distance_between_code_and_line_comment" value="1"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.tabulation.size" value="4"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_enumerator_list" value="48"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_declarator_list" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.join_wrapped_lines" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation" value="48"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration" value="82"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.continuation_indentation" value="4"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_expression_list" value="0"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_conditional_expression" value="80"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_access_specifier_extra_spaces" value="0"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer" value="4"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_compact_if" value="0"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_assignment" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_conditional_expression_chain" value="18"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_exception_specification" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration" value="80"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_exception_specification" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_binary_expression" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.tabulation.char" value="space"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_colon_in_constructor_initializer_list" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_overloaded_left_shift_chain" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indentation.size" value="4"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments" value="do not insert"/>
+</profile>
+</profiles>
\ No newline at end of file
diff --git a/CommonAPI-DBus/m4/ax_cxx_compile_stdcxx_11.m4 b/CommonAPI-DBus/m4/ax_cxx_compile_stdcxx_11.m4
new file mode 100644 (file)
index 0000000..0d96c07
--- /dev/null
@@ -0,0 +1,107 @@
+# ============================================================================
+#  http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+#   AX_CXX_COMPILE_STDCXX_11([ext|noext])
+#
+# DESCRIPTION
+#
+#   Check for baseline language coverage in the compiler for the C++11
+#   standard; if necessary, add switches to CXXFLAGS to enable support.
+#   Errors out if no mode that supports C++11 baseline syntax can be found.
+#   The argument, if specified, indicates whether you insist on an extended
+#   mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. -std=c++11).
+#   If neither is specified, you get whatever works, with preference for an
+#   extended mode.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
+#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 1
+
+m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
+  template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+    typedef check<check<bool>> right_angle_brackets;
+
+    int a;
+    decltype(a) b;
+
+    typedef check<int> check_type;
+    check_type c;
+    check_type&& cr = static_cast<check_type&&>(c);
+])
+
+AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
+  m4_if([$1], [], [],
+        [$1], [ext], [],
+        [$1], [noext], [],
+        [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
+  AC_LANG_ASSERT([C++])dnl
+  ac_success=no
+  AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
+  ax_cv_cxx_compile_cxx11,
+  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+    [ax_cv_cxx_compile_cxx11=yes],
+    [ax_cv_cxx_compile_cxx11=no])])
+  if test x$ax_cv_cxx_compile_cxx11 = xyes; then
+    ac_success=yes
+  fi
+
+  m4_if([$1], [noext], [], [dnl
+  if test x$ac_success = xno; then
+    for switch in -std=gnu++11 -std=gnu++0x; do
+      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+      AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+                     $cachevar,
+        [ac_save_CXXFLAGS="$CXXFLAGS"
+         CXXFLAGS="$CXXFLAGS $switch"
+         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+          [eval $cachevar=yes],
+          [eval $cachevar=no])
+         CXXFLAGS="$ac_save_CXXFLAGS"])
+      if eval test x\$$cachevar = xyes; then
+        CXXFLAGS="$CXXFLAGS $switch"
+        ac_success=yes
+        break
+      fi
+    done
+  fi])
+
+  m4_if([$1], [ext], [], [dnl
+  if test x$ac_success = xno; then
+    for switch in -std=c++11 -std=c++0x; do
+      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+      AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+                     $cachevar,
+        [ac_save_CXXFLAGS="$CXXFLAGS"
+         CXXFLAGS="$CXXFLAGS $switch"
+         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+          [eval $cachevar=yes],
+          [eval $cachevar=no])
+         CXXFLAGS="$ac_save_CXXFLAGS"])
+      if eval test x\$$cachevar = xyes; then
+        CXXFLAGS="$CXXFLAGS $switch"
+        ac_success=yes
+        break
+      fi
+    done
+  fi])
+
+  if test x$ac_success = xno; then
+    AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
+  fi
+])
diff --git a/CommonAPI-DBus/m4/ax_prog_doxygen.m4 b/CommonAPI-DBus/m4/ax_prog_doxygen.m4
new file mode 100644 (file)
index 0000000..44b22b0
--- /dev/null
@@ -0,0 +1,532 @@
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_prog_doxygen.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   DX_INIT_DOXYGEN(PROJECT-NAME, DOXYFILE-PATH, [OUTPUT-DIR])
+#   DX_DOXYGEN_FEATURE(ON|OFF)
+#   DX_DOT_FEATURE(ON|OFF)
+#   DX_HTML_FEATURE(ON|OFF)
+#   DX_CHM_FEATURE(ON|OFF)
+#   DX_CHI_FEATURE(ON|OFF)
+#   DX_MAN_FEATURE(ON|OFF)
+#   DX_RTF_FEATURE(ON|OFF)
+#   DX_XML_FEATURE(ON|OFF)
+#   DX_PDF_FEATURE(ON|OFF)
+#   DX_PS_FEATURE(ON|OFF)
+#
+# DESCRIPTION
+#
+#   The DX_*_FEATURE macros control the default setting for the given
+#   Doxygen feature. Supported features are 'DOXYGEN' itself, 'DOT' for
+#   generating graphics, 'HTML' for plain HTML, 'CHM' for compressed HTML
+#   help (for MS users), 'CHI' for generating a seperate .chi file by the
+#   .chm file, and 'MAN', 'RTF', 'XML', 'PDF' and 'PS' for the appropriate
+#   output formats. The environment variable DOXYGEN_PAPER_SIZE may be
+#   specified to override the default 'a4wide' paper size.
+#
+#   By default, HTML, PDF and PS documentation is generated as this seems to
+#   be the most popular and portable combination. MAN pages created by
+#   Doxygen are usually problematic, though by picking an appropriate subset
+#   and doing some massaging they might be better than nothing. CHM and RTF
+#   are specific for MS (note that you can't generate both HTML and CHM at
+#   the same time). The XML is rather useless unless you apply specialized
+#   post-processing to it.
+#
+#   The macros mainly control the default state of the feature. The use can
+#   override the default by specifying --enable or --disable. The macros
+#   ensure that contradictory flags are not given (e.g.,
+#   --enable-doxygen-html and --enable-doxygen-chm,
+#   --enable-doxygen-anything with --disable-doxygen, etc.) Finally, each
+#   feature will be automatically disabled (with a warning) if the required
+#   programs are missing.
+#
+#   Once all the feature defaults have been specified, call DX_INIT_DOXYGEN
+#   with the following parameters: a one-word name for the project for use
+#   as a filename base etc., an optional configuration file name (the
+#   default is 'Doxyfile', the same as Doxygen's default), and an optional
+#   output directory name (the default is 'doxygen-doc').
+#
+#   Automake Support
+#
+#   The following is a template aminclude.am file for use with Automake.
+#   Make targets and variables values are controlled by the various
+#   DX_COND_* conditionals set by autoconf.
+#
+#   The provided targets are:
+#
+#     doxygen-doc: Generate all doxygen documentation.
+#
+#     doxygen-run: Run doxygen, which will generate some of the
+#                  documentation (HTML, CHM, CHI, MAN, RTF, XML)
+#                  but will not do the post processing required
+#                  for the rest of it (PS, PDF, and some MAN).
+#
+#     doxygen-man: Rename some doxygen generated man pages.
+#
+#     doxygen-ps:  Generate doxygen PostScript documentation.
+#
+#     doxygen-pdf: Generate doxygen PDF documentation.
+#
+#   Note that by default these are not integrated into the automake targets.
+#   If doxygen is used to generate man pages, you can achieve this
+#   integration by setting man3_MANS to the list of man pages generated and
+#   then adding the dependency:
+#
+#     $(man3_MANS): doxygen-doc
+#
+#   This will cause make to run doxygen and generate all the documentation.
+#
+#   The following variable is intended for use in Makefile.am:
+#
+#     DX_CLEANFILES = everything to clean.
+#
+#   Then add this variable to MOSTLYCLEANFILES.
+#
+#     ----- begin aminclude.am -------------------------------------
+#
+#     ## --------------------------------- ##
+#     ## Format-independent Doxygen rules. ##
+#     ## --------------------------------- ##
+#
+#     if DX_COND_doc
+#
+#     ## ------------------------------- ##
+#     ## Rules specific for HTML output. ##
+#     ## ------------------------------- ##
+#
+#     if DX_COND_html
+#
+#     DX_CLEAN_HTML = @DX_DOCDIR@/html
+#
+#     endif DX_COND_html
+#
+#     ## ------------------------------ ##
+#     ## Rules specific for CHM output. ##
+#     ## ------------------------------ ##
+#
+#     if DX_COND_chm
+#
+#     DX_CLEAN_CHM = @DX_DOCDIR@/chm
+#
+#     if DX_COND_chi
+#
+#     DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi
+#
+#     endif DX_COND_chi
+#
+#     endif DX_COND_chm
+#
+#     ## ------------------------------ ##
+#     ## Rules specific for MAN output. ##
+#     ## ------------------------------ ##
+#
+#     if DX_COND_man
+#
+#     DX_CLEAN_MAN = @DX_DOCDIR@/man
+#
+#     endif DX_COND_man
+#
+#     ## ------------------------------ ##
+#     ## Rules specific for RTF output. ##
+#     ## ------------------------------ ##
+#
+#     if DX_COND_rtf
+#
+#     DX_CLEAN_RTF = @DX_DOCDIR@/rtf
+#
+#     endif DX_COND_rtf
+#
+#     ## ------------------------------ ##
+#     ## Rules specific for XML output. ##
+#     ## ------------------------------ ##
+#
+#     if DX_COND_xml
+#
+#     DX_CLEAN_XML = @DX_DOCDIR@/xml
+#
+#     endif DX_COND_xml
+#
+#     ## ----------------------------- ##
+#     ## Rules specific for PS output. ##
+#     ## ----------------------------- ##
+#
+#     if DX_COND_ps
+#
+#     DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps
+#
+#     DX_PS_GOAL = doxygen-ps
+#
+#     doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
+#
+#     @DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag
+#         cd @DX_DOCDIR@/latex; \
+#         rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
+#         $(DX_LATEX) refman.tex; \
+#         $(MAKEINDEX_PATH) refman.idx; \
+#         $(DX_LATEX) refman.tex; \
+#         countdown=5; \
+#         while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
+#                           refman.log > /dev/null 2>&1 \
+#            && test $$countdown -gt 0; do \
+#             $(DX_LATEX) refman.tex; \
+#             countdown=`expr $$countdown - 1`; \
+#         done; \
+#         $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
+#
+#     endif DX_COND_ps
+#
+#     ## ------------------------------ ##
+#     ## Rules specific for PDF output. ##
+#     ## ------------------------------ ##
+#
+#     if DX_COND_pdf
+#
+#     DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf
+#
+#     DX_PDF_GOAL = doxygen-pdf
+#
+#     doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf
+#
+#     @DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag
+#         cd @DX_DOCDIR@/latex; \
+#         rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
+#         $(DX_PDFLATEX) refman.tex; \
+#         $(DX_MAKEINDEX) refman.idx; \
+#         $(DX_PDFLATEX) refman.tex; \
+#         countdown=5; \
+#         while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
+#                           refman.log > /dev/null 2>&1 \
+#            && test $$countdown -gt 0; do \
+#             $(DX_PDFLATEX) refman.tex; \
+#             countdown=`expr $$countdown - 1`; \
+#         done; \
+#         mv refman.pdf ../@PACKAGE@.pdf
+#
+#     endif DX_COND_pdf
+#
+#     ## ------------------------------------------------- ##
+#     ## Rules specific for LaTeX (shared for PS and PDF). ##
+#     ## ------------------------------------------------- ##
+#
+#     if DX_COND_latex
+#
+#     DX_CLEAN_LATEX = @DX_DOCDIR@/latex
+#
+#     endif DX_COND_latex
+#
+#     .PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
+#
+#     .INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
+#
+#     doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag
+#
+#     doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
+#
+#     @DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
+#         rm -rf @DX_DOCDIR@
+#         $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
+#
+#     DX_CLEANFILES = \
+#         @DX_DOCDIR@/@PACKAGE@.tag \
+#         -r \
+#         $(DX_CLEAN_HTML) \
+#         $(DX_CLEAN_CHM) \
+#         $(DX_CLEAN_CHI) \
+#         $(DX_CLEAN_MAN) \
+#         $(DX_CLEAN_RTF) \
+#         $(DX_CLEAN_XML) \
+#         $(DX_CLEAN_PS) \
+#         $(DX_CLEAN_PDF) \
+#         $(DX_CLEAN_LATEX)
+#
+#     endif DX_COND_doc
+#
+#     ----- end aminclude.am ---------------------------------------
+#
+# LICENSE
+#
+#   Copyright (c) 2009 Oren Ben-Kiki <oren@ben-kiki.org>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 12
+
+## ----------##
+## Defaults. ##
+## ----------##
+
+DX_ENV=""
+AC_DEFUN([DX_FEATURE_doc],  ON)
+AC_DEFUN([DX_FEATURE_dot],  OFF)
+AC_DEFUN([DX_FEATURE_man],  OFF)
+AC_DEFUN([DX_FEATURE_html], ON)
+AC_DEFUN([DX_FEATURE_chm],  OFF)
+AC_DEFUN([DX_FEATURE_chi],  OFF)
+AC_DEFUN([DX_FEATURE_rtf],  OFF)
+AC_DEFUN([DX_FEATURE_xml],  OFF)
+AC_DEFUN([DX_FEATURE_pdf],  ON)
+AC_DEFUN([DX_FEATURE_ps],   ON)
+
+## --------------- ##
+## Private macros. ##
+## --------------- ##
+
+# DX_ENV_APPEND(VARIABLE, VALUE)
+# ------------------------------
+# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
+AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
+
+# DX_DIRNAME_EXPR
+# ---------------
+# Expand into a shell expression prints the directory part of a path.
+AC_DEFUN([DX_DIRNAME_EXPR],
+         [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
+
+# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
+# -------------------------------------
+# Expands according to the M4 (static) status of the feature.
+AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
+
+# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
+# ----------------------------------
+# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
+AC_DEFUN([DX_REQUIRE_PROG], [
+AC_PATH_TOOL([$1], [$2])
+if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then
+    AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
+    AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)
+fi
+])
+
+# DX_TEST_FEATURE(FEATURE)
+# ------------------------
+# Expand to a shell expression testing whether the feature is active.
+AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
+
+# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
+# -------------------------------------------------
+# Verify that a required features has the right state before trying to turn on
+# the DX_CURRENT_FEATURE.
+AC_DEFUN([DX_CHECK_DEPEND], [
+test "$DX_FLAG_$1" = "$2" \
+|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
+                            requires, contradicts) doxygen-DX_CURRENT_FEATURE])
+])
+
+# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
+# ----------------------------------------------------------
+# Turn off the DX_CURRENT_FEATURE if the required feature is off.
+AC_DEFUN([DX_CLEAR_DEPEND], [
+test "$DX_FLAG_$1" = "$2" || AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)
+])
+
+# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
+#                CHECK_DEPEND, CLEAR_DEPEND,
+#                REQUIRE, DO-IF-ON, DO-IF-OFF)
+# --------------------------------------------
+# Parse the command-line option controlling a feature. CHECK_DEPEND is called
+# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
+# otherwise CLEAR_DEPEND is called to turn off the default state if a required
+# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
+# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
+# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
+AC_DEFUN([DX_ARG_ABLE], [
+    AC_DEFUN([DX_CURRENT_FEATURE], [$1])
+    AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
+    AC_ARG_ENABLE(doxygen-$1,
+                  [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
+                                                      [--enable-doxygen-$1]),
+                                  DX_IF_FEATURE([$1], [don't $2], [$2]))],
+                  [
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    AC_SUBST([DX_FLAG_$1], 1)
+    $3
+;; #(
+n|N|no|No|NO)
+    AC_SUBST([DX_FLAG_$1], 0)
+;; #(
+*)
+    AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
+;;
+esac
+], [
+AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
+$4
+])
+if DX_TEST_FEATURE([$1]); then
+    $5
+    :
+fi
+AM_CONDITIONAL(DX_COND_$1, DX_TEST_FEATURE([$1]))
+if DX_TEST_FEATURE([$1]); then
+    $6
+    :
+else
+    $7
+    :
+fi
+])
+
+## -------------- ##
+## Public macros. ##
+## -------------- ##
+
+# DX_XXX_FEATURE(DEFAULT_STATE)
+# -----------------------------
+AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc],  [$1])])
+AC_DEFUN([DX_DOT_FEATURE],     [AC_DEFUN([DX_FEATURE_dot], [$1])])
+AC_DEFUN([DX_MAN_FEATURE],     [AC_DEFUN([DX_FEATURE_man],  [$1])])
+AC_DEFUN([DX_HTML_FEATURE],    [AC_DEFUN([DX_FEATURE_html], [$1])])
+AC_DEFUN([DX_CHM_FEATURE],     [AC_DEFUN([DX_FEATURE_chm],  [$1])])
+AC_DEFUN([DX_CHI_FEATURE],     [AC_DEFUN([DX_FEATURE_chi],  [$1])])
+AC_DEFUN([DX_RTF_FEATURE],     [AC_DEFUN([DX_FEATURE_rtf],  [$1])])
+AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
+AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
+AC_DEFUN([DX_PDF_FEATURE],     [AC_DEFUN([DX_FEATURE_pdf],  [$1])])
+AC_DEFUN([DX_PS_FEATURE],      [AC_DEFUN([DX_FEATURE_ps],   [$1])])
+
+# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
+# ---------------------------------------------------------
+# PROJECT also serves as the base name for the documentation files.
+# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
+AC_DEFUN([DX_INIT_DOXYGEN], [
+
+# Files:
+AC_SUBST([DX_PROJECT], [$1])
+AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
+AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
+
+# Environment variables used inside doxygen.cfg:
+DX_ENV_APPEND(SRCDIR, $srcdir)
+DX_ENV_APPEND(PROJECT, $DX_PROJECT)
+DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
+DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
+
+# Doxygen itself:
+DX_ARG_ABLE(doc, [generate any doxygen documentation],
+            [],
+            [],
+            [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
+             DX_REQUIRE_PROG([DX_PERL], perl)],
+            [DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
+
+# Dot for graphics:
+DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_DOT], dot)],
+            [DX_ENV_APPEND(HAVE_DOT, YES)
+             DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
+            [DX_ENV_APPEND(HAVE_DOT, NO)])
+
+# Man pages generation:
+DX_ARG_ABLE(man, [generate doxygen manual pages],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_MAN, YES)],
+            [DX_ENV_APPEND(GENERATE_MAN, NO)])
+
+# RTF file generation:
+DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_RTF, YES)],
+            [DX_ENV_APPEND(GENERATE_RTF, NO)])
+
+# XML file generation:
+DX_ARG_ABLE(xml, [generate doxygen XML documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_XML, YES)],
+            [DX_ENV_APPEND(GENERATE_XML, NO)])
+
+# (Compressed) HTML help generation:
+DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_HHC], hhc)],
+            [DX_ENV_APPEND(HHC_PATH, $DX_HHC)
+             DX_ENV_APPEND(GENERATE_HTML, YES)
+             DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
+            [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
+
+# Seperate CHI file generation.
+DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],
+            [DX_CHECK_DEPEND(chm, 1)],
+            [DX_CLEAR_DEPEND(chm, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_CHI, YES)],
+            [DX_ENV_APPEND(GENERATE_CHI, NO)])
+
+# Plain HTML pages generation:
+DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
+            [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
+            [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
+            [],
+            [DX_ENV_APPEND(GENERATE_HTML, YES)],
+            [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
+
+# PostScript file generation:
+DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_LATEX], latex)
+             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
+             DX_REQUIRE_PROG([DX_DVIPS], dvips)
+             DX_REQUIRE_PROG([DX_EGREP], egrep)])
+
+# PDF file generation:
+DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
+             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
+             DX_REQUIRE_PROG([DX_EGREP], egrep)])
+
+# LaTeX generation for PS and/or PDF:
+AM_CONDITIONAL(DX_COND_latex, DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf))
+if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
+    DX_ENV_APPEND(GENERATE_LATEX, YES)
+else
+    DX_ENV_APPEND(GENERATE_LATEX, NO)
+fi
+
+# Paper size for PS and/or PDF:
+AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
+           [a4wide (default), a4, letter, legal or executive])
+case "$DOXYGEN_PAPER_SIZE" in
+#(
+"")
+    AC_SUBST(DOXYGEN_PAPER_SIZE, "")
+;; #(
+a4wide|a4|letter|legal|executive)
+    DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
+;; #(
+*)
+    AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
+;;
+esac
+
+#For debugging:
+#echo DX_FLAG_doc=$DX_FLAG_doc
+#echo DX_FLAG_dot=$DX_FLAG_dot
+#echo DX_FLAG_man=$DX_FLAG_man
+#echo DX_FLAG_html=$DX_FLAG_html
+#echo DX_FLAG_chm=$DX_FLAG_chm
+#echo DX_FLAG_chi=$DX_FLAG_chi
+#echo DX_FLAG_rtf=$DX_FLAG_rtf
+#echo DX_FLAG_xml=$DX_FLAG_xml
+#echo DX_FLAG_pdf=$DX_FLAG_pdf
+#echo DX_FLAG_ps=$DX_FLAG_ps
+#echo DX_ENV=$DX_ENV
+])
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusAttribute.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusAttribute.h
new file mode 100644 (file)
index 0000000..9ffa400
--- /dev/null
@@ -0,0 +1,114 @@
+/* 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_DBUS_DBUS_ATTRIBUTE_H_
+#define COMMONAPI_DBUS_DBUS_ATTRIBUTE_H_
+
+#include "DBusProxyHelper.h"
+#include "DBusEvent.h"
+
+#include <cassert>
+
+namespace CommonAPI {
+namespace DBus {
+
+
+class DBusProxy;
+
+
+template <typename _AttributeType, typename _DBusProxyType = DBusProxy>
+class DBusReadonlyAttribute: public _AttributeType {
+ public:
+       typedef typename _AttributeType::ValueType ValueType;
+       typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback;
+
+       DBusReadonlyAttribute(_DBusProxyType& dbusProxy, const char* getMethodName):
+                       dbusProxy_(dbusProxy),
+                       getMethodName_(getMethodName) {
+               assert(getMethodName);
+       }
+
+       CallStatus getValue(ValueType& value) const {
+               CallStatus callStatus;
+               DBusProxyHelper<DBusSerializableArguments<>,
+                                               DBusSerializableArguments<ValueType> >::callMethodWithReply(dbusProxy_, getMethodName_, "", callStatus, value);
+               return callStatus;
+       }
+
+       std::future<CallStatus> getValueAsync(AttributeAsyncCallback attributeAsyncCallback) {
+               return DBusProxyHelper<DBusSerializableArguments<>,
+                                                          DBusSerializableArguments<ValueType> >::callMethodAsync(dbusProxy_, getMethodName_, "", std::move(attributeAsyncCallback));
+       }
+
+ protected:
+       _DBusProxyType& dbusProxy_;
+       const char* getMethodName_;
+};
+
+
+template <typename _AttributeType, typename _DBusProxyType = DBusProxy>
+class DBusAttribute: public DBusReadonlyAttribute<_AttributeType> {
+ public:
+       typedef typename _AttributeType::ValueType ValueType;
+       typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback;
+
+       DBusAttribute(_DBusProxyType& dbusProxy, const char* setMethodName, const char* setMethodSignature, const char* getMethodName):
+               DBusReadonlyAttribute<_AttributeType>(dbusProxy, getMethodName),
+                       setMethodName_(setMethodName),
+                       setMethodSignature_(setMethodSignature) {
+               assert(setMethodName);
+               assert(setMethodSignature);
+       }
+
+       void setValue(const ValueType& requestValue, CallStatus& callStatus, ValueType& responseValue) {
+               DBusProxyHelper<DBusSerializableArguments<ValueType>,
+                                               DBusSerializableArguments<ValueType> >::callMethodWithReply(
+                                                               this->dbusProxy_,
+                                                               setMethodName_,
+                                                               setMethodSignature_,
+                                                               requestValue,
+                                                               callStatus,
+                                                               responseValue);
+       }
+
+       std::future<CallStatus> setValueAsync(const ValueType& requestValue, AttributeAsyncCallback attributeAsyncCallback) {
+               return DBusProxyHelper<DBusSerializableArguments<ValueType>,
+                                                          DBusSerializableArguments<ValueType> >::callMethodAsync(
+                                                                          this->dbusProxy_,
+                                                                          setMethodName_,
+                                                                          setMethodSignature_,
+                                                                          requestValue,
+                                                                          attributeAsyncCallback);
+       }
+
+ protected:
+       const char* setMethodName_;
+       const char* setMethodSignature_;
+};
+
+
+template <typename _AttributeType, typename _DBusProxyType = DBusProxy>
+class DBusObservableAttribute: public _AttributeType {
+ public:
+       typedef typename _AttributeType::ValueType ValueType;
+       typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback;
+       typedef typename _AttributeType::ChangedEvent ChangedEvent;
+
+       template <typename... _AttributeTypeArguments>
+       DBusObservableAttribute(_DBusProxyType& dbusProxy, const char* changedEventName, _AttributeTypeArguments... arguments):
+               _AttributeType(dbusProxy, arguments...),
+               changedEvent_(dbusProxy, changedEventName, this->setMethodSignature_) {
+       }
+
+       ChangedEvent& getChangedEvent() {
+               return changedEvent_;
+       }
+
+ protected:
+       DBusEvent<ChangedEvent> changedEvent_;
+};
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_ATTRIBUTE_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusConnection.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusConnection.cpp
new file mode 100644 (file)
index 0000000..f94df52
--- /dev/null
@@ -0,0 +1,553 @@
+/* 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 "DBusConnection.h"
+#include "DBusInputStream.h"
+
+#include <sstream>
+#include <cassert>
+#include <future>
+
+#include <iostream>
+
+namespace CommonAPI {
+namespace DBus {
+
+
+DBusObjectPathVTable DBusConnection::libdbusObjectPathVTable_ = {
+                NULL, // no need to handle unregister callbacks
+                &DBusConnection::onLibdbusObjectPathMessageThunk
+};
+
+void DBusConnection::dispatch() {
+    while (!stopDispatching_ && readWriteDispatch(10)) {
+    }
+}
+
+DBusConnection::DBusConnection(BusType busType) :
+                busType_(busType),
+                libdbusConnection_(NULL),
+                isLibdbusSignalFilterAdded_(false),
+                stopDispatching_(false) {
+    dbus_threads_init_default();
+}
+
+DBusConnection::DBusConnection(::DBusConnection* libDbusConnection) :
+                busType_(WRAPPED),
+                libdbusConnection_(libDbusConnection),
+                isLibdbusSignalFilterAdded_(false),
+                stopDispatching_(false)  {
+    dbus_threads_init_default();
+}
+
+DBusConnection::~DBusConnection() {
+    if (isConnected()) {
+        disconnect();
+    }
+    dispatchThread_.join();
+}
+
+bool DBusConnection::connect() {
+    DBusError dbusError;
+    return connect(dbusError);
+}
+
+bool DBusConnection::connect(DBusError& dbusError) {
+    assert(!dbusError);
+
+    if (isConnected())
+        return true;
+
+    const ::DBusBusType libdbusType = static_cast<DBusBusType>(busType_);
+
+    libdbusConnection_ = dbus_bus_get_private(libdbusType, &dbusError.libdbusError_);
+    if (dbusError)
+        return false;
+
+    assert(libdbusConnection_);
+    dbus_connection_set_exit_on_disconnect(libdbusConnection_, false);
+
+    dbusConnectionStatusEvent_.notifyListeners(AvailabilityStatus::AVAILABLE);
+
+    initLibdbusObjectPathHandlerAfterConnect();
+
+    initLibdbusSignalFilterAfterConnect();
+
+    dispatchThread_ = std::thread(std::bind(&DBusConnection::dispatch, this));
+
+    return true;
+}
+
+void DBusConnection::disconnect() {
+    if (isConnected()) {
+        stopDispatching_ = true;
+        if (!dbusSignalMatchRulesMap_.empty()) {
+            dbus_connection_remove_filter(libdbusConnection_, &onLibdbusSignalFilterThunk, this);
+        }
+
+        dbus_connection_close(libdbusConnection_);
+        dbus_connection_unref(libdbusConnection_);
+        libdbusConnection_ = NULL;
+
+        dbusConnectionStatusEvent_.notifyListeners(AvailabilityStatus::NOT_AVAILABLE);
+    }
+}
+
+bool DBusConnection::isConnected() const {
+    return (libdbusConnection_ != NULL);
+}
+
+DBusConnectionStatusEvent& DBusConnection::getConnectionStatusEvent() {
+    return dbusConnectionStatusEvent_;
+}
+
+const std::shared_ptr<DBusServiceRegistry>& DBusConnection::getDBusServiceRegistry() {
+    if (!dbusServiceRegistry_) {
+        dbusServiceRegistry_ = std::make_shared<DBusServiceRegistry>(this->shared_from_this());
+    }
+
+    return dbusServiceRegistry_;
+}
+
+const std::shared_ptr<DBusDaemonProxy>& DBusConnection::getDBusDaemonProxy() {
+    if (!dbusDaemonProxy_) {
+        dbusDaemonProxy_ = std::make_shared<DBusDaemonProxy>(this->shared_from_this());
+    }
+
+    return dbusDaemonProxy_;
+}
+
+const std::shared_ptr<DBusObjectManager>& DBusConnection::getDBusObjectManager() {
+    if (!dbusObjectManager_) {
+        dbusObjectManager_ = std::make_shared<DBusObjectManager>(this->shared_from_this());
+    }
+
+    return dbusObjectManager_;
+}
+
+bool DBusConnection::requestServiceNameAndBlock(const std::string& serviceName) const {
+    DBusError dbusError;
+    const int libdbusStatus = dbus_bus_request_name(libdbusConnection_,
+                                                    serviceName.c_str(),
+                                                    DBUS_NAME_FLAG_DO_NOT_QUEUE,
+                                                    &dbusError.libdbusError_);
+    const bool isServiceNameAcquired = (libdbusStatus == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
+
+    return isServiceNameAcquired;
+}
+
+bool DBusConnection::releaseServiceName(const std::string& serviceName) const {
+    DBusError dbusError;
+    const int libdbusStatus = dbus_bus_release_name(libdbusConnection_,
+                                                    serviceName.c_str(),
+                                                    &dbusError.libdbusError_);
+    const bool isServiceNameReleased = (libdbusStatus == DBUS_RELEASE_NAME_REPLY_RELEASED);
+
+    return isServiceNameReleased;
+}
+
+bool DBusConnection::sendDBusMessage(const DBusMessage& dbusMessage, uint32_t* allocatedSerial) const {
+    assert(dbusMessage);
+    assert(isConnected());
+
+    dbus_uint32_t* libdbusSerial = static_cast<dbus_uint32_t*>(allocatedSerial);
+    const bool result = dbus_connection_send(libdbusConnection_, dbusMessage.libdbusMessage_, libdbusSerial);
+
+    return result;
+}
+
+void DBusConnection::onLibdbusPendingCallNotifyThunk(::DBusPendingCall* libdbusPendingCall, void *userData) {
+       assert(userData);
+       assert(libdbusPendingCall);
+
+       auto dbusMessageReplyAsyncHandler = reinterpret_cast<DBusMessageReplyAsyncHandler*>(userData);
+
+       ::DBusMessage* libdbusMessage = dbus_pending_call_steal_reply(
+                       libdbusPendingCall);
+       const bool increaseLibdbusMessageReferenceCount = false;
+       DBusMessage dbusMessage(libdbusMessage, increaseLibdbusMessageReferenceCount);
+
+       dbusMessageReplyAsyncHandler->onDBusMessageReply(CallStatus::SUCCESS, dbusMessage);
+
+       // libdbus calls the Cleanup method below
+       dbus_pending_call_unref(libdbusPendingCall);
+}
+
+void DBusConnection::onLibdbusDataCleanup(void* userData) {
+       auto dbusMessageReplyAsyncHandler = reinterpret_cast<DBusMessageReplyAsyncHandler*>(userData);
+       delete dbusMessageReplyAsyncHandler;
+}
+
+std::future<CallStatus> DBusConnection::sendDBusMessageWithReplyAsync(
+               const DBusMessage& dbusMessage,
+               std::unique_ptr<DBusMessageReplyAsyncHandler> dbusMessageReplyAsyncHandler,
+               int timeoutMilliseconds) const {
+
+    assert(dbusMessage);
+    assert(isConnected());
+
+    DBusPendingCall* libdbusPendingCall;
+    dbus_bool_t libdbusSuccess;
+
+    libdbusSuccess = dbus_connection_send_with_reply(
+                    libdbusConnection_,
+                    dbusMessage.libdbusMessage_,
+                    &libdbusPendingCall,
+                    timeoutMilliseconds);
+
+    if (!libdbusSuccess || !libdbusPendingCall) {
+       dbusMessageReplyAsyncHandler->onDBusMessageReply(CallStatus::CONNECTION_FAILED, dbusMessage);
+        return dbusMessageReplyAsyncHandler->getFuture();
+    }
+
+    libdbusSuccess = dbus_pending_call_set_notify(
+                    libdbusPendingCall,
+                    onLibdbusPendingCallNotifyThunk,
+                    dbusMessageReplyAsyncHandler.get(),
+                    onLibdbusDataCleanup);
+
+    if (!libdbusSuccess) {
+       dbusMessageReplyAsyncHandler->onDBusMessageReply(CallStatus::OUT_OF_MEMORY, dbusMessage);
+        dbus_pending_call_unref(libdbusPendingCall);
+        return dbusMessageReplyAsyncHandler->getFuture();
+    }
+
+    return dbusMessageReplyAsyncHandler.release()->getFuture();
+}
+
+
+DBusMessage DBusConnection::sendDBusMessageWithReplyAndBlock(const DBusMessage& dbusMessage,
+                                                             DBusError& dbusError,
+                                                             int timeoutMilliseconds) const {
+    assert(dbusMessage);
+    assert(!dbusError);
+    assert(isConnected());
+
+    ::DBusMessage* libdbusMessageReply = dbus_connection_send_with_reply_and_block(libdbusConnection_,
+                                                                                   dbusMessage.libdbusMessage_,
+                                                                                   timeoutMilliseconds,
+                                                                                   &dbusError.libdbusError_);
+    if (dbusError)
+        return DBusMessage();
+
+    const bool increaseLibdbusMessageReferenceCount = false;
+    return DBusMessage(libdbusMessageReply, increaseLibdbusMessageReferenceCount);
+}
+
+
+bool DBusConnection::readWriteDispatch(int timeoutMilliseconds) {
+    if(isConnected()) {
+        const dbus_bool_t libdbusSuccess = dbus_connection_read_write_dispatch(libdbusConnection_,
+                                                                               timeoutMilliseconds);
+        return libdbusSuccess;
+    }
+    return false;
+}
+
+DBusProxyConnection::DBusSignalHandlerToken DBusConnection::addSignalMemberHandler(const std::string& objectPath,
+                                                                                   const std::string& interfaceName,
+                                                                                   const std::string& interfaceMemberName,
+                                                                                   const std::string& interfaceMemberSignature,
+                                                                                   DBusSignalHandler* dbusSignalHandler) {
+    DBusSignalHandlerPath dbusSignalHandlerPath(
+                    objectPath,
+                    interfaceName,
+                    interfaceMemberName,
+                    interfaceMemberSignature);
+    const bool isFirstSignalMemberHandler = dbusSignalHandlerTable_.find(dbusSignalHandlerPath) == dbusSignalHandlerTable_.end();
+
+    dbusSignalHandlerTable_.insert(DBusSignalHandlerTable::value_type(dbusSignalHandlerPath, dbusSignalHandler));
+
+    if (isFirstSignalMemberHandler)
+        addLibdbusSignalMatchRule(objectPath, interfaceName, interfaceMemberName);
+
+    return dbusSignalHandlerPath;
+}
+
+void DBusConnection::removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken) {
+    auto equalRangeIteratorPair = dbusSignalHandlerTable_.equal_range(dbusSignalHandlerToken);
+
+    // the range can't be empty!
+    assert(equalRangeIteratorPair.first != equalRangeIteratorPair.second);
+
+    // advance to the next element
+    equalRangeIteratorPair.first++;
+
+    // check if the first element was the only element
+    const bool isLastSignalMemberHandler = equalRangeIteratorPair.first == equalRangeIteratorPair.second;
+
+    if (isLastSignalMemberHandler) {
+        const std::string& objectPath = std::get<0>(dbusSignalHandlerToken);
+        const std::string& interfaceName = std::get<1>(dbusSignalHandlerToken);
+        const std::string& interfaceMemberName = std::get<2>(dbusSignalHandlerToken);
+
+        removeLibdbusSignalMatchRule(objectPath, interfaceName, interfaceMemberName);
+    }
+
+    dbusSignalHandlerTable_.erase(dbusSignalHandlerToken);
+}
+
+void DBusConnection::registerObjectPath(const std::string& objectPath) {
+    assert(!objectPath.empty());
+    assert(objectPath[0] == '/');
+
+    auto handlerIterator = libdbusRegisteredObjectPaths_.find(objectPath);
+    const bool foundRegisteredObjectPathHandler = handlerIterator != libdbusRegisteredObjectPaths_.end();
+
+    if (foundRegisteredObjectPathHandler) {
+        uint32_t& referenceCount = handlerIterator->second;
+
+        referenceCount++;
+
+        return;
+    }
+
+    libdbusRegisteredObjectPaths_.insert(LibdbusRegisteredObjectPathHandlersTable::value_type(objectPath, 1));
+
+    if (isConnected()) {
+        DBusError dbusError;
+        const dbus_bool_t libdbusSuccess = dbus_connection_try_register_object_path(libdbusConnection_,
+                                                                                    objectPath.c_str(),
+                                                                                    &libdbusObjectPathVTable_,
+                                                                                    this,
+                                                                                    &dbusError.libdbusError_);
+        assert(libdbusSuccess);
+        assert(!dbusError);
+    }
+}
+
+void DBusConnection::unregisterObjectPath(const std::string& objectPath) {
+    assert(!objectPath.empty());
+    assert(objectPath[0] == '/');
+
+    auto handlerIterator = libdbusRegisteredObjectPaths_.find(objectPath);
+    const bool foundRegisteredObjectPathHandler = handlerIterator != libdbusRegisteredObjectPaths_.end();
+
+    assert(foundRegisteredObjectPathHandler);
+
+    uint32_t& referenceCount = handlerIterator->second;
+    if (referenceCount > 1) {
+        referenceCount--;
+        return;
+    }
+
+    libdbusRegisteredObjectPaths_.erase(handlerIterator);
+
+    if (isConnected()) {
+        dbus_bool_t libdbusSuccess = dbus_connection_unregister_object_path(libdbusConnection_,
+                                                                            objectPath.c_str());
+        assert(libdbusSuccess);
+    }
+}
+
+void DBusConnection::addLibdbusSignalMatchRule(const std::string& objectPath,
+                                               const std::string& interfaceName,
+                                               const std::string& interfaceMemberName) {
+    DBusSignalMatchRuleTuple dbusSignalMatchRuleTuple(objectPath, interfaceName, interfaceMemberName);
+    auto matchRuleIterator = dbusSignalMatchRulesMap_.find(dbusSignalMatchRuleTuple);
+    const bool matchRuleFound = matchRuleIterator != dbusSignalMatchRulesMap_.end();
+
+    if (matchRuleFound) {
+        uint32_t& matchRuleReferenceCount = matchRuleIterator->second.first;
+        matchRuleReferenceCount++;
+        return;
+    }
+
+    const bool isFirstMatchRule = dbusSignalMatchRulesMap_.empty();
+
+    // generate D-Bus match rule string
+    std::ostringstream matchRuleStringStream;
+
+    matchRuleStringStream << "type='signal'";
+    matchRuleStringStream << ",path='" << objectPath << "'";
+    matchRuleStringStream << ",interface='" << interfaceName << "'";
+    matchRuleStringStream << ",member='" << interfaceMemberName << "'";
+
+    // add the match rule string to the map with reference count set to 1
+    std::string matchRuleString = matchRuleStringStream.str();
+    auto success = dbusSignalMatchRulesMap_.insert(
+                    DBusSignalMatchRulesMap::value_type(dbusSignalMatchRuleTuple,
+                                                        DBusSignalMatchRuleMapping(1, matchRuleString)));
+    assert(success.second);
+
+    // if not connected the filter and the rules will be added as soon as the connection is established
+    if (isConnected()) {
+        // add the libdbus message signal filter
+        if (isFirstMatchRule) {
+            const dbus_bool_t libdbusSuccess = dbus_connection_add_filter(libdbusConnection_,
+                                                                          &onLibdbusSignalFilterThunk,
+                                                                          this,
+                                                                          NULL);
+            assert(libdbusSuccess);
+        }
+
+        // finally add the match rule
+        DBusError dbusError;
+        dbus_bus_add_match(libdbusConnection_, matchRuleString.c_str(), &dbusError.libdbusError_);
+        assert(!dbusError);
+    }
+}
+
+void DBusConnection::removeLibdbusSignalMatchRule(const std::string& objectPath,
+                                                  const std::string& interfaceName,
+                                                  const std::string& interfaceMemberName) {
+    DBusSignalMatchRuleTuple dbusSignalMatchRuleTuple(objectPath, interfaceName, interfaceMemberName);
+    auto matchRuleIterator = dbusSignalMatchRulesMap_.find(dbusSignalMatchRuleTuple);
+    const bool matchRuleFound = matchRuleIterator != dbusSignalMatchRulesMap_.end();
+
+    assert(matchRuleFound);
+
+    uint32_t& matchRuleReferenceCount = matchRuleIterator->second.first;
+    if (matchRuleReferenceCount > 1) {
+        matchRuleReferenceCount--;
+        return;
+    }
+
+    const std::string& matchRuleString = matchRuleIterator->second.second;
+    DBusError dbusError;
+    dbus_bus_remove_match(libdbusConnection_, matchRuleString.c_str(), &dbusError.libdbusError_);
+    assert(!dbusError);
+
+    dbusSignalMatchRulesMap_.erase(matchRuleIterator);
+
+    const bool isLastMatchRule = dbusSignalMatchRulesMap_.empty();
+    if (isLastMatchRule)
+        dbus_connection_remove_filter(libdbusConnection_, &onLibdbusSignalFilterThunk, this);
+}
+
+void DBusConnection::initLibdbusObjectPathHandlerAfterConnect() {
+    assert(isConnected());
+
+    // nothing to do if there aren't any registered object path handlers
+    if (libdbusRegisteredObjectPaths_.empty())
+        return;
+
+    DBusError dbusError;
+    dbus_bool_t libdbusSuccess;
+
+    for (    auto handlerIterator = libdbusRegisteredObjectPaths_.begin();
+             handlerIterator != libdbusRegisteredObjectPaths_.end();
+             handlerIterator++) {
+        const std::string& objectPath = handlerIterator->first;
+
+        dbusError.clear();
+
+        libdbusSuccess = dbus_connection_try_register_object_path(libdbusConnection_,
+                                                                  objectPath.c_str(),
+                                                                  &libdbusObjectPathVTable_,
+                                                                  this,
+                                                                  &dbusError.libdbusError_);
+        assert(libdbusSuccess);
+        assert(!dbusError);
+    }
+}
+
+void DBusConnection::initLibdbusSignalFilterAfterConnect() {
+    assert(isConnected());
+
+    // nothing to do if there aren't any signal match rules
+    if (dbusSignalMatchRulesMap_.empty())
+        return;
+
+    // first we add the libdbus message signal filter
+    const dbus_bool_t libdbusSuccess = dbus_connection_add_filter(libdbusConnection_,
+                                                                  &onLibdbusSignalFilterThunk,
+                                                                  this,
+                                                                  NULL);
+    assert(libdbusSuccess);
+
+    // then we upload all match rules to the dbus-daemon
+    DBusError dbusError;
+    for (auto iterator = dbusSignalMatchRulesMap_.begin(); iterator != dbusSignalMatchRulesMap_.end(); iterator++) {
+        const std::string& matchRuleString = iterator->second.second;
+
+        dbusError.clear();
+        dbus_bus_add_match(libdbusConnection_, matchRuleString.c_str(), &dbusError.libdbusError_);
+        assert(!dbusError);
+    }
+}
+
+::DBusHandlerResult DBusConnection::onLibdbusObjectPathMessage(::DBusMessage* libdbusMessage) const {
+    assert(libdbusMessage);
+
+    // handle only method call messages
+    if (dbus_message_get_type(libdbusMessage) != DBUS_MESSAGE_TYPE_METHOD_CALL) {
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    }
+
+    bool isDBusMessageHandled = dbusObjectManager_->handleMessage(DBusMessage(libdbusMessage));
+    return isDBusMessageHandled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+::DBusHandlerResult DBusConnection::onLibdbusSignalFilter(::DBusMessage* libdbusMessage) {
+    assert(libdbusMessage);
+
+    // handle only signal messages
+    if (dbus_message_get_type(libdbusMessage) != DBUS_MESSAGE_TYPE_SIGNAL)
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    const char* objectPath = dbus_message_get_path(libdbusMessage);
+    const char* interfaceName = dbus_message_get_interface(libdbusMessage);
+    const char* interfaceMemberName = dbus_message_get_member(libdbusMessage);
+    const char* interfaceMemberSignature = dbus_message_get_signature(libdbusMessage);
+
+    assert(objectPath);
+    assert(interfaceName);
+    assert(interfaceMemberName);
+    assert(interfaceMemberSignature);
+
+    DBusSignalHandlerPath dbusSignalHandlerPath(objectPath, interfaceName, interfaceMemberName, interfaceMemberSignature);
+    auto equalRangeIteratorPair = dbusSignalHandlerTable_.equal_range(dbusSignalHandlerPath);
+
+    if (equalRangeIteratorPair.first != equalRangeIteratorPair.second) {
+        DBusMessage dbusMessage(libdbusMessage);
+
+        while (equalRangeIteratorPair.first != equalRangeIteratorPair.second) {
+            DBusSignalHandler* dbusSignalHandler = equalRangeIteratorPair.first->second;
+            const SubscriptionStatus dbusSignalHandlerSubscriptionStatus = dbusSignalHandler->onSignalDBusMessage(dbusMessage);
+
+            if (dbusSignalHandlerSubscriptionStatus == SubscriptionStatus::CANCEL) {
+               auto dbusSignalHandlerSubscription = equalRangeIteratorPair.first;
+               equalRangeIteratorPair.first++;
+               dbusSignalHandlerTable_.erase(dbusSignalHandlerSubscription);
+            } else
+               equalRangeIteratorPair.first++;
+        }
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+    }
+
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+::DBusHandlerResult DBusConnection::onLibdbusSignalFilterThunk(::DBusConnection* libdbusConnection,
+                                                               ::DBusMessage* libdbusMessage,
+                                                               void* userData) {
+    assert(libdbusConnection);
+    assert(libdbusMessage);
+    assert(userData);
+
+    DBusConnection* dbusConnection = reinterpret_cast<DBusConnection*>(userData);
+
+    assert(dbusConnection->libdbusConnection_ == libdbusConnection);
+
+    return dbusConnection->onLibdbusSignalFilter(libdbusMessage);
+}
+
+::DBusHandlerResult DBusConnection::onLibdbusObjectPathMessageThunk(::DBusConnection* libdbusConnection,
+                                                                    ::DBusMessage* libdbusMessage,
+                                                                    void* userData) {
+    assert(libdbusConnection);
+    assert(libdbusMessage);
+    assert(userData);
+
+    const DBusConnection* dbusConnection = reinterpret_cast<DBusConnection*>(userData);
+
+    assert(dbusConnection->libdbusConnection_ == libdbusConnection);
+
+    return dbusConnection->onLibdbusObjectPathMessage(libdbusMessage);
+}
+
+} // namespace DBus
+} // namespace CommonAPI
+
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusConnection.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusConnection.h
new file mode 100644 (file)
index 0000000..1d397c6
--- /dev/null
@@ -0,0 +1,175 @@
+/* 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_DBUS_DBUS_CONNECTION_H_
+#define COMMONAPI_DBUS_DBUS_CONNECTION_H_
+
+#include "DBusProxyConnection.h"
+#include "DBusDaemonProxy.h"
+#include "DBusServiceRegistry.h"
+#include "DBusObjectManager.h"
+
+#include <dbus/dbus.h>
+
+
+namespace CommonAPI {
+namespace DBus {
+
+class DBusConnection;
+class DBusObjectManager;
+
+class DBusConnectionStatusEvent: public Event<AvailabilityStatus> {
+    friend class DBusConnection;
+};
+
+
+class DBusConnection: public DBusProxyConnection, public std::enable_shared_from_this<DBusConnection> {
+ public:
+       enum BusType {
+               SESSION = DBUS_BUS_SESSION,
+               SYSTEM = DBUS_BUS_SYSTEM,
+               STARTER = DBUS_BUS_STARTER,
+               WRAPPED
+       };
+
+       inline static std::shared_ptr<DBusConnection> getBus(const BusType& busType);
+       inline static std::shared_ptr<DBusConnection> wrapLibDBus(::DBusConnection* libDbusConnection);
+       inline static std::shared_ptr<DBusConnection> getSessionBus();
+       inline static std::shared_ptr<DBusConnection> getSystemBus();
+       inline static std::shared_ptr<DBusConnection> getStarterBus();
+
+       DBusConnection(const DBusConnection&) = delete;
+       DBusConnection(::DBusConnection* libDbusConnection);
+
+       DBusConnection& operator=(const DBusConnection&) = delete;
+       virtual ~DBusConnection();
+
+       BusType getBusType() const;
+
+       bool connect();
+       bool connect(DBusError& dbusError);
+       void disconnect();
+
+       virtual bool isConnected() const;
+
+       virtual DBusConnectionStatusEvent& getConnectionStatusEvent();
+
+       virtual bool requestServiceNameAndBlock(const std::string& serviceName) const;
+       virtual bool releaseServiceName(const std::string& serviceName) const;
+
+       bool sendDBusMessage(const DBusMessage& dbusMessage, uint32_t* allocatedSerial = NULL) const;
+
+       static const int kDefaultSendTimeoutMs = 100 * 1000;
+
+       std::future<CallStatus> sendDBusMessageWithReplyAsync(
+                       const DBusMessage& dbusMessage,
+                       std::unique_ptr<DBusMessageReplyAsyncHandler> dbusMessageReplyAsyncHandler,
+                       int timeoutMilliseconds = kDefaultSendTimeoutMs) const;
+
+       DBusMessage sendDBusMessageWithReplyAndBlock(const DBusMessage& dbusMessage,
+                                                    DBusError& dbusError,
+                                                    int timeoutMilliseconds = kDefaultSendTimeoutMs) const;
+
+       DBusSignalHandlerToken addSignalMemberHandler(const std::string& objectPath,
+                                                     const std::string& interfaceName,
+                                                     const std::string& interfaceMemberName,
+                                                     const std::string& interfaceMemberSignature,
+                                                     DBusSignalHandler* dbusSignalHandler);
+
+       void registerObjectPath(const std::string& objectPath);
+       void unregisterObjectPath(const std::string& objectPath);
+
+       void removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken);
+
+       bool readWriteDispatch(int timeoutMilliseconds = -1);
+
+       virtual const std::shared_ptr<DBusDaemonProxy>& getDBusDaemonProxy();
+    virtual const std::shared_ptr<DBusServiceRegistry>& getDBusServiceRegistry();
+    virtual const std::shared_ptr<DBusObjectManager>& getDBusObjectManager();
+
+ private:
+    void dispatch();
+
+    std::thread dispatchThread_;
+    bool stopDispatching_;
+
+       DBusConnection(BusType busType);
+
+       void addLibdbusSignalMatchRule(const std::string& objectPath,
+                                      const std::string& interfaceName,
+                                      const std::string& interfaceMemberName);
+
+       void removeLibdbusSignalMatchRule(const std::string& objectPath,
+                                         const std::string& interfaceName,
+                                         const std::string& interfaceMemberName);
+
+       void initLibdbusObjectPathHandlerAfterConnect();
+
+       void initLibdbusSignalFilterAfterConnect();
+
+       ::DBusHandlerResult onLibdbusObjectPathMessage(::DBusMessage* libdbusMessage) const;
+
+       ::DBusHandlerResult onLibdbusSignalFilter(::DBusMessage* libdbusMessage);
+
+       static void onLibdbusPendingCallNotifyThunk(::DBusPendingCall* libdbusPendingCall, void *userData);
+       static void onLibdbusDataCleanup(void* userData);
+
+       static ::DBusHandlerResult onLibdbusObjectPathMessageThunk(::DBusConnection* libdbusConnection,
+                                                                  ::DBusMessage* libdbusMessage,
+                                                                   void* userData);
+
+       static ::DBusHandlerResult onLibdbusSignalFilterThunk(::DBusConnection* libdbusConnection,
+                                                             ::DBusMessage* libdbusMessage,
+                                                              void* userData);
+
+       BusType busType_;
+
+       ::DBusConnection* libdbusConnection_;
+
+       std::shared_ptr<DBusDaemonProxy> dbusDaemonProxy_;
+       std::shared_ptr<DBusServiceRegistry> dbusServiceRegistry_;
+    std::shared_ptr<DBusObjectManager> dbusObjectManager_;
+
+       DBusConnectionStatusEvent dbusConnectionStatusEvent_;
+
+       typedef std::tuple<std::string, std::string, std::string> DBusSignalMatchRuleTuple;
+       typedef std::pair<uint32_t, std::string> DBusSignalMatchRuleMapping;
+       typedef std::unordered_map<DBusSignalMatchRuleTuple, DBusSignalMatchRuleMapping> DBusSignalMatchRulesMap;
+       DBusSignalMatchRulesMap dbusSignalMatchRulesMap_;
+
+    bool isLibdbusSignalFilterAdded_;
+
+    DBusSignalHandlerTable dbusSignalHandlerTable_;
+
+    // referenceCount, objectPath
+    typedef std::unordered_map<std::string, uint32_t> LibdbusRegisteredObjectPathHandlersTable;
+    LibdbusRegisteredObjectPathHandlersTable libdbusRegisteredObjectPaths_;
+
+    static DBusObjectPathVTable libdbusObjectPathVTable_;
+};
+
+std::shared_ptr<DBusConnection> DBusConnection::getBus(const BusType& busType) {
+       return std::shared_ptr<DBusConnection>(new DBusConnection(busType));
+}
+
+std::shared_ptr<DBusConnection> DBusConnection::wrapLibDBus(::DBusConnection* libDbusConnection) {
+    return std::shared_ptr<DBusConnection>(new DBusConnection(libDbusConnection));
+}
+
+std::shared_ptr<DBusConnection> DBusConnection::getSessionBus() {
+       return getBus(BusType::SESSION);
+}
+
+std::shared_ptr<DBusConnection> DBusConnection::getSystemBus() {
+       return getBus(BusType::SYSTEM);
+}
+
+std::shared_ptr<DBusConnection> DBusConnection::getStarterBus() {
+       return getBus(BusType::STARTER);
+}
+
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_CONNECTION_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusDaemonProxy.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusDaemonProxy.cpp
new file mode 100644 (file)
index 0000000..8700ee7
--- /dev/null
@@ -0,0 +1,110 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
+#include "DBusDaemonProxy.h"\r
+#include "DBusProxyHelper.h"\r
+#include <iostream>\r
+\r
+\r
+namespace CommonAPI {\r
+namespace DBus {\r
+\r
+DBusDaemonProxy::DBusDaemonProxy(const std::shared_ptr<DBusProxyConnection>& connection):\r
+                DBusProxy("org.freedesktop.DBus", "/org/freedesktop/DBus", getInterfaceName(), connection, true),\r
+                nameOwnerChangedEvent_(*this, "NameOwnerChanged", "sss") {\r
+}\r
+\r
+const char* DBusDaemonProxy::getInterfaceName() const {\r
+       return "org.freedesktop.DBus";\r
+}\r
+\r
+DBusDaemonProxy::NameOwnerChangedEvent& DBusDaemonProxy::getNameOwnerChangedEvent() {\r
+    return nameOwnerChangedEvent_;\r
+}\r
+\r
+void DBusDaemonProxy::listNames(CommonAPI::CallStatus& callStatus, std::vector<std::string>& busNames) const {\r
+    DBusMessage dbusMethodCall = createMethodCall("ListNames", "");\r
+\r
+    DBusError dbusError;\r
+    DBusMessage dbusMessageReply = getDBusConnection()->sendDBusMessageWithReplyAndBlock(\r
+                    dbusMethodCall,\r
+                    dbusError);\r
+\r
+    if (dbusError || !dbusMessageReply.isMethodReturnType()) {\r
+        callStatus = CallStatus::REMOTE_ERROR;\r
+        return;\r
+    }\r
+\r
+    DBusInputStream inputStream(dbusMessageReply);\r
+    const bool success = DBusSerializableArguments<std::vector<std::string>>::deserialize(inputStream, busNames);\r
+    if (!success) {\r
+        callStatus = CallStatus::REMOTE_ERROR;\r
+        return;\r
+    }\r
+    callStatus = CallStatus::SUCCESS;\r
+\r
+}\r
+\r
+std::future<CallStatus> DBusDaemonProxy::listNamesAsync(ListNamesAsyncCallback listNamesAsyncCallback) const {\r
+    DBusMessage dbusMessage = createMethodCall("ListNames", "");\r
+\r
+    return getDBusConnection()->sendDBusMessageWithReplyAsync(\r
+                    dbusMessage,\r
+                    DBusProxyAsyncCallbackHandler<std::vector<std::string>>::create(listNamesAsyncCallback));\r
+}\r
+\r
+void DBusDaemonProxy::nameHasOwner(const std::string& busName, CommonAPI::CallStatus& callStatus, bool& hasOwner) const {\r
+\r
+    DBusMessage dbusMethodCall = createMethodCall("NameHasOwner", "s");\r
+\r
+    DBusOutputStream outputStream(dbusMethodCall);\r
+    bool success = DBusSerializableArguments<std::string>::serialize(outputStream, busName);\r
+    if (!success) {\r
+        callStatus = CallStatus::OUT_OF_MEMORY;\r
+        return;\r
+    }\r
+    outputStream.flush();\r
+\r
+    DBusError dbusError;\r
+    DBusMessage dbusMessageReply = getDBusConnection()->sendDBusMessageWithReplyAndBlock(\r
+                    dbusMethodCall,\r
+                    dbusError);\r
+    if (dbusError || !dbusMessageReply.isMethodReturnType()) {\r
+        callStatus = CallStatus::REMOTE_ERROR;\r
+        return;\r
+    }\r
+\r
+    DBusInputStream inputStream(dbusMessageReply);\r
+    success = DBusSerializableArguments<bool>::deserialize(inputStream, hasOwner);\r
+    if (!success) {\r
+        callStatus = CallStatus::REMOTE_ERROR;\r
+        return;\r
+    }\r
+    callStatus = CallStatus::SUCCESS;\r
+\r
+}\r
+\r
+std::future<CallStatus> DBusDaemonProxy::nameHasOwnerAsync(const std::string& busName, NameHasOwnerAsyncCallback nameHasOwnerAsyncCallback) const {\r
+\r
+    DBusMessage dbusMessage = createMethodCall("NameHasOwner", "s");\r
+\r
+    DBusOutputStream outputStream(dbusMessage);\r
+    const bool success = DBusSerializableArguments<std::string>::serialize(outputStream, busName);\r
+    if (!success) {\r
+        std::promise<CallStatus> promise;\r
+        promise.set_value(CallStatus::OUT_OF_MEMORY);\r
+        return promise.get_future();\r
+    }\r
+    outputStream.flush();\r
+\r
+    return getDBusConnection()->sendDBusMessageWithReplyAsync(\r
+                    dbusMessage,\r
+                    DBusProxyAsyncCallbackHandler<bool>::create(nameHasOwnerAsyncCallback));\r
+\r
+}\r
+\r
+void DBusDaemonProxy::getOwnVersion(uint16_t& ownVersionMajor, uint16_t& ownVersionMinor) const {\r
+}\r
+\r
+} // namespace DBus\r
+} // namespace CommonAPI\r
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusDaemonProxy.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusDaemonProxy.h
new file mode 100644 (file)
index 0000000..2abda78
--- /dev/null
@@ -0,0 +1,51 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
+#ifndef COMMONAPI_DBUS_DBUS_DAEMON_PROXY_H_\r
+#define COMMONAPI_DBUS_DBUS_DAEMON_PROXY_H_\r
+\r
+#include "DBusProxy.h"\r
+#include "DBusEvent.h"\r
+\r
+#include "DBusServiceStatusEvent.h"\r
+\r
+#include <string>\r
+#include <vector>\r
+\r
+namespace CommonAPI {\r
+namespace DBus {\r
+\r
+class DBusServiceStatusEvent;\r
+\r
+class DBusDaemonProxy: public DBusProxy {\r
+\r
+ public:\r
+       typedef Event<std::string, std::string, std::string> NameOwnerChangedEvent;\r
+       typedef std::function<void(const CommonAPI::CallStatus&, std::vector<std::string>)> ListNamesAsyncCallback;\r
+       typedef std::function<void(const CommonAPI::CallStatus&, bool)> NameHasOwnerAsyncCallback;\r
+\r
+\r
+       DBusDaemonProxy(const std::shared_ptr<DBusProxyConnection>& connection);\r
+\r
+    const char* getInterfaceName() const;\r
+\r
+    NameOwnerChangedEvent& getNameOwnerChangedEvent();\r
+\r
+    void listNames(CommonAPI::CallStatus& callStatus, std::vector<std::string>& busNames) const;\r
+    std::future<CallStatus> listNamesAsync(ListNamesAsyncCallback listNamesAsyncCallback) const;\r
+\r
+    void nameHasOwner(const std::string& busName, CommonAPI::CallStatus& callStatus, bool& hasOwner) const;\r
+    std::future<CallStatus> nameHasOwnerAsync(const std::string& busName, NameHasOwnerAsyncCallback nameHasOwnerAsyncCallback) const;\r
+\r
+ protected:\r
+    void getOwnVersion(uint16_t& ownVersionMajor, uint16_t& ownVersionMinor) const;\r
+\r
+ private:\r
+    DBusEvent<NameOwnerChangedEvent> nameOwnerChangedEvent_;\r
+\r
+};\r
+\r
+} // namespace DBus\r
+} // namespace CommonAPI\r
+\r
+#endif // COMMONAPI_DBUS_DBUS_DAEMON_PROXY_H_\r
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusError.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusError.cpp
new file mode 100644 (file)
index 0000000..937a22a
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 "DBusError.h"
+
+#include <cassert>
+#include <cstring>
+
+namespace CommonAPI {
+namespace DBus {
+
+
+DBusError::DBusError() {
+       dbus_error_init(&libdbusError_);
+}
+
+DBusError::~DBusError() {
+       dbus_error_free(&libdbusError_);
+}
+
+DBusError::operator bool() const {
+       return dbus_error_is_set(&libdbusError_);
+}
+
+void DBusError::clear() {
+       dbus_error_free(&libdbusError_);
+}
+
+std::string DBusError::getName() const {
+       assert(*this);
+
+       return std::string(libdbusError_.name);
+}
+
+std::string DBusError::getMessage() const {
+       assert(*this);
+
+       return std::string(libdbusError_.message);
+}
+
+} // namespace DBus
+} // namespace CommonAPI
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusError.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusError.h
new file mode 100644 (file)
index 0000000..d8f33ee
--- /dev/null
@@ -0,0 +1,37 @@
+/* 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_DBUS_DBUS_ERROR_H_
+#define COMMONAPI_DBUS_DBUS_ERROR_H_
+
+#include <string>
+#include <dbus/dbus.h>
+
+namespace CommonAPI {
+namespace DBus {
+
+class DBusConnection;
+
+
+class DBusError {
+ public:
+       DBusError();
+       ~DBusError();
+
+       operator bool() const;
+
+       void clear();
+
+       std::string getName() const;
+       std::string getMessage() const;
+
+ private:
+       ::DBusError libdbusError_;
+
+       friend class DBusConnection;
+};
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_ERROR_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusEvent.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusEvent.h
new file mode 100644 (file)
index 0000000..0fb0db7
--- /dev/null
@@ -0,0 +1,74 @@
+/* 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_DBUS_DBUS_EVENT_H_
+#define COMMONAPI_DBUS_DBUS_EVENT_H_
+
+#include "DBusProxyConnection.h"
+#include "DBusMessage.h"
+#include "DBusSerializableArguments.h"
+
+#include <CommonAPI/Event.h>
+
+namespace CommonAPI {
+namespace DBus {
+
+class DBusProxy;
+
+
+template <typename _EventType, typename _DBusProxy = DBusProxy>
+class DBusEvent: public _EventType, public DBusProxyConnection::DBusSignalHandler {
+ public:
+       typedef typename _EventType::ArgumentsTuple ArgumentsTuple;
+       typedef typename _EventType::CancellableListener CancellableListener;
+
+       DBusEvent(_DBusProxy& dbusProxy, const char* eventName, const char* eventSignature):
+                       dbusProxy_(dbusProxy),
+                       eventName_(eventName),
+                       eventSignature_(eventSignature) {
+               assert(eventName);
+               assert(eventSignature);
+       }
+
+       virtual ~DBusEvent() {
+               if (this->hasListeners())
+                       dbusProxy_.removeSignalMemberHandler(subscription_);
+       }
+
+       virtual SubscriptionStatus onSignalDBusMessage(const DBusMessage& dbusMessage) {
+               return unpackArgumentsAndHandleSignalDBusMessage(dbusMessage, ArgumentsTuple());
+       }
+
+ protected:
+       virtual void onFirstListenerAdded(const CancellableListener&) {
+               subscription_ = dbusProxy_.addSignalMemberHandler(eventName_, eventSignature_, this);
+       }
+
+       virtual void onLastListenerRemoved(const CancellableListener&) {
+               dbusProxy_.removeSignalMemberHandler(subscription_);
+       }
+
+ private:
+       template <typename ... _Arguments>
+       inline SubscriptionStatus unpackArgumentsAndHandleSignalDBusMessage(const DBusMessage& dbusMessage, std::tuple<_Arguments...> argTuple) {
+               return handleSignalDBusMessage(dbusMessage, std::move(argTuple), typename make_sequence<sizeof...(_Arguments)>::type());
+       }
+
+       template <typename ... _Arguments, int... _ArgIndices>
+       inline SubscriptionStatus handleSignalDBusMessage(const DBusMessage& dbusMessage, std::tuple<_Arguments...> argTuple, index_sequence<_ArgIndices...>) {
+               DBusInputStream dbusInputStream(dbusMessage);
+               const bool success = DBusSerializableArguments<_Arguments...>::deserialize(dbusInputStream, std::get<_ArgIndices>(argTuple)...);
+               // Continue subscription if deserialization failed
+               return success ? this->notifyListeners(std::get<_ArgIndices>(argTuple)...) : SubscriptionStatus::RETAIN;
+       }
+
+       _DBusProxy& dbusProxy_;
+       const char* eventName_;
+       const char* eventSignature_;
+       DBusProxyConnection::DBusSignalHandlerToken subscription_;
+};
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_EVENT_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusFactory.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusFactory.cpp
new file mode 100644 (file)
index 0000000..4bec90c
--- /dev/null
@@ -0,0 +1,114 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
+#include "DBusProxy.h"\r
+#include "DBusConnection.h"\r
+#include "DBusFactory.h"\r
+#include "DBusServiceRegistry.h"\r
+#include "DBusUtils.h"\r
+\r
+#include <algorithm>\r
+#include <cassert>\r
+#include <iostream>\r
+#include <sstream>\r
+#include <unordered_map>\r
+#include <vector>\r
+\r
+namespace CommonAPI {\r
+namespace DBus {\r
+\r
+std::unordered_map<std::string, DBusProxyFactoryFunction>* registeredProxyFactoryFunctions_;\r
+std::unordered_map<std::string, DBusAdapterFactoryFunction>* registeredAdapterFactoryFunctions_;\r
+\r
+\r
+void DBusFactory::registerProxyFactoryMethod(std::string interfaceName, DBusProxyFactoryFunction proxyFactoryMethod) {\r
+    if(!registeredProxyFactoryFunctions_) {\r
+        registeredProxyFactoryFunctions_ = new std::unordered_map<std::string, DBusProxyFactoryFunction>();\r
+    }\r
+    registeredProxyFactoryFunctions_->insert({interfaceName, proxyFactoryMethod});\r
+}\r
+\r
+void DBusFactory::registerAdapterFactoryMethod(std::string interfaceName, DBusAdapterFactoryFunction adapterFactoryMethod) {\r
+    if(!registeredAdapterFactoryFunctions_) {\r
+        registeredAdapterFactoryFunctions_ = new std::unordered_map<std::string, DBusAdapterFactoryFunction>();\r
+    }\r
+    registeredAdapterFactoryFunctions_->insert({interfaceName, adapterFactoryMethod});\r
+}\r
+\r
+\r
+\r
+DBusFactory::DBusFactory(std::shared_ptr<Runtime> runtime, const MiddlewareInfo* middlewareInfo) :\r
+                CommonAPI::Factory(runtime, middlewareInfo),\r
+                dbusConnection_(CommonAPI::DBus::DBusConnection::getSessionBus()),\r
+                acquiredConnectionName_("") {\r
+    dbusConnection_->connect();\r
+}\r
+\r
+DBusFactory::~DBusFactory() {\r
+}\r
+\r
+\r
+std::vector<std::string> DBusFactory::getAvailableServiceInstances(const std::string& serviceInterfaceName,\r
+                                                                   const std::string& serviceDomainName) {\r
+    return dbusConnection_->getDBusServiceRegistry()->getAvailableServiceInstances(serviceInterfaceName, serviceDomainName);\r
+}\r
+\r
+\r
+bool DBusFactory::isServiceInstanceAlive(const std::string& serviceInstanceId,\r
+                                         const std::string& serviceInterfaceName,\r
+                                         const std::string& serviceDomainName) {\r
+\r
+    return dbusConnection_->getDBusServiceRegistry()->isServiceInstanceAlive(serviceInstanceId, serviceInterfaceName, serviceDomainName);\r
+}\r
+\r
+std::shared_ptr<Proxy> DBusFactory::createProxy(const char* interfaceName, const std::string& participantId, const std::string& domain) {\r
+    std::string connectionName;\r
+    std::string objectPath;\r
+\r
+    findFallbackInstanceIdMapping(participantId, connectionName, objectPath);\r
+\r
+    if(!registeredProxyFactoryFunctions_) {\r
+        registeredProxyFactoryFunctions_ = new std::unordered_map<std::string, DBusProxyFactoryFunction> {};\r
+    }\r
+\r
+    for (auto it = registeredProxyFactoryFunctions_->begin(); it != registeredProxyFactoryFunctions_->end(); ++it) {\r
+        if(it->first == interfaceName) {\r
+            return (it->second)(connectionName.c_str(), objectPath.c_str(), dbusConnection_);\r
+        }\r
+    }\r
+\r
+    return NULL;\r
+}\r
+\r
+std::shared_ptr<StubAdapter> DBusFactory::createAdapter(std::shared_ptr<StubBase> stubBase, const char* interfaceName, const std::string& participantId, const std::string& domain) {\r
+    assert(dbusConnection_->isConnected());\r
+\r
+    std::string connectionName;\r
+    std::string objectPath;\r
+    findFallbackInstanceIdMapping(participantId, connectionName, objectPath);\r
+\r
+    if(acquiredConnectionName_ == "") {\r
+        dbusConnection_->requestServiceNameAndBlock(connectionName);\r
+        acquiredConnectionName_ = connectionName;\r
+    } else if (acquiredConnectionName_ != connectionName) {\r
+        return NULL;\r
+    }\r
+\r
+    if(!registeredAdapterFactoryFunctions_) {\r
+        registeredAdapterFactoryFunctions_ = new std::unordered_map<std::string, DBusAdapterFactoryFunction> {};\r
+    }\r
+\r
+    for (auto it = registeredAdapterFactoryFunctions_->begin(); it != registeredAdapterFactoryFunctions_->end(); ++it) {\r
+        if(it->first == interfaceName) {\r
+            std::shared_ptr<DBusStubAdapter> dbusStubAdapter =  (it->second)(connectionName.c_str(), objectPath.c_str(), dbusConnection_, stubBase);\r
+            dbusStubAdapter->init();\r
+            return dbusStubAdapter;\r
+        }\r
+    }\r
+\r
+    return NULL;\r
+}\r
+\r
+\r
+} // namespace DBus\r
+} // namespace CommonAPI\r
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusFactory.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusFactory.h
new file mode 100644 (file)
index 0000000..239f018
--- /dev/null
@@ -0,0 +1,44 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
+#ifndef COMMONAPI_DBUS_DBUS_FACTORY_H_\r
+#define COMMONAPI_DBUS_DBUS_FACTORY_H_\r
+\r
+#include <thread>\r
+\r
+#include <CommonAPI/Factory.h>\r
+\r
+#include "CommonAPI/DBus/DBusStubAdapter.h"\r
+#include "DBusConnection.h"\r
+\r
+namespace CommonAPI {\r
+namespace DBus {\r
+\r
+typedef std::shared_ptr<DBusProxy> (*DBusProxyFactoryFunction) (const char* busName, const char* objectPath, std::shared_ptr<DBusProxyConnection> dbusProxyConnection);\r
+typedef std::shared_ptr<DBusStubAdapter> (*DBusAdapterFactoryFunction) (std::string busName, std::string objectPath, std::shared_ptr<DBusProxyConnection> dbusProxyConnection, std::shared_ptr<StubBase> stubBase);\r
+\r
+class DBusFactory: public Factory {\r
+ public:\r
+    DBusFactory(std::shared_ptr<Runtime> runtime, const MiddlewareInfo* middlewareInfo);\r
+    virtual ~DBusFactory();\r
+\r
+    static void registerProxyFactoryMethod(std::string interfaceName, DBusProxyFactoryFunction proxyFactoryFunction);\r
+    static void registerAdapterFactoryMethod(std::string interfaceName, DBusAdapterFactoryFunction adapterFactoryMethod);\r
+\r
+    virtual std::vector<std::string> getAvailableServiceInstances(const std::string& serviceInterfaceName, const std::string& serviceDomainName = "local");\r
+\r
+    virtual bool isServiceInstanceAlive(const std::string& serviceInstanceID, const std::string& serviceInterfaceName, const std::string& serviceDomainName = "local");\r
+\r
+    virtual std::shared_ptr<Proxy> createProxy(const char* interfaceName, const std::string& participantId, const std::string& domain);\r
+\r
+    virtual std::shared_ptr<StubAdapter> createAdapter(std::shared_ptr<StubBase> stubBase, const char* interfaceName, const std::string& participantId, const std::string& domain);\r
+\r
+ private:\r
+    std::shared_ptr<CommonAPI::DBus::DBusConnection> dbusConnection_;\r
+    std::string acquiredConnectionName_;\r
+};\r
+\r
+} // namespace DBus\r
+} // namespace CommonAPI\r
+\r
+#endif // COMMONAPI_DBUS_DBUS_FACTORY_H_\r
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusFunctionalHash.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusFunctionalHash.cpp
new file mode 100644 (file)
index 0000000..f7890f5
--- /dev/null
@@ -0,0 +1,85 @@
+/* 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 "DBusFunctionalHash.h"
+
+#include <murmurhash/MurmurHash3.h>
+
+#include <cassert>
+#include <cstring>
+
+
+/*
+ * @see http://code.google.com/p/smhasher/
+ */
+#define SMHASHER_SEED_VALUE                    0xc70f6907UL
+
+
+namespace std {
+
+size_t hash< pair<const char*, const char*> >::operator()(const pair<const char*, const char*>& t) const {
+       const char* a = t.first;
+       const char* b = t.second;
+
+       assert(a);
+       assert(b);
+
+       uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE);
+       MurmurHash3_x86_32(a, strlen(a), seed, &seed);
+       MurmurHash3_x86_32(b, strlen(b), seed, &seed);
+
+       return static_cast<size_t>(seed);
+}
+
+
+size_t hash< pair<string, string> >::operator()(const pair<string, string>& t) const {
+       const string& a = t.first;
+       const string& b = t.second;
+
+       uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE);
+       MurmurHash3_x86_32(a.c_str(), a.length(), seed, &seed);
+       MurmurHash3_x86_32(b.c_str(), b.length(), seed, &seed);
+
+       return static_cast<size_t>(seed);
+}
+
+
+size_t hash< tuple<string, string, string> >::operator()(const tuple<string, string, string>& t) const {
+       const string& a = get<0>(t);
+       const string& b = get<1>(t);
+       const string& c = get<2>(t);
+
+       uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE);
+       MurmurHash3_x86_32(a.c_str(), a.length(), seed, &seed);
+       MurmurHash3_x86_32(b.c_str(), b.length(), seed, &seed);
+       MurmurHash3_x86_32(c.c_str(), c.length(), seed, &seed);
+
+       return static_cast<size_t>(seed);
+}
+
+
+size_t hash< tuple<string, string, string, string> >::operator()(const tuple<string, string, string, string>& t) const {
+       const string& a = get<0>(t);
+       const string& b = get<1>(t);
+       const string& c = get<2>(t);
+       const string& d = get<3>(t);
+
+       uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE);
+       MurmurHash3_x86_32(a.c_str(), a.length(), seed, &seed);
+       MurmurHash3_x86_32(b.c_str(), b.length(), seed, &seed);
+       MurmurHash3_x86_32(c.c_str(), c.length(), seed, &seed);
+       MurmurHash3_x86_32(d.c_str(), d.length(), seed, &seed);
+
+       return static_cast<size_t>(seed);
+}
+
+
+bool equal_to< pair<const char*, const char*> >::operator()(const pair<const char*, const char*>& a,
+                                                                                                                       const pair<const char*, const char*>& b) const {
+       if (a.first == b.first && a.second == b.second)
+               return true;
+
+       return !strcmp(a.first, b.first) && !strcmp(a.second, b.second);
+}
+
+}  // namespace std
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusFunctionalHash.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusFunctionalHash.h
new file mode 100644 (file)
index 0000000..54b89d9
--- /dev/null
@@ -0,0 +1,55 @@
+/* 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_DBUS_DBUS_FUNCTIONAL_HASH_H_
+#define COMMONAPI_DBUS_DBUS_FUNCTIONAL_HASH_H_
+
+#include <functional>
+#include <string>
+#include <tuple>
+
+namespace std {
+
+template<>
+struct hash< pair<const char*, const char*> >:
+               public unary_function< pair<const char*, const char*>, size_t > {
+
+       size_t operator()(const pair<const char*, const char*>& t) const;
+};
+
+
+template<>
+struct hash< pair<string, string> >:
+               public unary_function< pair<string, string>, size_t > {
+
+       size_t operator()(const pair<string, string>& t) const;
+};
+
+
+template<>
+struct hash< tuple<string, string, string> >:
+               public unary_function< tuple<string, string, string>, size_t > {
+
+       size_t operator()(const tuple<string, string, string>& t) const;
+};
+
+
+template<>
+struct hash< tuple<string, string, string, string> >:
+               public std::unary_function< tuple<string, string, string, string>, size_t > {
+
+       size_t operator()(const tuple<string, string, string, string>& t) const;
+};
+
+
+template<>
+struct equal_to< pair<const char*, const char*> >: public binary_function< pair<const char*, const char*>,
+                                                                                                                                                                                                        pair<const char*, const char*>,
+                                                                                                                                                                                                        bool> {
+
+  bool operator()(const pair<const char*, const char*>& a, const pair<const char*, const char*>& b) const;
+};
+
+} // namespace std
+
+#endif // COMMONAPI_DBUS_DBUS_FUNCTIONAL_HASH_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusHelper.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusHelper.h
new file mode 100644 (file)
index 0000000..a8c285e
--- /dev/null
@@ -0,0 +1,34 @@
+/* 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_DBUS_DBUS_HELPER_H_
+#define COMMONAPI_DBUS_DBUS_HELPER_H_
+
+namespace CommonAPI {
+namespace DBus {
+
+template <int ...>
+struct index_sequence {};
+
+
+template <int N, int ...S>
+struct make_sequence : make_sequence<N-1, N-1, S...> {};
+
+template <int ...S>
+struct make_sequence<0, S...> {
+    typedef index_sequence<S...> type;
+};
+
+
+template <int N, int _Offset, int ...S>
+struct make_sequence_range : make_sequence_range<N-1, _Offset, N-1+_Offset, S...> {};
+
+template <int _Offset, int ...S>
+struct make_sequence_range<0, _Offset, S...> {
+    typedef index_sequence<S...> type;
+};
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_HELPER_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusInputStream.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusInputStream.cpp
new file mode 100644 (file)
index 0000000..6f1d8ae
--- /dev/null
@@ -0,0 +1,233 @@
+/* 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 "DBusInputStream.h"
+
+namespace CommonAPI {
+namespace DBus {
+
+DBusInputStream::DBusInputStream(const CommonAPI::DBus::DBusMessage& message) :
+                message_(message),
+                dataBegin_(message.getBodyData()),
+                currentDataPosition_(0),
+                dataLength_(message.getBodyLength()),
+                exception_(nullptr) {
+}
+
+DBusInputStream::~DBusInputStream() {
+}
+
+const CommonAPI::DBus::DBusError& DBusInputStream::getError() const {
+    return *exception_;
+}
+
+bool DBusInputStream::isErrorSet() const {
+    return exception_ != nullptr;
+}
+
+void DBusInputStream::clearError() {
+    exception_ = nullptr;
+}
+
+void DBusInputStream::alignToBoundary(const size_t alignBoundary) {
+    const unsigned int alignMask = alignBoundary - 1;
+    currentDataPosition_ = (currentDataPosition_ + alignMask) & (~alignMask);
+}
+
+char* DBusInputStream::readRawData(const size_t numBytesToRead) {
+    assert((currentDataPosition_ + numBytesToRead) <= dataLength_);
+
+    char* dataPtr = (char*) (dataBegin_ + currentDataPosition_);
+    currentDataPosition_ += numBytesToRead;
+    return dataPtr;
+}
+
+template <>
+DBusInputStream& DBusInputStream::readBasicTypeValue<float>(float& val) {
+    if (sizeof(val) > 1)
+        alignToBoundary(sizeof(double));
+
+    val = (float)(*(reinterpret_cast<double*>(readRawData(sizeof(double)))));
+    return *this;
+}
+
+InputStream& DBusInputStream::readValue(bool& boolValue) {
+    alignToBoundary(4);
+    return readBasicTypeValue(boolValue);
+}
+
+InputStream& DBusInputStream::readValue(int8_t& int8Value)  { return readBasicTypeValue(int8Value); }
+InputStream& DBusInputStream::readValue(int16_t& int16Value)  { return readBasicTypeValue(int16Value); }
+InputStream& DBusInputStream::readValue(int32_t& int32Value)  { return readBasicTypeValue(int32Value); }
+InputStream& DBusInputStream::readValue(int64_t& int64Value)  { return readBasicTypeValue(int64Value); }
+
+InputStream& DBusInputStream::readValue(uint8_t& uint8Value)  { return readBasicTypeValue(uint8Value); }
+InputStream& DBusInputStream::readValue(uint16_t& uint16Value) { return readBasicTypeValue(uint16Value); }
+InputStream& DBusInputStream::readValue(uint32_t& uint32Value) { return readBasicTypeValue(uint32Value); }
+InputStream& DBusInputStream::readValue(uint64_t& uint64Value) { return readBasicTypeValue(uint64Value); }
+
+InputStream& DBusInputStream::readValue(float& floatValue) { return readBasicTypeValue(floatValue); }
+InputStream& DBusInputStream::readValue(double& doubleValue) { return readBasicTypeValue(doubleValue); }
+
+InputStream& DBusInputStream::readValue(std::string& stringValue) {
+    uint32_t lengthOfString;
+    readValue(lengthOfString);
+
+    // length field does not include terminating 0-byte, therefore length of data to read is +1
+    char* dataPtr = readRawData(lengthOfString + 1);
+
+    // The string contained in a DBus-message is required to be 0-terminated, therefore the following line works
+    stringValue = dataPtr;
+
+    return *this;
+}
+
+InputStream& DBusInputStream::readValue(ByteBuffer& byteBufferValue) {
+    *this >> byteBufferValue;
+    return *this;
+}
+
+InputStream& DBusInputStream::readEnumValue(int8_t& int8BackingTypeValue) { return readValue(int8BackingTypeValue); }
+InputStream& DBusInputStream::readEnumValue(int16_t& int16BackingTypeValue) { return readValue(int16BackingTypeValue); }
+InputStream& DBusInputStream::readEnumValue(int32_t& int32BackingTypeValue) { return readValue(int32BackingTypeValue); }
+InputStream& DBusInputStream::readEnumValue(int64_t& int64BackingTypeValue) { return readValue(int64BackingTypeValue); }
+InputStream& DBusInputStream::readEnumValue(uint8_t& uint8BackingTypeValue) { return readValue(uint8BackingTypeValue); }
+InputStream& DBusInputStream::readEnumValue(uint16_t& uint16BackingTypeValue) { return readValue(uint16BackingTypeValue); }
+InputStream& DBusInputStream::readEnumValue(uint32_t& uint32BackingTypeValue) { return readValue(uint32BackingTypeValue); }
+InputStream& DBusInputStream::readEnumValue(uint64_t& uint64BackingTypeValue) { return readValue(uint64BackingTypeValue); }
+
+InputStream& DBusInputStream::readVersionValue(Version& versionValue) {
+    alignToBoundary(8);
+    readValue(versionValue.Major);
+    readValue(versionValue.Minor);
+    return *this;
+}
+
+void DBusInputStream::beginReadSerializableStruct(const SerializableStruct& serializableStruct) {
+    alignToBoundary(8);
+}
+
+void DBusInputStream::endReadSerializableStruct(const SerializableStruct& serializableStruct) { }
+
+
+void DBusInputStream::beginReadBoolVector() {
+    beginReadGenericVector();
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadInt8Vector() {
+    beginReadGenericVector();
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadInt16Vector() {
+    beginReadGenericVector();
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadInt32Vector() {
+    beginReadGenericVector();
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadInt64Vector() {
+    beginReadGenericVector();
+    alignToBoundary(8);
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadUInt8Vector() {
+    beginReadGenericVector();
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadUInt16Vector() {
+    beginReadGenericVector();
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadUInt32Vector() {
+    beginReadGenericVector();
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadUInt64Vector() {
+    beginReadGenericVector();
+    alignToBoundary(8);
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadFloatVector() {
+    beginReadGenericVector();
+    alignToBoundary(8);
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadDoubleVector() {
+    beginReadGenericVector();
+    alignToBoundary(8);
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadStringVector() {
+    beginReadGenericVector();
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadByteBufferVector() {
+    beginReadGenericVector();
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadVersionVector() {
+    beginReadGenericVector();
+    alignToBoundary(8);
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadVectorOfSerializableStructs() {
+    beginReadGenericVector();
+    alignToBoundary(8);
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadVectorOfVectors() {
+    beginReadGenericVector();
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+void DBusInputStream::beginReadVectorOfMaps() {
+    beginReadGenericVector();
+    alignToBoundary(8);
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+bool DBusInputStream::hasMoreVectorElements() {
+    return bytesToRead_.top() > currentDataPosition_ - savedStreamPositions_.top();
+}
+
+void DBusInputStream::endReadVector() {
+    bytesToRead_.pop();
+    savedStreamPositions_.pop();
+}
+
+void DBusInputStream::beginReadMap() {
+    uint32_t vectorByteSize;
+    readBasicTypeValue(vectorByteSize);
+    bytesToRead_.push(vectorByteSize);
+    alignToBoundary(8);
+    savedStreamPositions_.push(currentDataPosition_);
+}
+
+bool DBusInputStream::hasMoreMapElements() {
+    return bytesToRead_.top() > currentDataPosition_ - savedStreamPositions_.top();
+}
+
+void DBusInputStream::endReadMap() {
+    bytesToRead_.pop();
+    savedStreamPositions_.pop();
+}
+
+
+} // namespace DBus
+} // namespace CommonAPI
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusInputStream.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusInputStream.h
new file mode 100644 (file)
index 0000000..0ab77d4
--- /dev/null
@@ -0,0 +1,209 @@
+/* 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_DBUS_DBUS_INPUT_STREAM_H_
+#define COMMONAPI_DBUS_DBUS_INPUT_STREAM_H_
+
+#include "DBusError.h"
+#include "DBusMessage.h"
+
+#include <CommonAPI/InputStream.h>
+
+#include <stdint.h>
+#include <cassert>
+#include <string>
+#include <vector>
+#include <stack>
+
+namespace CommonAPI {
+namespace DBus {
+
+/**
+ * Used to mark the position of a pointer within an array of bytes.
+ */
+typedef uint32_t position_t;
+
+/**
+ * @class DBusInputMessageStream
+ *
+ * Used to deserialize and read data from a #DBusMessage. For all data types that can be read from a #DBusMessage, a ">>"-operator should be defined to handle the reading
+ * (this operator is predefined for all basic data types and for vectors).
+ */
+class DBusInputStream: public InputStream {
+ public:
+       virtual bool hasError() const { return isErrorSet(); }
+
+    virtual InputStream& readValue(bool& boolValue);
+
+       virtual InputStream& readValue(int8_t& int8Value);
+       virtual InputStream& readValue(int16_t& int16Value);
+       virtual InputStream& readValue(int32_t& int32Value);
+       virtual InputStream& readValue(int64_t& int64Value);
+
+       virtual InputStream& readValue(uint8_t& uint8Value);
+       virtual InputStream& readValue(uint16_t& uint16Value);
+       virtual InputStream& readValue(uint32_t& uint32Value);
+       virtual InputStream& readValue(uint64_t& uint64Value);
+
+       virtual InputStream& readValue(float& floatValue);
+       virtual InputStream& readValue(double& doubleValue);
+
+       virtual InputStream& readValue(std::string& stringValue);
+       virtual InputStream& readValue(ByteBuffer& byteBufferValue);
+
+       virtual InputStream& readEnumValue(int8_t& int8BackingTypeValue);
+       virtual InputStream& readEnumValue(int16_t& int16BackingTypeValue);
+       virtual InputStream& readEnumValue(int32_t& int32BackingTypeValue);
+       virtual InputStream& readEnumValue(int64_t& int64BackingTypeValue);
+       virtual InputStream& readEnumValue(uint8_t& uint8BackingTypeValue);
+       virtual InputStream& readEnumValue(uint16_t& uint16BackingTypeValue);
+       virtual InputStream& readEnumValue(uint32_t& uint32BackingTypeValue);
+       virtual InputStream& readEnumValue(uint64_t& uint64BackingTypeValue);
+
+       virtual InputStream& readVersionValue(Version& versionValue);
+
+       virtual void beginReadSerializableStruct(const SerializableStruct& serializableStruct);
+       virtual void endReadSerializableStruct(const SerializableStruct& serializableStruct);
+
+    virtual void beginReadBoolVector();
+    virtual void beginReadInt8Vector();
+    virtual void beginReadInt16Vector();
+    virtual void beginReadInt32Vector();
+    virtual void beginReadInt64Vector();
+    virtual void beginReadUInt8Vector();
+    virtual void beginReadUInt16Vector();
+    virtual void beginReadUInt32Vector();
+    virtual void beginReadUInt64Vector();
+    virtual void beginReadFloatVector();
+    virtual void beginReadDoubleVector();
+    virtual void beginReadStringVector();
+    virtual void beginReadByteBufferVector();
+    virtual void beginReadVersionVector();
+    virtual void beginReadVectorOfSerializableStructs();
+    virtual void beginReadVectorOfVectors();
+    virtual void beginReadVectorOfMaps();
+
+       virtual bool hasMoreVectorElements();
+       virtual void endReadVector();
+
+       virtual void beginReadMap();
+       virtual bool hasMoreMapElements();
+       virtual void endReadMap();
+
+
+       /**
+     * Creates a #DBusInputMessageStream which can be used to deserialize and read data from the given #DBusMessage.
+     * As no message-signature is checked, the user is responsible to ensure that the correct data types are read in the correct order.
+     *
+     * @param message the #DBusMessage from which data should be read.
+     */
+    DBusInputStream(const CommonAPI::DBus::DBusMessage& message);
+    DBusInputStream(const DBusInputStream& imessagestream) = delete;
+
+    /**
+     * Destructor; does not call the destructor of the referred #DBusMessage. Make sure to maintain a reference to the
+     * #DBusMessage outside of the stream if you intend to make further use of the message.
+     */
+    ~DBusInputStream();
+
+    /**
+     * Marks the stream as erroneous.
+     */
+    void setError();
+
+    /**
+     * @return An instance of #DBusError if this stream is in an erroneous state, NULL otherwise
+     */
+    const CommonAPI::DBus::DBusError& getError() const;
+
+    /**
+     * @return true if this stream is in an erroneous state, false otherwise.
+     */
+    bool isErrorSet() const;
+
+    /**
+     * Marks the state of the stream as cleared from all errors. Further reading is possible afterwards.
+     * The stream will have maintained the last valid position from before its state became erroneous.
+     */
+    void clearError();
+
+    /**
+     * Aligns the stream to the given byte boundary, i.e. the stream skips as many bytes as are necessary to execute the next read
+     * starting from the given boundary.
+     *
+     * @param alignBoundary the byte boundary to which the stream needs to be aligned.
+     */
+    void alignToBoundary(const size_t alignBoundary);
+
+    /**
+     * Reads the given number of bytes and returns them as an array of characters.
+     *
+     * Actually, for performance reasons this command only returns a pointer to the current position in the stream,
+     * and then increases the position of this pointer by the number of bytes indicated by the given parameter.
+     * It is the user's responsibility to actually use only the number of bytes he indicated he would use.
+     * It is assumed the user knows what kind of value is stored next in the #DBusMessage the data is streamed from.
+     * Using a reinterpret_cast on the returned pointer should then restore the original value.
+     *
+     * Example use case:
+     * @code
+     * ...
+     * inputMessageStream.alignForBasicType(sizeof(int32_t));
+     * char* const dataPtr = inputMessageStream.read(sizeof(int32_t));
+     * int32_t val = *(reinterpret_cast<int32_t*>(dataPtr));
+     * ...
+     * @endcode
+     */
+    char* readRawData(const size_t numBytesToRead);
+
+    /**
+     * Handles all reading of basic types from a given #DBusInputMessageStream.
+     * Basic types in this context are: uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t, float, double.
+     * Any types not listed here (especially all complex types, e.g. structs, unions etc.) need to provide a
+     * specialized implementation of this operator.
+     *
+     * @tparam _BasicType The type of the value that is to be read from the given stream.
+     * @param val The variable in which the retrieved value is to be stored
+     * @param inputMessageStream The stream which the value is to be read from
+     * @return The given inputMessageStream to allow for successive reading
+     */
+    template <typename _BasicType>
+    DBusInputStream& readBasicTypeValue(_BasicType& val) {
+        if (sizeof(val) > 1)
+            alignToBoundary(sizeof(_BasicType));
+
+        val = *(reinterpret_cast<_BasicType*>(readRawData(sizeof(_BasicType))));
+        return *this;
+    }
+
+    /**
+     * Returns the position of the reading pointer, relative to the beginning of the data stream.
+     */
+    position_t getCurrentPosition() const;
+
+ private:
+    inline void beginReadGenericVector() {
+        uint32_t vectorByteSize;
+        readBasicTypeValue(vectorByteSize);
+        bytesToRead_.push(vectorByteSize);
+    }
+
+    char* dataBegin_;
+    position_t currentDataPosition_;
+    size_t dataLength_;
+    CommonAPI::DBus::DBusError* exception_;
+    CommonAPI::DBus::DBusMessage message_;
+
+    std::stack<uint32_t> bytesToRead_;
+    std::stack<position_t> savedStreamPositions_;
+};
+
+
+inline void DBusInputStream::setError() {
+    exception_ = new CommonAPI::DBus::DBusError();
+}
+
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_INPUT_STREAM_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusMessage.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusMessage.cpp
new file mode 100644 (file)
index 0000000..5e032e9
--- /dev/null
@@ -0,0 +1,239 @@
+/* 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 "DBusMessage.h"
+
+#include <cassert>
+#include <cstring>
+
+namespace CommonAPI {
+namespace DBus {
+
+DBusMessage::DBusMessage():
+               libdbusMessage_(NULL) {
+}
+
+DBusMessage::DBusMessage(::DBusMessage* libdbusMessage) {
+       libdbusMessage_ = libdbusMessage != NULL ? dbus_message_ref(libdbusMessage) : NULL;
+}
+
+DBusMessage::DBusMessage(::DBusMessage* libdbusMessage, bool increaseReferenceCount) {
+       assert(libdbusMessage);
+
+       libdbusMessage_ = increaseReferenceCount ? dbus_message_ref(libdbusMessage) : libdbusMessage;
+}
+
+DBusMessage::DBusMessage(const DBusMessage& src) {
+       libdbusMessage_ = src.libdbusMessage_ != NULL ? dbus_message_ref(src.libdbusMessage_) : NULL;
+}
+
+DBusMessage::DBusMessage(DBusMessage&& rsrc) {
+       libdbusMessage_ = rsrc.libdbusMessage_;
+       rsrc.libdbusMessage_ = NULL;
+}
+
+DBusMessage::~DBusMessage() {
+       if (libdbusMessage_)
+               dbus_message_unref(libdbusMessage_);
+}
+
+DBusMessage& DBusMessage::operator=(const DBusMessage& src) {
+       if (this != &src) {
+               if (libdbusMessage_)
+                       dbus_message_unref(libdbusMessage_);
+
+               libdbusMessage_ = src.libdbusMessage_ != NULL ? dbus_message_ref(src.libdbusMessage_) : NULL;
+       }
+
+       return *this;
+}
+
+DBusMessage& DBusMessage::operator=(DBusMessage&& rsrc) {
+       if (this != &rsrc) {
+               if (libdbusMessage_)
+                       dbus_message_unref(libdbusMessage_);
+
+               libdbusMessage_ = rsrc.libdbusMessage_;
+               rsrc.libdbusMessage_ = NULL;
+       }
+
+       return *this;
+}
+
+DBusMessage::operator bool() const {
+       const bool isNotNullDBusMessage = (libdbusMessage_ != NULL);
+       return isNotNullDBusMessage;
+}
+
+DBusMessage DBusMessage::createOrgFreedesktopOrgMethodCall(const char* methodName, const char* signature) {
+       return DBusMessage::createMethodCall("org.freedesktop.DBus",
+                                                                                "/",
+                                                                                "org.freedesktop.DBus",
+                                                                                methodName,
+                                                                                signature);
+}
+
+DBusMessage DBusMessage::createOrgFreedesktopOrgMethodCall(const std::string& methodName,
+                                                                                                                  const std::string& signature) {
+       assert(!methodName.empty());
+
+       return createOrgFreedesktopOrgMethodCall(methodName.c_str(),
+                                                                                        signature.empty() ? NULL : signature.c_str());
+}
+
+DBusMessage DBusMessage::createMethodCall(const char* busName,
+                                          const char* objectPath,
+                                          const char* interfaceName,
+                                          const char* methodName,
+                                          const char* signature) {
+       assert(busName);
+       assert(objectPath);
+       assert(interfaceName);
+       assert(methodName);
+
+       ::DBusMessage* libdbusMessageCall = dbus_message_new_method_call(busName,
+                                                                                                                                        objectPath,
+                                                                                                                                        interfaceName,
+                                                                                                                                        methodName);
+       assert(libdbusMessageCall);
+
+       if (signature)
+               dbus_message_set_signature(libdbusMessageCall, signature);
+
+       const bool increaseLibdbusMessageReferenceCount = false;
+       return DBusMessage(libdbusMessageCall, increaseLibdbusMessageReferenceCount);
+}
+
+DBusMessage DBusMessage::createMethodCall(const std::string& busName,
+                                                                                 const std::string& objectPath,
+                                                                                 const std::string& interfaceName,
+                                                                                 const std::string& methodName,
+                                                                                 const std::string& signature) {
+       assert(!busName.empty());
+       assert(!objectPath.empty());
+       assert(!interfaceName.empty());
+       assert(!methodName.empty());
+
+       return createMethodCall(busName.c_str(),
+                                                       objectPath.c_str(),
+                                                       interfaceName.c_str(),
+                                                       methodName.c_str(),
+                                                       signature.empty() ? NULL : signature.c_str());
+}
+
+DBusMessage DBusMessage::createMethodReturn(const char* signature) const {
+       ::DBusMessage* libdbusMessageReturn = dbus_message_new_method_return(libdbusMessage_);
+       assert(libdbusMessageReturn);
+
+       if (signature)
+               dbus_message_set_signature(libdbusMessageReturn, signature);
+
+       const bool increaseLibdbusMessageReferenceCount = false;
+       return DBusMessage(libdbusMessageReturn, increaseLibdbusMessageReferenceCount);
+}
+
+DBusMessage DBusMessage::createMethodReturn(const std::string& signature) const {
+       return createMethodReturn(signature.empty() ? NULL : signature.c_str());
+}
+
+DBusMessage DBusMessage::createSignal(const char* objectPath,
+                                      const char* interfaceName,
+                                      const char* signalName,
+                                      const char* signature) {
+       assert(objectPath);
+       assert(interfaceName);
+       assert(signalName);
+
+       ::DBusMessage* libdbusMessageSignal = dbus_message_new_signal(objectPath,
+                                                                                                                                 interfaceName,
+                                                                                                                                 signalName);
+       assert(libdbusMessageSignal);
+
+       if (signature)
+               dbus_message_set_signature(libdbusMessageSignal, signature);
+
+       const bool increaseLibdbusMessageReferenceCount = false;
+       return DBusMessage(libdbusMessageSignal, increaseLibdbusMessageReferenceCount);
+}
+
+DBusMessage DBusMessage::createSignal(const std::string& objectPath,
+                                                                         const std::string& interfaceName,
+                                                                         const std::string& signalName,
+                                                                         const std::string& signature) {
+       assert(!objectPath.empty());
+       assert(!interfaceName.empty());
+       assert(!signalName.empty());
+
+       return createSignal(objectPath.c_str(),
+                                               interfaceName.c_str(),
+                                               signalName.c_str(),
+                                               signature.empty() ? NULL : signature.c_str());
+}
+
+const char* DBusMessage::getObjectPath() const {
+       return dbus_message_get_path(libdbusMessage_);
+}
+
+const char* DBusMessage::getSenderName() const {
+       return dbus_message_get_sender(libdbusMessage_);
+}
+
+const char* DBusMessage::getInterfaceName() const {
+       return dbus_message_get_interface(libdbusMessage_);
+}
+
+const char* DBusMessage::getMemberName() const {
+       return dbus_message_get_member(libdbusMessage_);
+}
+
+const char* DBusMessage::getSignatureString() const {
+       return dbus_message_get_signature(libdbusMessage_);
+}
+
+const char* DBusMessage::getErrorName() const {
+       assert(isErrorType());
+
+       return dbus_message_get_error_name(libdbusMessage_);
+}
+
+bool DBusMessage::hasMemberName(const char* memberName) const {
+    const char* dbusMessageMemberName = getMemberName();
+
+    assert(memberName);
+    assert(dbusMessageMemberName);
+
+    return !strcmp(dbusMessageMemberName, memberName);
+}
+
+bool DBusMessage::hasSignature(const char* signature) const {
+       const char* dbusMessageSignature = getSignatureString();
+
+       assert(signature);
+       assert(dbusMessageSignature);
+
+       return !strcmp(dbusMessageSignature, signature);
+}
+
+const DBusMessage::Type DBusMessage::getType() const {
+       const int libdbusType = dbus_message_get_type(libdbusMessage_);
+       return static_cast<Type>(libdbusType);
+}
+
+char* DBusMessage::getBodyData() const {
+       return dbus_message_get_body(libdbusMessage_);
+}
+
+int DBusMessage::getBodyLength() const {
+       return dbus_message_get_body_length(libdbusMessage_);
+}
+
+int DBusMessage::getBodySize() const {
+       return dbus_message_get_body_allocated(libdbusMessage_);
+}
+
+bool DBusMessage::setBodyLength(const int bodyLength) {
+       return dbus_message_set_body_length(libdbusMessage_, bodyLength);
+}
+
+} // namespace DBus
+} // namespace CommonAPI
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusMessage.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusMessage.h
new file mode 100644 (file)
index 0000000..aefa305
--- /dev/null
@@ -0,0 +1,121 @@
+/* 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_DBUS_DBUS_MESSAGE_H_
+#define COMMONAPI_DBUS_DBUS_MESSAGE_H_
+
+#include <string>
+
+#include <dbus/dbus.h>
+
+namespace CommonAPI {
+namespace DBus {
+
+class DBusConnection;
+
+class DBusMessage {
+ public:
+       DBusMessage();
+       DBusMessage(::DBusMessage* libdbusMessage);
+       DBusMessage(::DBusMessage* libdbusMessage, bool increaseReferenceCount);
+       DBusMessage(const DBusMessage& src);
+       DBusMessage(DBusMessage&& src);
+
+       ~DBusMessage();
+
+       DBusMessage& operator=(const DBusMessage& src);
+       DBusMessage& operator=(DBusMessage&& rsrc);
+       operator bool() const;
+
+       static DBusMessage createOrgFreedesktopOrgMethodCall(const char* methodName,
+                                                                    const char* signature = NULL);
+
+       static DBusMessage createOrgFreedesktopOrgMethodCall(const std::string& methodName,
+                                                                                                                const std::string& signature = "");
+
+       static DBusMessage createMethodCall(const char* busName,
+                                        const char* objectPath,
+                                        const char* interfaceName,
+                                        const char* methodName,
+                                        const char* signature = NULL);
+
+       static DBusMessage createMethodCall(const std::string& busName,
+                                                                               const std::string& objectPath,
+                                                                               const std::string& interfaceName,
+                                                                               const std::string& methodName,
+                                                                               const std::string& signature = "");
+
+       DBusMessage createMethodReturn(const char* signature = NULL) const;
+
+       DBusMessage createMethodReturn(const std::string& signature) const;
+
+       static DBusMessage createSignal(const char* objectPath,
+                                               const char* interfaceName,
+                                               const char* signalName,
+                                               const char* signature = NULL);
+
+       static DBusMessage createSignal(const std::string& objectPath,
+                                                                       const std::string& interfaceName,
+                                                                       const std::string& signalName,
+                                                                       const std::string& signature = "");
+
+       const char* getSenderName() const;
+       const char* getObjectPath() const;
+       const char* getInterfaceName() const;
+       const char* getMemberName() const;
+       const char* getSignatureString() const;
+       const char* getErrorName() const;
+
+       bool hasMemberName(const char* memberName) const;
+       bool hasSignature(const char* signature) const;
+
+       enum class Type: int {
+               Invalid = DBUS_MESSAGE_TYPE_INVALID,
+               MethodCall = DBUS_MESSAGE_TYPE_METHOD_CALL,
+               MethodReturn = DBUS_MESSAGE_TYPE_METHOD_RETURN,
+               Error = DBUS_MESSAGE_TYPE_ERROR,
+               Signal = DBUS_MESSAGE_TYPE_SIGNAL
+       };
+       const Type getType() const;
+       inline bool isInvalidType() const;
+       inline bool isMethodCallType() const;
+       inline bool isMethodReturnType() const;
+       inline bool isErrorType() const;
+       inline bool isSignalType() const;
+
+       char* getBodyData() const;
+       int getBodyLength() const;
+       int getBodySize() const;
+
+       bool setBodyLength(const int bodyLength);
+
+ private:
+       ::DBusMessage* libdbusMessage_;
+
+       friend class DBusConnection;
+};
+
+bool DBusMessage::isInvalidType() const {
+       return (getType() == Type::Invalid);
+}
+
+bool DBusMessage::isMethodCallType() const {
+       return (getType() == Type::MethodCall);
+}
+
+bool DBusMessage::isMethodReturnType() const {
+       return (getType() == Type::MethodReturn);
+}
+
+bool DBusMessage::isErrorType() const {
+       return (getType() == Type::Error);
+}
+
+bool DBusMessage::isSignalType() const {
+       return (getType() == Type::Signal);
+}
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_MESSAGE_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusMultiEvent.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusMultiEvent.h
new file mode 100644 (file)
index 0000000..7bb47a5
--- /dev/null
@@ -0,0 +1,113 @@
+/* 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_DBUS_DBUS_MULTI_EVENT_H_
+#define COMMONAPI_DBUS_DBUS_MULTI_EVENT_H_
+
+#include <CommonAPI/Event.h>
+
+#include <string>
+#include <unordered_map>
+
+namespace CommonAPI {
+namespace DBus {
+
+template <typename... _Arguments>
+class DBusMultiEvent {
+ public:
+       typedef std::function<SubscriptionStatus(const std::string&, const _Arguments&...)> Listener;
+       typedef std::unordered_multimap<std::string, Listener> ListenersMap;
+       typedef typename ListenersMap::iterator Subscription;
+
+       Subscription subscribeAll(const Listener& listener);
+       Subscription subscribe(const std::string& name, const Listener& listener);
+
+       void unsubscribe(Subscription listenerSubscription);
+
+       virtual ~DBusMultiEvent() { }
+
+ protected:
+       SubscriptionStatus notifyListeners(const std::string& name, const _Arguments&... eventArguments);
+
+       virtual void onFirstListenerAdded(const std::string& name, const Listener& listener) { }
+       virtual void onListenerAdded(const std::string& name, const Listener& listener) { }
+
+       virtual void onListenerRemoved(const std::string& name, const Listener& listener) { }
+       virtual void onLastListenerRemoved(const std::string& name, const Listener& listener) { }
+
+ private:
+       typedef std::pair<typename ListenersMap::iterator, typename ListenersMap::iterator> IteratorRange;
+       SubscriptionStatus notifyListenersRange(const std::string& name, IteratorRange listenersRange, const _Arguments&... eventArguments);
+
+       ListenersMap listenersMap_;
+};
+
+template <typename... _Arguments>
+typename DBusMultiEvent<_Arguments...>::Subscription
+DBusMultiEvent<_Arguments...>::subscribeAll(const Listener& listener) {
+       return subscribe(std::string(), listener);
+}
+
+template <typename... _Arguments>
+typename DBusMultiEvent<_Arguments...>::Subscription
+DBusMultiEvent<_Arguments...>::subscribe(const std::string& name, const Listener& listener) {
+       const bool firstListenerAdded = listenersMap_.empty();
+
+       auto listenerSubscription = listenersMap_.insert({name, listener});
+
+       if (firstListenerAdded)
+               onFirstListenerAdded(name, listener);
+
+       onListenerAdded(name, listener);
+
+       return listenerSubscription;
+}
+
+template <typename... _Arguments>
+void DBusMultiEvent<_Arguments...>::unsubscribe(Subscription listenerSubscription) {
+       const std::string name = listenerSubscription->first;
+       const Listener listener = listenerSubscription->second;
+
+       listenersMap_.erase(listenerSubscription);
+
+       onListenerRemoved(name, listener);
+
+       const bool lastListenerRemoved = listenersMap_.empty();
+       if (lastListenerRemoved)
+               onLastListenerRemoved(name, listener);
+}
+
+template <typename... _Arguments>
+SubscriptionStatus DBusMultiEvent<_Arguments...>::notifyListeners(const std::string& name, const _Arguments&... eventArguments) {
+       const SubscriptionStatus subscriptionStatus = notifyListenersRange(name, listenersMap_.equal_range(name), eventArguments...);
+
+       if (subscriptionStatus == SubscriptionStatus::CANCEL)
+               return SubscriptionStatus::CANCEL;
+
+       return notifyListenersRange(name, listenersMap_.equal_range(std::string()), eventArguments...);
+}
+
+template <typename... _Arguments>
+SubscriptionStatus DBusMultiEvent<_Arguments...>::notifyListenersRange(
+               const std::string& name,
+               IteratorRange listenersRange,
+               const _Arguments&... eventArguments) {
+       for (auto iterator = listenersRange.first; iterator != listenersRange.second; ) {
+               const Listener& listener = iterator->second;
+               const SubscriptionStatus listenerSubcriptionStatus = listener(name, eventArguments...);
+
+               if (listenerSubcriptionStatus == SubscriptionStatus::CANCEL) {
+                       auto listenerIterator = iterator;
+                       listenersMap_.erase(listenerIterator);
+                       iterator++;
+               } else
+                       iterator++;
+       }
+
+       return listenersMap_.empty() ? SubscriptionStatus::CANCEL : SubscriptionStatus::RETAIN;
+}
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_MULTI_EVENT_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusObjectManager.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusObjectManager.cpp
new file mode 100644 (file)
index 0000000..42a53b7
--- /dev/null
@@ -0,0 +1,98 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
+#include "DBusObjectManager.h"\r
+#include "DBusOutputStream.h"\r
+\r
+#include <cassert>\r
+\r
+namespace CommonAPI {\r
+namespace DBus {\r
+\r
+DBusObjectManager::DBusObjectManager(const std::shared_ptr<DBusConnection>& dbusConnection):\r
+        dbusConnection_(dbusConnection) {\r
+\r
+    registerInterfaceHandler("/",\r
+                             "org.freedesktop.DBus.ObjectManager",\r
+                             std::bind(&DBusObjectManager::onGetDBusObjectManagerData, this, std::placeholders::_1));\r
+}\r
+\r
+DBusInterfaceHandlerToken DBusObjectManager::registerInterfaceHandler(const std::string& objectPath,\r
+                                                                      const std::string& interfaceName,\r
+                                                                      const DBusMessageInterfaceHandler& dbusMessageInterfaceHandler) {\r
+    DBusInterfaceHandlerPath handlerPath(objectPath, interfaceName);\r
+    bool noSuchHandlerRegistered = dbusRegisteredObjectsTable_.find(handlerPath) == dbusRegisteredObjectsTable_.end();\r
+\r
+    assert(noSuchHandlerRegistered);\r
+\r
+    dbusRegisteredObjectsTable_.insert({handlerPath, dbusMessageInterfaceHandler});\r
+    dbusConnection_->registerObjectPath(objectPath);\r
+\r
+    return handlerPath;\r
+}\r
+\r
+void DBusObjectManager::unregisterInterfaceHandler(const DBusInterfaceHandlerToken& dbusInterfaceHandlerToken) {\r
+    const std::string& objectPath = dbusInterfaceHandlerToken.first;\r
+\r
+    dbusConnection_->unregisterObjectPath(objectPath);\r
+\r
+    dbusRegisteredObjectsTable_.erase(dbusInterfaceHandlerToken);\r
+}\r
+\r
+bool DBusObjectManager::handleMessage(const DBusMessage& dbusMessage) const {\r
+    const char* objectPath = dbusMessage.getObjectPath();\r
+    const char* interfaceName = dbusMessage.getInterfaceName();\r
+\r
+    assert(objectPath);\r
+    assert(interfaceName);\r
+\r
+    DBusInterfaceHandlerPath handlerPath(objectPath, interfaceName);\r
+    auto handlerIterator = dbusRegisteredObjectsTable_.find(handlerPath);\r
+    const bool foundDBusInterfaceHandler = handlerIterator != dbusRegisteredObjectsTable_.end();\r
+    bool dbusMessageHandled = false;\r
+\r
+    if (foundDBusInterfaceHandler) {\r
+        const DBusMessageInterfaceHandler& interfaceHandlerDBusMessageHandler = handlerIterator->second;\r
+        dbusMessageHandled = interfaceHandlerDBusMessageHandler(dbusMessage);\r
+    }\r
+\r
+    return dbusMessageHandled;\r
+}\r
+\r
+bool DBusObjectManager::onGetDBusObjectManagerData(const DBusMessage& callMessage) {\r
+\r
+    DBusObjectToInterfaceDict dictToSend;\r
+\r
+    const char* interfaceName = callMessage.getInterfaceName();\r
+    const char* signature = callMessage.getSignatureString();\r
+\r
+    assert(!strcmp(interfaceName, "org.freedesktop.DBus.ObjectManager"));\r
+    assert(!strcmp(signature, ""));\r
+    assert(callMessage.getType() == DBusMessage::Type::MethodCall);\r
+\r
+    auto registeredObjectsIterator = dbusRegisteredObjectsTable_.begin();\r
+\r
+    while(registeredObjectsIterator != dbusRegisteredObjectsTable_.end()) {\r
+        DBusInterfaceHandlerPath handlerPath = registeredObjectsIterator->first;\r
+        auto foundDictEntry = dictToSend.find(handlerPath.first);\r
+\r
+        if(foundDictEntry == dictToSend.end()) {\r
+            dictToSend.insert( { handlerPath.first, { { handlerPath.second, {} } } } );\r
+        } else {\r
+            foundDictEntry->second.insert( {handlerPath.second, {} } );\r
+        }\r
+\r
+        ++registeredObjectsIterator;\r
+    }\r
+\r
+    DBusMessage replyMessage = callMessage.createMethodReturn(DBusServiceRegistry::getManagedObjectsDBusSignature_);\r
+\r
+    DBusOutputStream outStream(replyMessage);\r
+    outStream << dictToSend;\r
+    outStream.flush();\r
+    return dbusConnection_->sendDBusMessage(replyMessage);\r
+}\r
+\r
+\r
+} // namespace DBus\r
+} // namespace CommonAPI\r
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusObjectManager.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusObjectManager.h
new file mode 100644 (file)
index 0000000..ed1d599
--- /dev/null
@@ -0,0 +1,54 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
+#ifndef COMMONAPI_DBUS_DBUS_OBJECT_MANAGER_H_\r
+#define COMMONAPI_DBUS_DBUS_OBJECT_MANAGER_H_\r
+\r
+#include "DBusMessage.h"\r
+#include "DBusConnection.h"\r
+\r
+namespace CommonAPI {\r
+namespace DBus {\r
+\r
+// objectPath, interfaceName\r
+typedef std::function<bool(const DBusMessage&)> DBusMessageInterfaceHandler;\r
+typedef std::pair<std::string, std::string> DBusInterfaceHandlerPath;\r
+typedef DBusInterfaceHandlerPath DBusInterfaceHandlerToken;\r
+\r
+class DBusConnection;\r
+\r
+class DBusObjectManager {\r
+ public:\r
+    DBusObjectManager(const std::shared_ptr<DBusConnection>&);\r
+\r
+    void init();\r
+\r
+    const DBusInterfaceHandlerToken registerInterfaceHandlerForDBusObject(const std::string& objectPath,\r
+                                                                          const std::string& interfaceName,\r
+                                                                          const DBusMessageInterfaceHandler& dbusMessageInterfaceHandler);\r
+\r
+    DBusInterfaceHandlerToken registerInterfaceHandler(const std::string& objectPath,\r
+                                                       const std::string& interfaceName,\r
+                                                       const DBusMessageInterfaceHandler& dbusMessageInterfaceHandler);\r
+\r
+    void unregisterInterfaceHandler(const DBusInterfaceHandlerToken& dbusInterfaceHandlerToken);\r
+\r
+    bool handleMessage(const DBusMessage&) const;\r
+\r
+\r
+ private:\r
+    void addLibdbusObjectPathHandler(const std::string& objectPath);\r
+    void removeLibdbusObjectPathHandler(const std::string& objectPath);\r
+\r
+    bool onGetDBusObjectManagerData(const DBusMessage& callMessage);\r
+\r
+    typedef std::unordered_map<DBusInterfaceHandlerPath, DBusMessageInterfaceHandler> DBusRegisteredObjectsTable;\r
+    DBusRegisteredObjectsTable dbusRegisteredObjectsTable_;\r
+\r
+    std::shared_ptr<DBusConnection> dbusConnection_;\r
+};\r
+\r
+} // namespace DBus\r
+} // namespace CommonAPI\r
+\r
+#endif // COMMONAPI_DBUS_DBUS_OBJECT_MANAGER_H_\r
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusOutputStream.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusOutputStream.cpp
new file mode 100644 (file)
index 0000000..e829bcb
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 "DBusOutputStream.h"
+
+namespace CommonAPI {
+namespace DBus {
+
+DBusOutputStream::DBusOutputStream(DBusMessage dbusMessage) :
+                dbusMessage_(dbusMessage) {
+}
+
+DBusOutputStream::~DBusOutputStream() {
+}
+
+void DBusOutputStream::flush() {
+    const int toWrite = payload_.size();
+    const bool success = dbusMessage_.setBodyLength(toWrite);
+    char* destinationDataPtr = dbusMessage_.getBodyData();
+
+    memcpy(destinationDataPtr, payload_.c_str(), toWrite);
+}
+
+void DBusOutputStream::reserveMemory(size_t numOfBytes) {
+    assert(numOfBytes >= 0);
+
+    payload_.reserve(numOfBytes);
+}
+
+DBusOutputStream& DBusOutputStream::writeString(const char* cString, const uint32_t& length) {
+    assert(cString != NULL);
+    assert(cString[length] == '\0');
+
+    *this << length;
+
+    writeRawData(cString, length + 1);
+
+    return *this;
+}
+
+} // namespace DBus
+} // namespace CommonAPI
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusOutputStream.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusOutputStream.h
new file mode 100644 (file)
index 0000000..e1bca16
--- /dev/null
@@ -0,0 +1,337 @@
+/* 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_DBUS_DBUS_OUTPUT_MESSAGE_STREAM_H_
+#define COMMONAPI_DBUS_DBUS_OUTPUT_MESSAGE_STREAM_H_
+
+#include "DBusMessage.h"
+#include "DBusError.h"
+
+#include <CommonAPI/OutputStream.h>
+
+#include <string>
+#include <cstring>
+#include <vector>
+#include <cassert>
+#include <stack>
+
+namespace CommonAPI {
+namespace DBus {
+
+/**
+ * Used to mark the position of a pointer within an array of bytes.
+ */
+typedef uint32_t position_t;
+
+
+/**
+ * @class DBusOutputMessageStream
+ *
+ * Used to serialize and write data into a #DBusMessage. For all data types that may be written to a #DBusMessage, a "<<"-operator should be defined to handle the writing
+ * (this operator is predefined for all basic data types and for vectors). The signature that has to be written to the #DBusMessage separately is assumed
+ * to match the actual data that is inserted via the #DBusOutputMessageStream.
+ */
+class DBusOutputStream: public OutputStream {
+  public:
+       virtual OutputStream& writeValue(const bool& boolValue) { return writeBasicTypeValue<uint32_t>(boolValue); }
+
+       virtual OutputStream& writeValue(const int8_t& int8Value) { return writeBasicTypeValue(int8Value); }
+       virtual OutputStream& writeValue(const int16_t& int16Value) { return writeBasicTypeValue(int16Value); }
+       virtual OutputStream& writeValue(const int32_t& int32Value) { return writeBasicTypeValue(int32Value); }
+       virtual OutputStream& writeValue(const int64_t& int64Value) { return writeBasicTypeValue(int64Value); }
+
+       virtual OutputStream& writeValue(const uint8_t& uint8Value) { return writeBasicTypeValue(uint8Value); }
+       virtual OutputStream& writeValue(const uint16_t& uint16Value) { return writeBasicTypeValue(uint16Value); }
+       virtual OutputStream& writeValue(const uint32_t& uint32Value) { return writeBasicTypeValue(uint32Value); }
+       virtual OutputStream& writeValue(const uint64_t& uint64Value) { return writeBasicTypeValue(uint64Value); }
+
+       virtual OutputStream& writeValue(const float& floatValue) { return writeBasicTypeValue((double) floatValue); }
+       virtual OutputStream& writeValue(const double& doubleValue) { return writeBasicTypeValue(doubleValue); }
+
+       virtual OutputStream& writeValue(const std::string& stringValue) { return writeString(stringValue.c_str(), stringValue.length()); }
+
+       inline virtual OutputStream& writeValue(const ByteBuffer& byteBufferValue);
+
+       virtual OutputStream& writeEnumValue(const int8_t& int8BackingTypeValue) { return writeValue(int8BackingTypeValue); }
+       virtual OutputStream& writeEnumValue(const int16_t& int16BackingTypeValue) { return writeValue(int16BackingTypeValue); }
+       virtual OutputStream& writeEnumValue(const int32_t& int32BackingTypeValue) { return writeValue(int32BackingTypeValue); }
+       virtual OutputStream& writeEnumValue(const int64_t& int64BackingTypeValue) { return writeValue(int64BackingTypeValue); }
+       virtual OutputStream& writeEnumValue(const uint8_t& uint8BackingTypeValue) { return writeValue(uint8BackingTypeValue); }
+       virtual OutputStream& writeEnumValue(const uint16_t& uint16BackingTypeValue) { return writeValue(uint16BackingTypeValue); }
+       virtual OutputStream& writeEnumValue(const uint32_t& uint32BackingTypeValue) { return writeValue(uint32BackingTypeValue); }
+       virtual OutputStream& writeEnumValue(const uint64_t& uint64BackingTypeValue) { return writeValue(uint64BackingTypeValue); }
+
+    virtual void beginWriteBoolVector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteInt8Vector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteInt16Vector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteInt32Vector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteInt64Vector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        alignToBoundary(8);
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteUInt8Vector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteUInt16Vector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteUInt32Vector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteUInt64Vector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        alignToBoundary(8);
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteFloatVector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        alignToBoundary(8);
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteDoubleVector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        alignToBoundary(8);
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteStringVector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteByteBufferVector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteVersionVector(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        alignToBoundary(8);
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteVectorOfSerializableStructs(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        alignToBoundary(8);
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteVectorOfVectors(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        rememberCurrentStreamPosition();
+    }
+    virtual void beginWriteVectorOfMaps(uint32_t sizeOfVector) {
+        beginWriteGenericVector();
+        alignToBoundary(8);
+        rememberCurrentStreamPosition();
+    }
+
+    virtual void endWriteVector() {
+        uint32_t numOfWrittenBytes = getCurrentStreamPosition() - popRememberedStreamPosition();
+        writeBasicTypeValueAtPosition(popRememberedStreamPosition(), numOfWrittenBytes);
+    }
+
+       virtual OutputStream& writeVersionValue(const Version& versionValue) {
+               alignToBoundary(8);
+               writeValue(versionValue.Major);
+               writeValue(versionValue.Minor);
+               return *this;
+       }
+
+       virtual void beginWriteSerializableStruct(const SerializableStruct& serializableStruct) { alignToBoundary(8); }
+       virtual void endWriteSerializableStruct(const SerializableStruct& serializableStruct) { }
+
+       virtual void beginWriteMap(size_t elementCount) {
+        alignToBoundary(sizeof(uint32_t));
+        rememberCurrentStreamPosition();
+        writeBasicTypeValue((uint32_t) 0);
+           alignToBoundary(8);
+        rememberCurrentStreamPosition();
+       }
+
+       virtual void endWriteMap() {
+        uint32_t numOfWrittenBytes = getCurrentStreamPosition() - popRememberedStreamPosition();
+        writeBasicTypeValueAtPosition(popRememberedStreamPosition(), numOfWrittenBytes);
+       }
+
+       virtual bool hasError() const {
+               return dbusError_;
+       }
+
+       /**
+     * Creates a #DBusOutputMessageStream which can be used to serialize and write data into the given #DBusMessage. Any data written is buffered within the stream.
+     * Remember to call flush() when you are done with writing: Only then the data actually is written to the #DBusMessage.
+     *
+     * @param dbusMessage The #DBusMessage any data pushed into this stream should be written to.
+     */
+    DBusOutputStream(DBusMessage dbusMessage);
+
+    /**
+     * Destructor; does not call the destructor of the referred #DBusMessage. Make sure to maintain a reference to the
+     * #DBusMessage outside of the stream if you intend to make further use of the message, e.g. in order to send it,
+     * now that you have written some payload into it.
+     */
+    virtual ~DBusOutputStream();
+
+    /**
+     * Writes the data that was buffered within this #DBusOutputMessageStream to the #DBusMessage that was given to the constructor. Each call to flush()
+     * will completely override the data that currently is contained in the #DBusMessage. The data that is buffered in this #DBusOutputMessageStream is
+     * not deleted by calling flush().
+     */
+    void flush();
+
+    /**
+     * Marks the stream as erroneous.
+     */
+    inline void setError();
+
+    /**
+     * Reserves the given number of bytes for writing, thereby negating the need to dynamically allocate memory while writing.
+     * Use this method for optimization: If possible, reserve as many bytes as you need for your data before doing any writing.
+     *
+     * @param numOfBytes The number of bytes that should be reserved for writing.
+     */
+    void reserveMemory(size_t numOfBytes);
+
+    /**
+     * @return current data position where later writing is possible
+     */
+    size_t getCurrentPosition();
+
+    template<typename _BasicType>
+    DBusOutputStream& writeBasicTypeValue(const _BasicType& basicValue) {
+        if (sizeof(_BasicType) > 1)
+            alignToBoundary(sizeof(_BasicType));
+
+        writeRawData(reinterpret_cast<const char*>(&basicValue), sizeof(_BasicType));
+
+        return *this;
+    }
+
+    template<typename _BasicType>
+    bool writeBasicTypeValueAtPosition(size_t position, const _BasicType& basicValue) {
+        assert(position + sizeof(_BasicType) <= payload_.size());
+
+        return writeRawDataAtPosition(position, reinterpret_cast<const char*>(&basicValue), sizeof(_BasicType));
+    }
+
+    DBusOutputStream& writeString(const char* cString, const uint32_t& length);
+
+    /**
+     * Fills the stream with 0-bytes to make the next value be aligned to the boundary given.
+     * This means that as many 0-bytes are written to the buffer as are necessary
+     * to make the next value start with the given alignment.
+     *
+     * @param alignBoundary The byte-boundary to which the next value should be aligned.
+     */
+    virtual void alignToBoundary(const size_t alignBoundary);
+
+    /**
+     * Takes sizeInByte characters, starting from the character which val points to, and stores them for later writing.
+     * When calling flush(), all values that were written to this stream are copied into the payload of the #DBusMessage.
+     *
+     * The array of characters might be created from a pointer to a given value by using a reinterpret_cast. Example:
+     * @code
+     * ...
+     * int32_t val = 15;
+     * outputMessageStream.alignForBasicType(sizeof(int32_t));
+     * const char* const reinterpreted = reinterpret_cast<const char*>(&val);
+     * outputMessageStream.writeValue(reinterpreted, sizeof(int32_t));
+     * ...
+     * @endcode
+     *
+     * @param val The array of chars that should serve as input
+     * @param sizeInByte The number of bytes that should be written
+     * @return true if writing was successful, false otherwise.
+     *
+     * @see DBusOutputMessageStream()
+     * @see flush()
+     */
+    bool writeRawData(const char* rawDataPtr, const size_t sizeInByte);
+
+    bool writeRawDataAtPosition(size_t position, const char* rawDataPtr, const size_t sizeInByte);
+
+  protected:
+    std::string payload_;
+
+  private:
+    inline void beginWriteGenericVector() {
+        alignToBoundary(sizeof(uint32_t));
+        rememberCurrentStreamPosition();
+        writeBasicTypeValue((uint32_t) 0);
+    }
+
+    inline void rememberCurrentStreamPosition() {
+        savedStreamPositions_.push(payload_.size());
+    }
+
+    inline size_t popRememberedStreamPosition() {
+        size_t val = savedStreamPositions_.top();
+        savedStreamPositions_.pop();
+        return val;
+    }
+
+    inline size_t getCurrentStreamPosition() {
+        return payload_.size();
+    }
+
+    DBusError dbusError_;
+    DBusMessage dbusMessage_;
+
+    std::stack<position_t> savedStreamPositions_;
+};
+
+
+//Additional 0-termination, so this is 8 byte of \0
+static const char* eightByteZeroString = "\0\0\0\0\0\0\0";
+
+inline void DBusOutputStream::alignToBoundary(const size_t alignBoundary) {
+    assert(alignBoundary > 0 && alignBoundary <= 8 && (alignBoundary % 2 == 0 || alignBoundary == 1));
+
+    size_t alignMask = alignBoundary - 1;
+    size_t necessaryAlignment = ((alignMask - (payload_.size() & alignMask)) + 1) & alignMask;
+
+    writeRawData(eightByteZeroString, necessaryAlignment);
+}
+
+inline bool DBusOutputStream::writeRawData(const char* rawDataPtr, const size_t sizeInByte) {
+    assert(sizeInByte >= 0);
+
+    payload_.append(rawDataPtr, sizeInByte);
+
+    return true;
+}
+
+inline bool DBusOutputStream::writeRawDataAtPosition(size_t position, const char* rawDataPtr, const size_t sizeInByte) {
+    assert(sizeInByte >= 0);
+
+    payload_ = payload_.replace(position, sizeInByte, rawDataPtr, sizeInByte);
+
+    return true;
+}
+
+inline size_t DBusOutputStream::getCurrentPosition() {
+    return payload_.size();
+}
+
+
+OutputStream& DBusOutputStream::writeValue(const ByteBuffer& byteBufferValue) {
+       *this << byteBufferValue;
+       return *this;
+}
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_OUTPUT_MESSAGE_STREAM_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusProxy.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusProxy.cpp
new file mode 100644 (file)
index 0000000..e19dbda
--- /dev/null
@@ -0,0 +1,133 @@
+/* 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 "DBusProxy.h"
+#include "DBusServiceRegistry.h"
+#include "DBusUtils.h"
+
+#include <algorithm>
+#include <cassert>
+#include <iostream>
+#include <dbus/dbus.h>
+#include <functional>
+#include <CommonAPI/Event.h>
+
+namespace CommonAPI {
+namespace DBus {
+
+DBusProxyStatusEvent::DBusProxyStatusEvent(DBusProxy* dbusProxy) :
+                dbusProxy_(dbusProxy) {
+}
+
+void DBusProxyStatusEvent::onFirstListenerAdded(const Listener& listener) {
+    auto serviceStatusListener = std::bind(
+                    &DBusProxyStatusEvent::onServiceAvailableSignalHandler,
+                    this,
+                    std::placeholders::_1,
+                    std::placeholders::_2);
+
+    subscription_ = dbusProxy_->getDBusConnection()->getDBusServiceRegistry()->getServiceStatusEvent().subscribe(
+                    dbusProxy_->dbusBusName_ + ":" + dbusProxy_->dbusObjectPath_ + ":" + dbusProxy_->interfaceName_,
+                    serviceStatusListener);
+}
+
+void DBusProxyStatusEvent::onLastListenerRemoved(const Listener& listener) {
+    dbusProxy_->getDBusConnection()->getDBusServiceRegistry()->getServiceStatusEvent().unsubscribe(subscription_);
+}
+
+SubscriptionStatus DBusProxyStatusEvent::onServiceAvailableSignalHandler(const std::string& name,
+                                                                         const AvailabilityStatus& availabilityStatus) {
+    AvailabilityStatus availability = availabilityStatus;
+
+    return notifyListeners(availability);
+}
+
+const std::string DBusProxy::domain_ = "local";
+
+DBusProxy::DBusProxy(const std::string& dbusBusName,
+                     const std::string& dbusObjectPath,
+                     const std::string& interfaceName,
+                     const std::shared_ptr<DBusProxyConnection>& dbusProxyConnection) :
+                                                dbusBusName_(dbusBusName),
+                                dbusObjectPath_(dbusObjectPath),
+                                interfaceName_(interfaceName),
+                                statusEvent_(this),
+                                interfaceVersionAttribute_(*this, "getInterfaceVersion"),
+                                available_(false),
+                                availableSet_(false),
+                                connection_(dbusProxyConnection) {
+}
+
+DBusProxy::DBusProxy(const std::string& dbusBusName,
+                     const std::string& dbusObjectPath,
+                     const std::string& interfaceName,
+                     const std::shared_ptr<DBusProxyConnection>& connection,
+                     const bool isAlwaysAvailable) :
+                 dbusBusName_(dbusBusName),
+                 dbusObjectPath_(dbusObjectPath),
+                 interfaceName_(interfaceName),
+                 statusEvent_(this),
+                 interfaceVersionAttribute_(*this, "getInterfaceVersion"),
+                 available_(isAlwaysAvailable),
+                 availableSet_(isAlwaysAvailable),
+                 connection_(connection) {
+}
+
+std::string DBusProxy::getAddress() const {
+    return domain_ + ":" + interfaceName_ + ":" + dbusBusName_;
+}
+
+const std::string& DBusProxy::getDomain() const {
+    return domain_;
+}
+
+const std::string& DBusProxy::getServiceId() const {
+    return getInterfaceName();
+}
+
+const std::string& DBusProxy::getInstanceId() const {
+    return dbusBusName_;
+}
+
+
+bool DBusProxy::isAvailable() const {
+    if (!availableSet_) {
+        auto status = getDBusConnection()->getDBusServiceRegistry()->getReadyFuture().wait_for(std::chrono::milliseconds(1));
+        if (checkReady(status)) {
+            available_ = getDBusConnection()->getDBusServiceRegistry()->isServiceInstanceAlive(getAddress());
+            availableSet_ = true;
+        }
+    }
+    return available_;
+}
+
+bool DBusProxy::isAvailableBlocking() const {
+
+    if (!availableSet_) {
+        getDBusConnection()->getDBusServiceRegistry()->getReadyFuture().wait();
+        available_ = getDBusConnection()->getDBusServiceRegistry()->isServiceInstanceAlive(getAddress());
+        availableSet_ = true;
+    }
+    return available_;
+}
+
+ProxyStatusEvent& DBusProxy::getProxyStatusEvent() {
+    return statusEvent_;
+}
+
+InterfaceVersionAttribute& DBusProxy::getInterfaceVersionAttribute() {
+    return interfaceVersionAttribute_;
+}
+
+DBusMessage DBusProxy::createMethodCall(const char* methodName,
+                                        const char* methodSignature) const {
+    return DBusMessage::createMethodCall(
+                    dbusBusName_.c_str(),
+                    dbusObjectPath_.c_str(),
+                    getInterfaceName().c_str(),
+                    methodName,
+                    methodSignature);
+}
+
+} // namespace DBus
+} // namespace CommonAPI
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusProxy.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusProxy.h
new file mode 100644 (file)
index 0000000..9f5db75
--- /dev/null
@@ -0,0 +1,139 @@
+/* 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_DBUS_DBUS_PROXY_H_
+#define COMMONAPI_DBUS_DBUS_PROXY_H_
+
+#include "DBusProxyConnection.h"
+#include "DBusAttribute.h"
+
+#include <CommonAPI/Proxy.h>
+#include <CommonAPI/types.h>
+
+#include <functional>
+#include <memory>
+#include <string>
+
+namespace CommonAPI {
+namespace DBus {
+
+class DBusProxy;
+
+typedef Event<AvailabilityStatus> ProxyStatusEvent;
+
+class DBusProxyStatusEvent: public ProxyStatusEvent {
+ public:
+    DBusProxyStatusEvent(DBusProxy* dbusProxy);
+
+    void onFirstListenerAdded(const Listener& listener);
+    void onLastListenerRemoved(const Listener& listener);
+
+    Subscription subscribe(Listener listener);
+
+ private:
+    SubscriptionStatus onServiceAvailableSignalHandler(const std::string& name, const AvailabilityStatus& availabilityStatus);
+
+    DBusProxy* dbusProxy_;
+    DBusServiceStatusEvent::Subscription subscription_;
+
+    friend class DBusProxy;
+
+};
+
+
+class DBusProxy: public virtual CommonAPI::Proxy {
+ public:
+    DBusProxy(const std::string& dbusBusName,
+              const std::string& dbusObjectPath,
+              const std::string& interfaceName,
+              const std::shared_ptr<DBusProxyConnection>& dbusProxyConnection);
+
+    virtual std::string getAddress() const;
+    virtual const std::string& getDomain() const;
+    virtual const std::string& getServiceId() const;
+    virtual const std::string& getInstanceId() const;
+    virtual bool isAvailable() const;
+    virtual bool isAvailableBlocking() const;
+    virtual ProxyStatusEvent& getProxyStatusEvent();
+    virtual InterfaceVersionAttribute& getInterfaceVersionAttribute();
+
+    inline const std::string& getDBusBusName() const;
+    inline const std::string& getDBusObjectPath() const;
+    inline const std::string& getInterfaceName() const;
+    inline const std::shared_ptr<DBusProxyConnection>& getDBusConnection() const;
+
+    DBusMessage createMethodCall(const char* methodName,
+                                 const char* methodSignature = NULL) const;
+
+    inline DBusProxyConnection::DBusSignalHandlerToken addSignalMemberHandler(
+               const std::string& signalName,
+               const std::string& signalSignature,
+               DBusProxyConnection::DBusSignalHandler* dbusSignalHandler);
+
+    inline void removeSignalMemberHandler(const DBusProxyConnection::DBusSignalHandlerToken& dbusSignalHandlerToken);
+
+ protected:
+    DBusProxy(const DBusProxy& abstractProxy) = delete;
+
+    DBusProxy(const std::string& busName,
+              const std::string& objectId,
+              const std::string& interfaceName,
+              const std::shared_ptr<DBusProxyConnection>& connection,
+              const bool isAlwaysAvailable);
+
+    virtual void getOwnVersion(uint16_t& ownVersionMajor, uint16_t& ownVersionMinor) const = 0;
+
+    DBusProxyStatusEvent statusEvent_;
+    DBusProxyStatusEvent::Subscription remoteStatusSubscription_;
+
+ private:
+    void onServiceAlive(bool alive);
+
+    const std::string dbusBusName_;
+    const std::string dbusObjectPath_;
+    const std::string interfaceName_;
+
+    mutable bool available_;
+    mutable bool availableSet_;
+
+    std::shared_ptr<DBusProxyConnection> connection_;
+
+    DBusReadonlyAttribute<InterfaceVersionAttribute> interfaceVersionAttribute_;
+
+    static const std::string domain_;
+
+    friend class DBusProxyStatusEvent;
+};
+
+const std::string& DBusProxy::getDBusBusName() const {
+    return dbusBusName_;
+}
+
+const std::string& DBusProxy::getDBusObjectPath() const {
+    return dbusObjectPath_;
+}
+
+const std::string& DBusProxy::getInterfaceName() const {
+    return interfaceName_;
+}
+
+const std::shared_ptr<DBusProxyConnection>& DBusProxy::getDBusConnection() const {
+    return connection_;
+}
+
+DBusProxyConnection::DBusSignalHandlerToken DBusProxy::addSignalMemberHandler(
+        const std::string& signalName,
+        const std::string& signalSignature,
+        DBusProxyConnection::DBusSignalHandler* dbusSignalHandler) {
+    return connection_->addSignalMemberHandler(dbusObjectPath_, getInterfaceName(), signalName, signalSignature, dbusSignalHandler);
+}
+
+void DBusProxy::removeSignalMemberHandler(const DBusProxyConnection::DBusSignalHandlerToken& dbusSignalHandlerToken) {
+    return connection_->removeSignalMemberHandler(dbusSignalHandlerToken);
+}
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_PROXY_H_
+
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.h
new file mode 100644 (file)
index 0000000..8fd76ea
--- /dev/null
@@ -0,0 +1,72 @@
+/* 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_DBUS_DBUS_PROXY_ASYNC_CALLBACK_HANDLER_H_
+#define COMMONAPI_DBUS_DBUS_PROXY_ASYNC_CALLBACK_HANDLER_H_
+
+#include "DBusProxyConnection.h"
+#include "DBusMessage.h"
+#include "DBusSerializableArguments.h"
+#include "DBusHelper.h"
+
+#include <functional>
+#include <future>
+#include <memory>
+#include <iostream>
+
+
+namespace CommonAPI {
+namespace DBus {
+
+template <typename ... _ArgTypes>
+class DBusProxyAsyncCallbackHandler: public DBusProxyConnection::DBusMessageReplyAsyncHandler {
+ public:
+       typedef std::function<void(CallStatus, _ArgTypes...)> FunctionType;
+
+       static inline std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler> create(FunctionType&& callback) {
+               return std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler>(
+                               new DBusProxyAsyncCallbackHandler(std::move(callback)));
+       }
+
+       DBusProxyAsyncCallbackHandler() = delete;
+       DBusProxyAsyncCallbackHandler(FunctionType&& callback):
+               callback_(std::move(callback)) {
+       }
+
+       virtual std::future<CallStatus> getFuture() {
+               return promise_.get_future();
+       }
+
+       virtual void onDBusMessageReply(const CallStatus& dbusMessageCallStatus, const DBusMessage& dbusMessage) {
+               promise_.set_value(handleDBusMessageReply(dbusMessageCallStatus, dbusMessage, typename make_sequence<sizeof...(_ArgTypes)>::type()));
+       }
+
+ private:
+       template <int... _ArgIndices>
+       inline CallStatus handleDBusMessageReply(const CallStatus dbusMessageCallStatus, const DBusMessage& dbusMessage, index_sequence<_ArgIndices...>) const {
+               CallStatus callStatus = dbusMessageCallStatus;
+               std::tuple<_ArgTypes...> argTuple;
+
+        if (dbusMessageCallStatus == CallStatus::SUCCESS) {
+            if (!dbusMessage.isErrorType()) {
+                DBusInputStream dbusInputStream(dbusMessage);
+                const bool success = DBusSerializableArguments<_ArgTypes...>::deserialize(dbusInputStream, std::get<_ArgIndices>(argTuple)...);
+                if (!success)
+                    callStatus = CallStatus::REMOTE_ERROR;
+            } else {
+                callStatus = CallStatus::REMOTE_ERROR;
+            }
+        }
+
+               callback_(callStatus, std::move(std::get<_ArgIndices>(argTuple))...);
+               return callStatus;
+       }
+
+       std::promise<CallStatus> promise_;
+       const FunctionType callback_;
+};
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_PROXY_ASYNC_CALLBACK_HANDLER_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusProxyConnection.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusProxyConnection.h
new file mode 100644 (file)
index 0000000..c8f5b7e
--- /dev/null
@@ -0,0 +1,94 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
+#ifndef COMMONAPI_DBUS_DBUS_PROXY_CONNECTION_H_\r
+#define COMMONAPI_DBUS_DBUS_PROXY_CONNECTION_H_\r
+\r
+#include "DBusError.h"\r
+#include "DBusMessage.h"\r
+\r
+#include "DBusFunctionalHash.h"\r
+#include "DBusServiceStatusEvent.h"\r
+\r
+#include <CommonAPI/types.h>\r
+#include <CommonAPI/Attribute.h>\r
+#include <CommonAPI/Event.h>\r
+\r
+#include <cstdint>\r
+#include <functional>\r
+#include <future>\r
+#include <memory>\r
+#include <tuple>\r
+#include <unordered_map>\r
+#include <utility>\r
+#include <vector>\r
+\r
+namespace CommonAPI {\r
+namespace DBus {\r
+\r
+\r
+typedef std::function<void(const DBusMessage&)> DBusMessageHandler;\r
+\r
+class DBusDaemonProxy;\r
+class DBusServiceRegistry;\r
+class DBusObjectManager;\r
+\r
+\r
+class DBusProxyConnection {\r
+ public:\r
+    class DBusMessageReplyAsyncHandler {\r
+     public:\r
+       virtual ~DBusMessageReplyAsyncHandler() { }\r
+       virtual std::future<CallStatus> getFuture() = 0;\r
+       virtual void onDBusMessageReply(const CallStatus&, const DBusMessage&) = 0;\r
+    };\r
+\r
+    class DBusSignalHandler {\r
+     public:\r
+        virtual ~DBusSignalHandler() { }\r
+        virtual SubscriptionStatus onSignalDBusMessage(const DBusMessage&) = 0;\r
+    };\r
+\r
+    // objectPath, interfaceName, interfaceMemberName, interfaceMemberSignature\r
+    typedef std::tuple<std::string, std::string, std::string, std::string> DBusSignalHandlerPath;\r
+    typedef std::unordered_multimap<DBusSignalHandlerPath, DBusSignalHandler*> DBusSignalHandlerTable;\r
+    typedef DBusSignalHandlerPath DBusSignalHandlerToken;\r
+\r
+\r
+       virtual ~DBusProxyConnection() { }\r
+\r
+       virtual bool isConnected() const =  0;\r
+\r
+       virtual bool sendDBusMessage(const DBusMessage& dbusMessage, uint32_t* allocatedSerial = NULL) const = 0;\r
+\r
+       static const int kDefaultSendTimeoutMs = 100 * 1000;\r
+\r
+       virtual std::future<CallStatus> sendDBusMessageWithReplyAsync(\r
+                       const DBusMessage& dbusMessage,\r
+                       std::unique_ptr<DBusMessageReplyAsyncHandler> dbusMessageReplyAsyncHandler,\r
+                       int timeoutMilliseconds = kDefaultSendTimeoutMs) const = 0;\r
+\r
+       virtual DBusMessage sendDBusMessageWithReplyAndBlock(\r
+                       const DBusMessage& dbusMessage,\r
+                       DBusError& dbusError,\r
+                       int timeoutMilliseconds = kDefaultSendTimeoutMs) const = 0;\r
+\r
+       virtual DBusSignalHandlerToken addSignalMemberHandler(\r
+                       const std::string& objectPath,\r
+                       const std::string& interfaceName,\r
+                       const std::string& interfaceMemberName,\r
+                       const std::string& interfaceMemberSignature,\r
+                       DBusSignalHandler* dbusSignalHandler) = 0;\r
+\r
+       virtual void removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken) = 0;\r
+\r
+    virtual const std::shared_ptr<DBusDaemonProxy>& getDBusDaemonProxy() = 0;\r
+    virtual const std::shared_ptr<DBusServiceRegistry>& getDBusServiceRegistry() = 0;\r
+    virtual const std::shared_ptr<DBusObjectManager>& getDBusObjectManager() = 0;\r
+};\r
+\r
+\r
+} // namespace DBus\r
+} // namespace CommonAPI\r
+\r
+#endif //COMMONAPI_DBUS_DBUS_PROXY_CONNECTION_H_\r
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusProxyHelper.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusProxyHelper.h
new file mode 100644 (file)
index 0000000..efea71d
--- /dev/null
@@ -0,0 +1,139 @@
+/* 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_DBUS_DBUS_PROXY_HELPER_H_
+#define COMMONAPI_DBUS_DBUS_PROXY_HELPER_H_
+
+#include "DBusMessage.h"
+#include "DBusSerializableArguments.h"
+#include "DBusProxyAsyncCallbackHandler.h"
+
+#include <functional>
+#include <future>
+#include <memory>
+#include <string>
+
+namespace CommonAPI {
+namespace DBus {
+
+
+class DBusProxy;
+
+
+template< class, class >
+struct DBusProxyHelper;
+
+template <
+       template <class...> class _In, class... _InArgs,
+       template <class...> class _Out, class... _OutArgs>
+struct DBusProxyHelper<_In<_InArgs...>, _Out<_OutArgs...>> {
+       template <typename _DBusProxy = DBusProxy>
+       static void callMethod(const _DBusProxy& dbusProxy,
+                       const char* methodName,
+                       const char* methodSignature,
+                       const _InArgs&... inArgs,
+                       CommonAPI::CallStatus& callStatus) {
+           if (dbusProxy.isAvailableBlocking()) {
+
+               DBusMessage dbusMessage = dbusProxy.createMethodCall(methodName, methodSignature);
+
+               if (sizeof...(_InArgs) > 0) {
+                   DBusOutputStream outputStream(dbusMessage);
+                   const bool success = DBusSerializableArguments<_InArgs...>::serialize(outputStream, inArgs...);
+                   if (!success) {
+                       callStatus = CallStatus::OUT_OF_MEMORY;
+                       return;
+                   }
+                   outputStream.flush();
+               }
+
+               const bool dbusMessageSent = dbusProxy.getDBusConnection()->sendDBusMessage(dbusMessage);
+               callStatus = dbusMessageSent ? CallStatus::SUCCESS : CallStatus::OUT_OF_MEMORY;
+           } else {
+               callStatus = CallStatus::NOT_AVAILABLE;
+           }
+       }
+
+       template <typename _DBusProxy = DBusProxy>
+       static void callMethodWithReply(
+                       const _DBusProxy& dbusProxy,
+                       const char* methodName,
+                       const char* methodSignature,
+                       const _InArgs&... inArgs,
+                       CommonAPI::CallStatus& callStatus,
+                       _OutArgs&... outArgs) {
+
+           if (dbusProxy.isAvailableBlocking()) {
+
+               DBusMessage dbusMethodCall = dbusProxy.createMethodCall(methodName, methodSignature);
+
+               if (sizeof...(_InArgs) > 0) {
+                   DBusOutputStream outputStream(dbusMethodCall);
+                   const bool success = DBusSerializableArguments<_InArgs...>::serialize(outputStream, inArgs...);
+                   if (!success) {
+                       callStatus = CallStatus::OUT_OF_MEMORY;
+                       return;
+                   }
+                   outputStream.flush();
+               }
+
+               DBusError dbusError;
+               DBusMessage dbusMessageReply = dbusProxy.getDBusConnection()->sendDBusMessageWithReplyAndBlock(dbusMethodCall, dbusError);
+               if (dbusError || !dbusMessageReply.isMethodReturnType()) {
+                   callStatus = CallStatus::REMOTE_ERROR;
+                   return;
+               }
+
+               if (sizeof...(_OutArgs) > 0) {
+                   DBusInputStream inputStream(dbusMessageReply);
+                   const bool success = DBusSerializableArguments<_OutArgs...>::deserialize(inputStream, outArgs...);
+                   if (!success) {
+                       callStatus = CallStatus::REMOTE_ERROR;
+                       return;
+                   }
+               }
+
+               callStatus = CallStatus::SUCCESS;
+           } else {
+               callStatus = CallStatus::NOT_AVAILABLE;
+           }
+       }
+
+       template <typename _DBusProxy = DBusProxy, typename _AsyncCallback>
+       static std::future<CallStatus> callMethodAsync(
+                       const _DBusProxy& dbusProxy,
+                       const char* methodName,
+                       const char* methodSignature,
+                       const _InArgs&... inArgs,
+                       _AsyncCallback asyncCallback) {
+
+           if (dbusProxy.isAvailable()) {
+
+               DBusMessage dbusMessage = dbusProxy.createMethodCall(methodName, methodSignature);
+
+               if (sizeof...(_InArgs) > 0) {
+                   DBusOutputStream outputStream(dbusMessage);
+                           const bool success = DBusSerializableArguments<_InArgs...>::serialize(outputStream, inArgs...);
+                           if (!success) {
+                               std::promise<CallStatus> promise;
+                               promise.set_value(CallStatus::OUT_OF_MEMORY);
+                               return promise.get_future();
+                           }
+                           outputStream.flush();
+               }
+
+               return dbusProxy.getDBusConnection()->sendDBusMessageWithReplyAsync(
+                               dbusMessage,
+                               DBusProxyAsyncCallbackHandler<_OutArgs...>::create(std::move(asyncCallback)));
+               } else {
+                   std::promise<CallStatus> promise;
+                   promise.set_value(CallStatus::NOT_AVAILABLE);
+                   return promise.get_future();
+               }
+          }
+};
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_PROXY_HELPER_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusRuntime.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusRuntime.cpp
new file mode 100644 (file)
index 0000000..9179ce7
--- /dev/null
@@ -0,0 +1,29 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
+#include "DBusRuntime.h"\r
+\r
+namespace CommonAPI {\r
+namespace DBus {\r
+\r
+const MiddlewareInfo DBusRuntime::middlewareInfo_("DBus", &DBusRuntime::getInstance);\r
+\r
+__attribute__((constructor)) void registerDBusMiddleware(void) {\r
+    Runtime::registerRuntimeLoader("DBus", &DBusRuntime::getInstance);\r
+}\r
+\r
+std::shared_ptr<Runtime> DBusRuntime::getInstance() {\r
+    static std::shared_ptr<Runtime> singleton_;\r
+    if(!singleton_) {\r
+        singleton_ = std::make_shared<DBusRuntime>();\r
+    }\r
+    return singleton_;\r
+}\r
+\r
+std::shared_ptr<Factory> DBusRuntime::createFactory() {\r
+    auto factory = std::make_shared<DBusFactory>(this->shared_from_this(), &middlewareInfo_);\r
+    return factory;\r
+}\r
+\r
+} // namespace DBus\r
+} // namespace CommonAPI\r
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusRuntime.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusRuntime.h
new file mode 100644 (file)
index 0000000..52f7fa0
--- /dev/null
@@ -0,0 +1,33 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
+#ifndef COMMONAPI_DBUS_DBUS_RUNTIME_H_\r
+#define COMMONAPI_DBUS_DBUS_RUNTIME_H_\r
+\r
+#include "CommonAPI/Runtime.h"\r
+\r
+#include "DBusFactory.h"\r
+\r
+namespace CommonAPI {\r
+namespace DBus {\r
+\r
+class DBusRuntime: public Runtime, public std::enable_shared_from_this<DBusRuntime> {\r
+ public:\r
+    static std::shared_ptr<Runtime> getInstance();\r
+\r
+    std::shared_ptr<Factory> createFactory();\r
+\r
+    static const MiddlewareInfo middlewareInfo_;\r
+};\r
+\r
+} // namespace DBus\r
+} // namespace CommonAPI\r
+\r
+\r
+extern "C" {\r
+\r
+CommonAPI::MiddlewareInfo middlewareInfo = CommonAPI::DBus::DBusRuntime::middlewareInfo_;\r
+\r
+}\r
+\r
+#endif // COMMONAPI_DBUS_DBUS_RUNTIME_H_\r
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusSerializableArguments.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusSerializableArguments.h
new file mode 100644 (file)
index 0000000..c028f17
--- /dev/null
@@ -0,0 +1,58 @@
+/* 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_DBUS_SERIALIZABLE_ARGUMENTS_H_
+#define COMMONAPI_DBUS_SERIALIZABLE_ARGUMENTS_H_
+
+#include "DBusInputStream.h"
+#include "DBusOutputStream.h"
+
+namespace CommonAPI {
+namespace DBus {
+
+template <typename... _Arguments>
+struct DBusSerializableArguments;
+
+template <>
+struct DBusSerializableArguments<> {
+       static inline bool serialize(OutputStream& outputStream) {
+               return true;
+       }
+
+       static inline bool deserialize(DBusInputStream& inputStream) {
+               return true;
+       }
+};
+
+template <typename _ArgumentType>
+struct DBusSerializableArguments<_ArgumentType> {
+       static inline bool serialize(OutputStream& outputStream, const _ArgumentType& argument) {
+               outputStream << argument;
+               return !outputStream.hasError();
+       }
+
+       static inline bool deserialize(DBusInputStream& inputStream, _ArgumentType& argument) {
+               inputStream >> argument;
+               return !inputStream.hasError();
+       }
+};
+
+template <typename _ArgumentType, typename ... _Rest>
+struct DBusSerializableArguments<_ArgumentType, _Rest...> {
+       static inline bool serialize(OutputStream& outputStream, const _ArgumentType& argument, const _Rest&... rest) {
+               outputStream << argument;
+               const bool success = !outputStream.hasError();
+               return success ? DBusSerializableArguments<_Rest...>::serialize(outputStream, rest...) : false;
+       }
+
+       static inline bool deserialize(DBusInputStream& inputStream, _ArgumentType& argument, _Rest&... rest) {
+               inputStream >> argument;
+               const bool success = !inputStream.hasError();
+               return success ? DBusSerializableArguments<_Rest...>::deserialize(inputStream, rest...) : false;
+       }
+};
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_SERIALIZABLE_ARGUMENTS_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusServiceRegistry.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusServiceRegistry.cpp
new file mode 100644 (file)
index 0000000..bf43a28
--- /dev/null
@@ -0,0 +1,312 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
+#include <utility>\r
+#include <sstream>\r
+#include <iostream>\r
+#include <string>\r
+#include <tuple>\r
+#include <unistd.h>\r
+\r
+#include "DBusServiceRegistry.h"\r
+#include "DBusInputStream.h"\r
+#include "DBusDaemonProxy.h"\r
+#include "DBusConnection.h"\r
+#include "DBusUtils.h"\r
+\r
+\r
+namespace CommonAPI {\r
+namespace DBus {\r
+\r
+\r
+DBusServiceRegistry::DBusServiceRegistry(std::shared_ptr<DBusConnection> dbusConnection) :\r
+                dbusConnection_(dbusConnection),\r
+                ready(false),\r
+                serviceStatusEvent_(std::shared_ptr<DBusServiceRegistry>(this)),\r
+                readyPromise_(),\r
+                readyMutex_()\r
+{\r
+    readyFuture_ = readyPromise_.get_future();\r
+    cacheAllServices();\r
+    dbusNameOwnerChangedEventSubscription_ =\r
+                    dbusConnection_->getDBusDaemonProxy()->getNameOwnerChangedEvent().subscribe(\r
+                                    std::bind(&DBusServiceRegistry::onDBusNameOwnerChangedEvent,\r
+                                                    this,\r
+                                                    std::placeholders::_1,\r
+                                                    std::placeholders::_2,\r
+                                                    std::placeholders::_3));\r
+    std::thread(std::bind(&DBusServiceRegistry::isReadyBlocking, this)).detach();\r
+}\r
+\r
+void DBusServiceRegistry::registerAvailabilityListener(const std::string& service, const std::function<void(bool)>& listener) {\r
+    availabilityCallbackList.insert({service, listener});\r
+\r
+}\r
+\r
+DBusServiceStatusEvent& DBusServiceRegistry::getServiceStatusEvent() {\r
+    return serviceStatusEvent_;\r
+}\r
+\r
+DBusServiceRegistry::~DBusServiceRegistry() {\r
+    dbusConnection_->getDBusDaemonProxy()->getNameOwnerChangedEvent().unsubscribe(dbusNameOwnerChangedEventSubscription_);\r
+}\r
+\r
+std::future<bool>& DBusServiceRegistry::getReadyFuture() {\r
+    return readyFuture_;\r
+}\r
+\r
+bool DBusServiceRegistry::isReadyBlocking() {\r
+    if (!ready) {\r
+        readyMutex_.lock();\r
+        auto status = readyFuture_.wait_for(std::chrono::seconds(5));\r
+        if (checkReady(status)) {\r
+            ready = true;\r
+        } else {\r
+            ready = true;\r
+            readyPromise_.set_value(true);\r
+        }\r
+        readyMutex_.unlock();\r
+    }\r
+    return ready;\r
+}\r
+\r
+bool DBusServiceRegistry::isReady() {\r
+       return ready;\r
+}\r
+\r
+std::vector<std::string> DBusServiceRegistry::getAvailableServiceInstances(const std::string& serviceInterfaceName,\r
+                                                                           const std::string& serviceDomainName) {\r
+       if (!isReadyBlocking()) {\r
+               return std::vector<std::string>();\r
+       }\r
+\r
+    if (serviceDomainName != "local" || !dbusConnection_->isConnected()) {\r
+        return std::vector<std::string>();\r
+    }\r
+\r
+    std::vector<std::string> addressesOfKnownServiceInstances;\r
+    auto knownServiceInstancesIteratorPair = dbusCachedProvidersForInterfaces_.equal_range(serviceInterfaceName);\r
+\r
+    while(knownServiceInstancesIteratorPair.first != knownServiceInstancesIteratorPair.second) {\r
+        const DBusServiceInstanceId dbusServiceInstanceId = knownServiceInstancesIteratorPair.first->second;\r
+        addressesOfKnownServiceInstances.push_back(findInstanceIdMapping(dbusServiceInstanceId));\r
+        ++knownServiceInstancesIteratorPair.first;\r
+    }\r
+\r
+    return addressesOfKnownServiceInstances;\r
+}\r
+\r
+void DBusServiceRegistry::onManagedPathsList(const CallStatus& status, DBusObjectToInterfaceDict managedObjects,\r
+        std::list<std::string>::iterator iter, std::shared_ptr<std::list<std::string>> list) {\r
+\r
+    auto objectPathIterator = managedObjects.begin();\r
+\r
+    while (objectPathIterator != managedObjects.end()) {\r
+        const std::string& serviceObjPath = objectPathIterator->first;\r
+        auto interfaceNameIterator = objectPathIterator->second.begin();\r
+\r
+        while (interfaceNameIterator != objectPathIterator->second.end()) {\r
+            const std::string& interfaceName = interfaceNameIterator->first;\r
+            dbusCachedProvidersForInterfaces_.insert( { interfaceName, { *iter, serviceObjPath } });\r
+            ++interfaceNameIterator;\r
+        }\r
+        ++objectPathIterator;\r
+    }\r
+\r
+    list->erase(iter);\r
+\r
+    if (list->size() == 0) {\r
+        readyMutex_.lock();\r
+        if (!ready) {\r
+            readyPromise_.set_value(true);\r
+            ready = true;\r
+        }\r
+        readyMutex_.unlock();\r
+    }\r
+}\r
+\r
+bool DBusServiceRegistry::isServiceInstanceAlive(const std::string& address) {\r
+       std::vector<std::string> parts = split(address, ':');\r
+       return isServiceInstanceAlive(parts[2], parts[1], parts[0]);\r
+}\r
+\r
+\r
+bool DBusServiceRegistry::isServiceInstanceAlive(const std::string& serviceInstanceID,\r
+                                                 const std::string& serviceInterfaceName,\r
+                                                 const std::string& serviceDomainName ) {\r
+       if (!isReadyBlocking()) {\r
+               return false;\r
+       }\r
+\r
+    if (serviceDomainName != "local" || !dbusConnection_->isConnected()) {\r
+        return false;\r
+    }\r
+\r
+    DBusServiceInstanceId serviceInstanceId = findInstanceIdMapping(serviceInstanceID);\r
+\r
+    auto knownInstancesForInterfaceIteratorPair = dbusCachedProvidersForInterfaces_.equal_range(serviceInterfaceName);\r
+\r
+    while(knownInstancesForInterfaceIteratorPair.first != knownInstancesForInterfaceIteratorPair.second) {\r
+        DBusServiceInstanceId knownServiceId = knownInstancesForInterfaceIteratorPair.first->second;\r
+        if(knownServiceId == serviceInstanceId) {\r
+            return true;\r
+        }\r
+        ++knownInstancesForInterfaceIteratorPair.first;\r
+    }\r
+\r
+    return false;\r
+}\r
+\r
+void DBusServiceRegistry::getManagedObjects(const std::string& dbusWellKnownBusName) {\r
+    auto callMessage = DBusMessage::createMethodCall(\r
+                    dbusWellKnownBusName.c_str(),\r
+                    "/",\r
+                    "org.freedesktop.DBus.ObjectManager",\r
+                    "GetManagedObjects",\r
+                    "");\r
+    dbusConnection_->sendDBusMessageWithReplyAsync(\r
+                    callMessage,\r
+                    DBusProxyAsyncCallbackHandler<DBusObjectToInterfaceDict>::create(\r
+                                    std::bind(\r
+                                                    &DBusServiceRegistry::onManagedPaths,\r
+                                                    this,\r
+                                                    std::placeholders::_1,\r
+                                                    std::placeholders::_2,\r
+                                                    dbusWellKnownBusName)), 100);\r
+\r
+}\r
+\r
+void DBusServiceRegistry::onManagedPaths(const CallStatus& status, DBusObjectToInterfaceDict managedObjects,\r
+               std::string dbusWellKnownBusName) {\r
+\r
+       auto objectPathIterator = managedObjects.begin();\r
+\r
+       while (objectPathIterator != managedObjects.end()) {\r
+               const std::string& serviceObjPath = objectPathIterator->first;\r
+               auto interfaceNameIterator = objectPathIterator->second.begin();\r
+\r
+               while (interfaceNameIterator != objectPathIterator->second.end()) {\r
+                       const std::string& interfaceName = interfaceNameIterator->first;\r
+                       dbusCachedProvidersForInterfaces_.insert( { interfaceName, { dbusWellKnownBusName, serviceObjPath } });\r
+                       updateListeners(dbusWellKnownBusName, serviceObjPath, interfaceName, true);\r
+                       ++interfaceNameIterator;\r
+               }\r
+\r
+               ++objectPathIterator;\r
+       }\r
+}\r
+\r
+void DBusServiceRegistry::updateListeners(const std::string& conName, const std::string& objName, const std::string& intName , bool available) {\r
+    auto found = availabilityCallbackList.equal_range(findCommonAPIAddressForDBusAddress(conName, objName, intName));\r
+    auto foundIter = found.first;\r
+    while (foundIter != found.second) {\r
+        foundIter->second(true);\r
+        foundIter++;\r
+    }\r
+\r
+}\r
+\r
+void DBusServiceRegistry::addProvidedServiceInstancesToCache(const std::string& dbusNames) {\r
+       getManagedObjects(dbusNames);\r
+}\r
+\r
+void DBusServiceRegistry::addProvidedServiceInstancesToCache(std::vector<std::string>& dbusNames) {\r
+\r
+    std::shared_ptr<std::list<std::string>> dbusList = std::make_shared<std::list<std::string>>(dbusNames.begin(), dbusNames.end());\r
+\r
+    auto iter = dbusList->begin();\r
+\r
+    while (iter != dbusList->end()) {\r
+\r
+            auto callMessage = DBusMessage::createMethodCall(\r
+                            iter->c_str(),\r
+                            "/",\r
+                            "org.freedesktop.DBus.ObjectManager",\r
+                            "GetManagedObjects",\r
+                            "");\r
+            dbusConnection_->sendDBusMessageWithReplyAsync(\r
+                            callMessage,\r
+                            DBusProxyAsyncCallbackHandler<DBusObjectToInterfaceDict>::create(\r
+                                            std::bind(\r
+                                                            &DBusServiceRegistry::onManagedPathsList,\r
+                                                            this,\r
+                                                            std::placeholders::_1,\r
+                                                            std::placeholders::_2,\r
+                                                            iter,\r
+                                                            dbusList)), 10);\r
+            iter++;\r
+    }\r
+}\r
+\r
+\r
+DBusServiceInstanceId DBusServiceRegistry::findInstanceIdMapping(const std::string& instanceId) const {\r
+    DBusServiceInstanceId instanceDescriptor;\r
+    findFallbackInstanceIdMapping(instanceId, instanceDescriptor.first, instanceDescriptor.second);\r
+    return instanceDescriptor;\r
+}\r
+\r
+std::string DBusServiceRegistry::findInstanceIdMapping(const DBusServiceInstanceId& dbusInstanceId) const {\r
+    return findFallbackInstanceIdMapping(dbusInstanceId.first, dbusInstanceId.second);\r
+}\r
+\r
+inline const bool isServiceName(const std::string& name) {\r
+    return name[0] != ':';\r
+}\r
+\r
+void DBusServiceRegistry::onDBusNameOwnerChangedEvent(const std::string& affectedName,\r
+                                                      const std::string& oldOwner,\r
+                                                      const std::string& newOwner) {\r
+    if (isServiceName(affectedName)) {\r
+        if(!oldOwner.empty()) {\r
+            removeProvidedServiceInstancesFromCache(affectedName);\r
+        }\r
+\r
+        if (!newOwner.empty()) {\r
+            addProvidedServiceInstancesToCache(affectedName);\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void DBusServiceRegistry::removeProvidedServiceInstancesFromCache(const std::string& dbusWellKnownBusName) {\r
+    auto providersForInterfacesIteratorPair = dbusCachedProvidersForInterfaces_.equal_range(dbusWellKnownBusName);\r
+\r
+    //Iteriere Ã¼ber (interfaceName, (serviceInstanceId))\r
+    while(providersForInterfacesIteratorPair.first != providersForInterfacesIteratorPair.second) {\r
+\r
+        DBusServiceInstanceId dbusInstanceId = providersForInterfacesIteratorPair.first->second;\r
+        if(dbusInstanceId.first == dbusWellKnownBusName) {\r
+            auto toErase = providersForInterfacesIteratorPair.first;\r
+            ++providersForInterfacesIteratorPair.first;\r
+            dbusCachedProvidersForInterfaces_.erase(toErase);\r
+        }\r
+\r
+        ++providersForInterfacesIteratorPair.first;\r
+    }\r
+}\r
+\r
+void DBusServiceRegistry::onListNames(const CommonAPI::CallStatus& callStatus, std::vector<std::string> existingBusConnections) {\r
+\r
+       if (callStatus == CallStatus::SUCCESS) {\r
+               std::vector<std::string> dbusLivingServiceBusNames;\r
+               for (const std::string& connectionName : existingBusConnections) {\r
+                       const bool isWellKnownName = (connectionName[0] != ':');\r
+\r
+                       if (isWellKnownName) {\r
+                               dbusLivingServiceBusNames.push_back(connectionName);\r
+                       }\r
+               }\r
+               addProvidedServiceInstancesToCache(dbusLivingServiceBusNames);\r
+       }\r
+}\r
+\r
+void DBusServiceRegistry::cacheAllServices() {\r
+    CommonAPI::CallStatus callStatus;\r
+    std::vector<std::string> existingBusConnections;\r
+    dbusConnection_->getDBusDaemonProxy()->listNames(callStatus, existingBusConnections);\r
+    onListNames(callStatus, existingBusConnections);\r
+}\r
+\r
+\r
+}// namespace DBus\r
+} // namespace CommonAPI\r
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusServiceRegistry.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusServiceRegistry.h
new file mode 100644 (file)
index 0000000..f4c9a77
--- /dev/null
@@ -0,0 +1,116 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
+#ifndef COMMONAPI_DBUS_DBUS_SERVICE_REGISTRY_H_\r
+#define COMMONAPI_DBUS_DBUS_SERVICE_REGISTRY_H_\r
+\r
+\r
+#include <CommonAPI/types.h>\r
+#include <CommonAPI/Attribute.h>\r
+\r
+#include "DBusConnection.h"\r
+\r
+#include <unordered_map>\r
+#include <map>\r
+#include <unordered_set>\r
+#include <string>\r
+#include <vector>\r
+#include <memory>\r
+#include <list>\r
+#include <mutex>\r
+\r
+namespace CommonAPI {\r
+namespace DBus {\r
+\r
+typedef Event<std::string, std::string, std::string> NameOwnerChangedEvent;\r
+\r
+typedef Event<std::string, std::string, std::string>::Subscription NameOwnerChangedEventSubscription;\r
+\r
+typedef std::pair<std::string, std::string> DBusServiceInstanceId;\r
+\r
+typedef std::unordered_map<std::string, int> PropertyDictStub;\r
+typedef std::unordered_map<std::string, PropertyDictStub> InterfaceToPropertyDict;\r
+typedef std::unordered_map<std::string, InterfaceToPropertyDict> DBusObjectToInterfaceDict;\r
+\r
+class DBusConnection;\r
+class DBusDaemonProxy;\r
+\r
+\r
+class DBusServiceRegistry {\r
+ public:\r
+    static constexpr const char* getManagedObjectsDBusSignature_ = "a{oa{sa{sv}}}";\r
+\r
+    DBusServiceRegistry() = delete;\r
+    DBusServiceRegistry(const DBusServiceRegistry&) = delete;\r
+    DBusServiceRegistry& operator=(const DBusServiceRegistry&) = delete;\r
+\r
+    DBusServiceRegistry(std::shared_ptr<DBusConnection> connection);\r
+    ~DBusServiceRegistry();\r
+\r
+    std::vector<std::string> getAvailableServiceInstances(const std::string& interfaceName,\r
+                                                          const std::string& domainName = "local");\r
+\r
+    bool isServiceInstanceAlive(const std::string& instanceID,\r
+                                const std::string& interfaceName,\r
+                                const std::string& domainName = "local");\r
+\r
+    bool isServiceInstanceAlive(const std::string& address);\r
+\r
+    bool isReady();\r
+\r
+    bool isReadyBlocking();\r
+\r
+    void registerAvailabilityListener(const std::string& service, const std::function<void(bool)>& listener);\r
+\r
+    std::future<bool>& getReadyFuture();\r
+\r
+    DBusServiceStatusEvent& getServiceStatusEvent();\r
+\r
+ private:\r
+    void cacheAllServices();\r
+\r
+    void removeProvidedServiceInstancesFromCache(const std::string& serviceBusName);\r
+    void addProvidedServiceInstancesToCache(std::vector<std::string>& dbusNames);\r
+    void addProvidedServiceInstancesToCache(const std::string& dbusNames);\r
+    void addAllProvidedServiceInstancesToCache(const std::vector<std::string>& serviceBusNames);\r
+\r
+    void getManagedObjects(const std::string& serviceBusName);\r
+\r
+    void onDBusNameOwnerChangedEvent(const std::string& name, const std::string& oldOwner, const std::string& newOwner);\r
+\r
+    bool isRemoteServiceVersionMatchingLocalVersion(const std::string& serviceBusName, const std::string& serviceInterfaceName);\r
+    bool isServiceInstanceAliveHelper(const std::string& connectionName) const;\r
+\r
+    DBusServiceInstanceId findInstanceIdMapping(const std::string& instanceId) const;\r
+    std::string findInstanceIdMapping(const DBusServiceInstanceId& dbusInstanceId) const;\r
+\r
+    void onManagedPaths(const CallStatus& status, DBusObjectToInterfaceDict replyMessage, std::string dbusWellKnownBusName);\r
+    void onManagedPathsList(const CallStatus& status, DBusObjectToInterfaceDict managedObjects, std::list<std::string>::iterator iter, std::shared_ptr<std::list<std::string>> list);\r
+\r
+    std::multimap<std::string, DBusServiceInstanceId> dbusCachedProvidersForInterfaces_;\r
+\r
+    std::shared_ptr<DBusConnection> dbusConnection_;\r
+\r
+    std::unordered_multimap<std::string, std::function<void(bool)>> availabilityCallbackList;\r
+\r
+    bool ready;\r
+\r
+    void onListNames(const CommonAPI::CallStatus&, std::vector<std::string>);\r
+\r
+    NameOwnerChangedEvent::Subscription dbusNameOwnerChangedEventSubscription_;\r
+\r
+    void updateListeners(const std::string& conName, const std::string& objName, const std::string& intName , bool available);\r
+\r
+    mutable std::future<bool> readyFuture_;\r
+    mutable std::promise<bool> readyPromise_;\r
+\r
+    std::mutex readyMutex_;\r
+\r
+    DBusServiceStatusEvent serviceStatusEvent_;\r
+};\r
+\r
+\r
+} // namespace DBus\r
+} // namespace CommonAPI\r
+\r
+#endif // COMMONAPI_DBUS_DBUS_SERVICE_REGISTRY_H_\r
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusServiceStatusEvent.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusServiceStatusEvent.cpp
new file mode 100644 (file)
index 0000000..1ae833a
--- /dev/null
@@ -0,0 +1,44 @@
+/* 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 "DBusServiceStatusEvent.h"
+#include "DBusServiceRegistry.h"
+#include <cassert>
+
+namespace CommonAPI {
+namespace DBus {
+
+DBusServiceStatusEvent::DBusServiceStatusEvent(std::shared_ptr<DBusServiceRegistry> registry) :
+                registry_(registry) {
+}
+
+void DBusServiceStatusEvent::onFirstListenerAdded(const std::string& serviceName, const Listener& listener) {
+    if (registry_) {
+        registry_->registerAvailabilityListener(serviceName, std::bind(
+                        &DBusServiceStatusEvent::availabilityEvent,
+                        this,
+                        serviceName,
+                        std::placeholders::_1));
+    }
+}
+
+void DBusServiceStatusEvent::availabilityEvent(const std::string& name, const bool& available) {
+
+    const AvailabilityStatus availabilityStatus = !available ? AvailabilityStatus::NOT_AVAILABLE :
+                                                               AvailabilityStatus::AVAILABLE;
+    notifyListeners(name, availabilityStatus);
+}
+
+void DBusServiceStatusEvent::onListenerAdded(const std::string& name, const Listener& listener) {
+    if (registry_) {
+        const AvailabilityStatus availabilityStatus =
+                        !registry_->isServiceInstanceAlive(name) ? AvailabilityStatus::NOT_AVAILABLE :
+                                        AvailabilityStatus::AVAILABLE;
+
+        notifyListeners(name, availabilityStatus);
+    }
+
+}
+
+} // namespace DBus
+} // namespace CommonAPI
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusServiceStatusEvent.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusServiceStatusEvent.h
new file mode 100644 (file)
index 0000000..0c4f6e9
--- /dev/null
@@ -0,0 +1,39 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
+#ifndef COMMONAPI_DBUS_DBUS_SERVICE_STATUS_EVENT_H_\r
+#define COMMONAPI_DBUS_DBUS_SERVICE_STATUS_EVENT_H_\r
+\r
+#include "DBusMultiEvent.h"\r
+\r
+#include <CommonAPI/Event.h>\r
+#include <CommonAPI/types.h>\r
+\r
+#include <string>\r
+#include <memory>\r
+\r
+namespace CommonAPI {\r
+namespace DBus {\r
+\r
+\r
+class DBusServiceRegistry;\r
+\r
+class DBusServiceStatusEvent: public DBusMultiEvent<AvailabilityStatus> {\r
+ public:\r
+       DBusServiceStatusEvent(std::shared_ptr<DBusServiceRegistry> registry);\r
+\r
+ protected:\r
+       void onFirstListenerAdded(const std::string& serviceName, const Listener& listener);\r
+       void onListenerAdded(const std::string& serviceName, const Listener& listener);\r
+\r
+ private:\r
+       void availabilityEvent(const std::string& name, const bool& available);\r
+\r
+       std::shared_ptr<DBusServiceRegistry> registry_;\r
+};\r
+\r
+} // namespace DBus\r
+} // namespace CommonAPI\r
+\r
+#endif // COMMONAPI_DBUS_DBUS_SERVICE_STATUS_EVENT_H_\r
+\r
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusStubAdapter.cpp b/CommonAPI-DBus/src/CommonAPI/DBus/DBusStubAdapter.cpp
new file mode 100644 (file)
index 0000000..b217871
--- /dev/null
@@ -0,0 +1,103 @@
+/* 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 "DBusStubAdapter.h"
+
+#include <dbus/dbus-protocol.h>
+
+#include <cassert>
+#include <functional>
+#include <sstream>
+
+namespace CommonAPI {
+namespace DBus {
+
+const std::string DBusStubAdapter::domain_ = "local";
+
+DBusStubAdapter::DBusStubAdapter(const std::string& dbusBusName,
+                                 const std::string& dbusObjectPath,
+                                 const std::string& interfaceName,
+                                 const std::shared_ptr<DBusProxyConnection>& dbusConnection) :
+                dbusBusName_(dbusBusName),
+                dbusObjectPath_(dbusObjectPath),
+                interfaceName_(interfaceName),
+                dbusConnection_(dbusConnection),
+                isInitialized_(false) {
+
+    assert(!dbusBusName_.empty());
+    assert(!interfaceName_.empty());
+    assert(!dbusObjectPath_.empty());
+    assert(dbusObjectPath_[0] == '/');
+    assert(!interfaceName.empty());
+    assert(dbusConnection_);
+}
+
+DBusStubAdapter::~DBusStubAdapter() {
+       assert(dbusConnection_);
+       assert(isInitialized_);
+
+    dbusConnection_->getDBusObjectManager()->unregisterInterfaceHandler(dbusIntrospectionInterfaceHandlerToken_);
+       dbusConnection_->getDBusObjectManager()->unregisterInterfaceHandler(dbusInterfaceHandlerToken_);
+}
+
+void DBusStubAdapter::init() {
+    dbusIntrospectionInterfaceHandlerToken_ = dbusConnection_->getDBusObjectManager()->registerInterfaceHandler(
+                    dbusObjectPath_,
+                    "org.freedesktop.DBus.Introspectable",
+                    std::bind(&DBusStubAdapter::onIntrospectionInterfaceDBusMessage, this, std::placeholders::_1));
+
+    dbusInterfaceHandlerToken_ = dbusConnection_->getDBusObjectManager()->registerInterfaceHandler(
+                    dbusObjectPath_,
+                    interfaceName_,
+                    std::bind(&DBusStubAdapter::onInterfaceDBusMessage, this, std::placeholders::_1));
+
+    isInitialized_ = true;
+}
+
+const std::string DBusStubAdapter::getAddress() const {
+       return domain_ + ":" + interfaceName_ + ":" + dbusBusName_;
+}
+
+const std::string& DBusStubAdapter::getDomain() const {
+    return domain_;
+}
+
+const std::string& DBusStubAdapter::getServiceId() const {
+    return interfaceName_;
+}
+
+const std::string& DBusStubAdapter::getInstanceId() const {
+    return dbusObjectPath_;
+}
+
+bool DBusStubAdapter::onIntrospectionInterfaceDBusMessage(const DBusMessage& dbusMessage) {
+    bool dbusMessageHandled = false;
+
+    if (dbusMessage.isMethodCallType() && dbusMessage.hasMemberName("Introspect")) {
+        std::stringstream xmlData(std::ios_base::out);
+        xmlData << "<!DOCTYPE node PUBLIC \"" DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "\"\n\""
+                        DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER"\">\n"
+                   "<node name=\"" << dbusObjectPath_ << "\">\n"
+                       "<interface name=\"org.freedesktop.DBus.Introspectable\">\n"
+                           "<method name=\"Introspect\">\n"
+                               "<arg type=\"s\" name=\"xml_data\" direction=\"out\"/>\n"
+                           "</method>\n"
+                       "</interface>\n"
+                       "<interface name=\"" << interfaceName_ << "\">\n"
+                           << getMethodsDBusIntrospectionXmlData() << "\n"
+                       "</interface>\n"
+                   "</node>";
+
+        DBusMessage dbusMessageReply = dbusMessage.createMethodReturn("s");
+        DBusOutputStream dbusOutputStream(dbusMessageReply);
+        dbusOutputStream << xmlData.str();
+        dbusOutputStream.flush();
+
+        dbusMessageHandled = dbusConnection_->sendDBusMessage(dbusMessageReply);
+    }
+
+    return dbusMessageHandled;
+}
+
+} // namespace dbus
+} // namespace CommonAPI
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusStubAdapter.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusStubAdapter.h
new file mode 100644 (file)
index 0000000..90c12f5
--- /dev/null
@@ -0,0 +1,69 @@
+/* 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_DBUS_DBUS_STUB_ADAPTER_H_
+#define COMMONAPI_DBUS_DBUS_STUB_ADAPTER_H_
+
+#include "DBusConnection.h"
+
+#include <CommonAPI/Stub.h>
+#include <CommonAPI/DBus/DBusMessage.h>
+
+#include <string>
+#include <memory>
+
+namespace CommonAPI {
+namespace DBus {
+
+class DBusStubAdapter: virtual public CommonAPI::StubAdapter {
+ public:
+    DBusStubAdapter(const std::string& dbusBusName,
+                    const std::string& dbusObjectPath,
+                    const std::string& interfaceName,
+                    const std::shared_ptr<DBusProxyConnection>& dbusConnection);
+
+    virtual ~DBusStubAdapter();
+
+    virtual void init();
+
+    virtual const std::string getAddress() const;
+    virtual const std::string& getDomain() const;
+    virtual const std::string& getServiceId() const;
+    virtual const std::string& getInstanceId() const;
+
+    inline const std::string& getObjectPath() const;
+
+    inline const std::shared_ptr<DBusProxyConnection>& getDBusConnection() const;
+
+ protected:
+    virtual const char* getMethodsDBusIntrospectionXmlData() const = 0;
+    virtual bool onInterfaceDBusMessage(const DBusMessage& dbusMessage) = 0;
+
+ private:
+    bool onIntrospectionInterfaceDBusMessage(const DBusMessage& dbusMessage);
+
+    const std::string dbusBusName_;
+    const std::string dbusObjectPath_;
+    const std::string interfaceName_;
+    const std::shared_ptr<DBusProxyConnection> dbusConnection_;
+
+    bool isInitialized_;
+
+    DBusInterfaceHandlerToken dbusIntrospectionInterfaceHandlerToken_;
+    DBusInterfaceHandlerToken dbusInterfaceHandlerToken_;
+
+    static const std::string domain_;
+};
+
+const std::string& DBusStubAdapter::getObjectPath() const {
+    return dbusObjectPath_;
+}
+
+const std::shared_ptr<DBusProxyConnection>& DBusStubAdapter::getDBusConnection() const {
+    return dbusConnection_;
+}
+
+} // namespace dbus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_STUB_ADAPTER_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusStubAdapterHelper.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusStubAdapterHelper.h
new file mode 100644 (file)
index 0000000..0f20bd5
--- /dev/null
@@ -0,0 +1,362 @@
+/* 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_DBUS_DBUS_STUB_ADAPTER_HELPER_H_
+#define COMMONAPI_DBUS_DBUS_STUB_ADAPTER_HELPER_H_
+
+#include "DBusStubAdapter.h"
+#include "DBusInputStream.h"
+#include "DBusOutputStream.h"
+#include "DBusHelper.h"
+
+#include <iostream>
+#include <memory>
+#include <initializer_list>
+#include <tuple>
+#include <unordered_map>
+
+namespace CommonAPI {
+namespace DBus {
+
+template <typename _StubClass>
+class DBusStubAdapterHelper: public DBusStubAdapter, public std::enable_shared_from_this<typename _StubClass::StubAdapterType> {
+ public:
+    typedef typename _StubClass::StubAdapterType StubAdapterType;
+    typedef typename _StubClass::RemoteEventHandlerType RemoteEventHandlerType;
+
+    class StubDispatcher {
+     public:
+        virtual ~StubDispatcher() { }
+        virtual bool dispatchDBusMessage(const DBusMessage& dbusMessage, DBusStubAdapterHelper<_StubClass>& dbusStubAdapterHelper) = 0;
+    };
+
+ public:
+    DBusStubAdapterHelper(const std::string& dbusBusName,
+                          const std::string& dbusObjectPath,
+                          const std::string& interfaceName,
+                          const std::shared_ptr<DBusProxyConnection>& dbusConnection,
+                          std::shared_ptr<_StubClass> stub):
+                    DBusStubAdapter(dbusBusName, dbusObjectPath, interfaceName, dbusConnection),
+                    stub_(stub) {
+    }
+
+    virtual ~DBusStubAdapterHelper() { }
+
+    virtual void init() {
+        DBusStubAdapter::init();
+        remoteEventHandler_ = stub_->initStubAdapter(getStubAdapter());
+    }
+
+    inline std::shared_ptr<StubAdapterType> getStubAdapter() {
+        return this->shared_from_this();
+    }
+
+    inline const std::shared_ptr<_StubClass>& getStub() {
+        return stub_;
+    }
+
+    inline RemoteEventHandlerType* getRemoteEventHandler() {
+        return remoteEventHandler_;
+    }
+
+ protected:
+    // interfaceMemberName, interfaceMemberSignature
+    typedef std::pair<const char*, const char*> DBusInterfaceMemberPath;
+    typedef std::unordered_map<DBusInterfaceMemberPath, StubDispatcher*> StubDispatcherTable;
+
+    virtual bool onInterfaceDBusMessage(const DBusMessage& dbusMessage) {
+        const char* interfaceMemberName = dbusMessage.getMemberName();
+        const char* interfaceMemberSignature = dbusMessage.getSignatureString();
+
+        assert(interfaceMemberName);
+        assert(interfaceMemberSignature);
+
+        DBusInterfaceMemberPath dbusInterfaceMemberPath(interfaceMemberName, interfaceMemberSignature);
+        auto findIterator = this->stubDispatcherTable_.find(dbusInterfaceMemberPath);
+        const bool foundInterfaceMemberHandler = (findIterator != this->stubDispatcherTable_.end());
+        bool dbusMessageHandled = false;
+
+        if (foundInterfaceMemberHandler) {
+            StubDispatcher* stubDispatcher = findIterator->second;
+            dbusMessageHandled = stubDispatcher->dispatchDBusMessage(dbusMessage, *this);
+        }
+
+        return dbusMessageHandled;
+    }
+
+    std::shared_ptr<_StubClass> stub_;
+    RemoteEventHandlerType* remoteEventHandler_;
+    static const StubDispatcherTable stubDispatcherTable_;
+};
+
+template< class >
+struct DBusStubSignalHelper;
+
+template<template<class ...> class _In, class... _InArgs>
+struct DBusStubSignalHelper<_In<_InArgs...>> {
+    template <typename _DBusStub = DBusStubAdapter>
+    static bool sendSignal(const _DBusStub& dbusStub,
+                    const char* signalName,
+                    const char* signalSignature,
+                    const _InArgs&... inArgs) {
+        DBusMessage dbusMessage = DBusMessage::createSignal(
+                        dbusStub.getObjectPath().c_str(),
+                        dbusStub.getInterfaceName(),
+                        signalName,
+                        signalSignature);
+
+        if (sizeof...(_InArgs) > 0) {
+            DBusOutputStream outputStream(dbusMessage);
+            const bool success = DBusSerializableArguments<_InArgs...>::serialize(outputStream, inArgs...);
+            if (!success) {
+                return false;
+            }
+            outputStream.flush();
+        }
+
+        const bool dbusMessageSent = dbusStub.getDBusConnection()->sendDBusMessage(dbusMessage);
+        return dbusMessageSent;
+    }
+};
+
+
+
+template< class, class >
+class DBusMethodStubDispatcher;
+
+template <
+    typename _StubClass,
+    template <class...> class _In, class... _InArgs>
+class DBusMethodStubDispatcher<_StubClass, _In<_InArgs...> >: public DBusStubAdapterHelper<_StubClass>::StubDispatcher {
+ public:
+    typedef DBusStubAdapterHelper<_StubClass> DBusStubAdapterHelperType;
+    typedef void (_StubClass::*_StubFunctor)(_InArgs...);
+
+    DBusMethodStubDispatcher(_StubFunctor stubFunctor):
+            stubFunctor_(stubFunctor) {
+    }
+
+    bool dispatchDBusMessage(const DBusMessage& dbusMessage, DBusStubAdapterHelperType& dbusStubAdapterHelper) {
+        return handleDBusMessage(dbusMessage, dbusStubAdapterHelper, typename make_sequence<sizeof...(_InArgs)>::type());
+    }
+
+ private:
+    template <int... _InArgIndices, int... _OutArgIndices>
+    inline bool handleDBusMessage(const DBusMessage& dbusMessage,
+                                  DBusStubAdapterHelperType& dbusStubAdapterHelper,
+                                  index_sequence<_InArgIndices...>) const {
+        std::tuple<_InArgs...> argTuple;
+
+        if (sizeof...(_InArgs) > 0) {
+            DBusInputStream dbusInputStream(dbusMessage);
+            const bool success = DBusSerializableArguments<_InArgs...>::deserialize(dbusInputStream, std::get<_InArgIndices>(argTuple)...);
+            if (!success)
+                return false;
+        }
+
+        (dbusStubAdapterHelper.getStub().get()->*stubFunctor_)(std::move(std::get<_InArgIndices>(argTuple))...);
+
+        return true;
+    }
+
+    _StubFunctor stubFunctor_;
+};
+
+
+template< class, class, class >
+class DBusMethodWithReplyStubDispatcher;
+
+template <
+    typename _StubClass,
+    template <class...> class _In, class... _InArgs,
+    template <class...> class _Out, class... _OutArgs>
+class DBusMethodWithReplyStubDispatcher<_StubClass, _In<_InArgs...>, _Out<_OutArgs...> >:
+            public DBusStubAdapterHelper<_StubClass>::StubDispatcher {
+ public:
+    typedef DBusStubAdapterHelper<_StubClass> DBusStubAdapterHelperType;
+    typedef void (_StubClass::*_StubFunctor)(_InArgs..., _OutArgs&...);
+
+    DBusMethodWithReplyStubDispatcher(_StubFunctor stubFunctor, const char* dbusReplySignature):
+            stubFunctor_(stubFunctor),
+            dbusReplySignature_(dbusReplySignature) {
+    }
+
+    bool dispatchDBusMessage(const DBusMessage& dbusMessage, DBusStubAdapterHelperType& dbusStubAdapterHelper) {
+        return handleDBusMessage(
+                        dbusMessage,
+                        dbusStubAdapterHelper,
+                        typename make_sequence_range<sizeof...(_InArgs), 0>::type(),
+                        typename make_sequence_range<sizeof...(_OutArgs), sizeof...(_InArgs)>::type());
+    }
+
+ private:
+    template <int... _InArgIndices, int... _OutArgIndices>
+    inline bool handleDBusMessage(const DBusMessage& dbusMessage,
+                                  DBusStubAdapterHelperType& dbusStubAdapterHelper,
+                                  index_sequence<_InArgIndices...>,
+                                  index_sequence<_OutArgIndices...>) const {
+        std::tuple<_InArgs..., _OutArgs...> argTuple;
+
+        if (sizeof...(_InArgs) > 0) {
+            DBusInputStream dbusInputStream(dbusMessage);
+            const bool success = DBusSerializableArguments<_InArgs...>::deserialize(dbusInputStream, std::get<_InArgIndices>(argTuple)...);
+            if (!success)
+                return false;
+        }
+
+        (dbusStubAdapterHelper.getStub().get()->*stubFunctor_)(std::move(std::get<_InArgIndices>(argTuple))..., std::get<_OutArgIndices>(argTuple)...);
+
+        DBusMessage dbusMessageReply = dbusMessage.createMethodReturn(dbusReplySignature_);
+
+        if (sizeof...(_OutArgs) > 0) {
+            DBusOutputStream dbusOutputStream(dbusMessageReply);
+            const bool success = DBusSerializableArguments<_OutArgs...>::serialize(dbusOutputStream, std::get<_OutArgIndices>(argTuple)...);
+            if (!success)
+                return false;
+
+            dbusOutputStream.flush();
+        }
+
+        return dbusStubAdapterHelper.getDBusConnection()->sendDBusMessage(dbusMessageReply);
+    }
+
+    _StubFunctor stubFunctor_;
+    const char* dbusReplySignature_;
+};
+
+
+template <typename _StubClass, typename _AttributeType>
+class DBusGetAttributeStubDispatcher: public DBusStubAdapterHelper<_StubClass>::StubDispatcher {
+ public:
+    typedef DBusStubAdapterHelper<_StubClass> DBusStubAdapterHelperType;
+    typedef const _AttributeType& (_StubClass::*GetStubFunctor)();
+
+    DBusGetAttributeStubDispatcher(GetStubFunctor getStubFunctor, const char* dbusSignature):
+        getStubFunctor_(getStubFunctor),
+        dbusSignature_(dbusSignature) {
+    }
+
+    bool dispatchDBusMessage(const DBusMessage& dbusMessage, DBusStubAdapterHelperType& dbusStubAdapterHelper) {
+        return sendAttributeValueReply(dbusMessage, dbusStubAdapterHelper);
+    }
+
+ protected:
+    inline bool sendAttributeValueReply(const DBusMessage& dbusMessage, DBusStubAdapterHelperType& dbusStubAdapterHelper) {
+        DBusMessage dbusMessageReply = dbusMessage.createMethodReturn(dbusSignature_);
+        DBusOutputStream dbusOutputStream(dbusMessageReply);
+
+        dbusOutputStream << (dbusStubAdapterHelper.getStub().get()->*getStubFunctor_)();
+        dbusOutputStream.flush();
+
+        return dbusStubAdapterHelper.getDBusConnection()->sendDBusMessage(dbusMessageReply);
+    }
+
+    GetStubFunctor getStubFunctor_;
+    const char* dbusSignature_;
+};
+
+
+template <typename _StubClass, typename _AttributeType>
+class DBusSetAttributeStubDispatcher: public DBusGetAttributeStubDispatcher<_StubClass, _AttributeType> {
+ public:
+    typedef typename DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::DBusStubAdapterHelperType DBusStubAdapterHelperType;
+    typedef typename DBusStubAdapterHelperType::RemoteEventHandlerType RemoteEventHandlerType;
+
+    typedef typename DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::GetStubFunctor GetStubFunctor;
+    typedef bool (RemoteEventHandlerType::*OnRemoteSetFunctor)(_AttributeType);
+    typedef void (RemoteEventHandlerType::*OnRemoteChangedFunctor)();
+
+    DBusSetAttributeStubDispatcher(GetStubFunctor getStubFunctor,
+                                   OnRemoteSetFunctor onRemoteSetFunctor,
+                                   OnRemoteChangedFunctor onRemoteChangedFunctor,
+                                   const char* dbusSignature) :
+                    DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>(getStubFunctor, dbusSignature),
+                    onRemoteSetFunctor_(onRemoteSetFunctor),
+                    onRemoteChangedFunctor_(onRemoteChangedFunctor) {
+    }
+
+    bool dispatchDBusMessage(const DBusMessage& dbusMessage, DBusStubAdapterHelperType& dbusStubAdapterHelper) {
+        bool attributeValueChanged;
+
+        if (!setAttributeValue(dbusMessage, dbusStubAdapterHelper, attributeValueChanged))
+            return false;
+
+        if (attributeValueChanged)
+            notifyOnRemoteChanged(dbusStubAdapterHelper);
+
+        return true;
+    }
+
+ protected:
+    inline bool setAttributeValue(const DBusMessage& dbusMessage, DBusStubAdapterHelperType& dbusStubAdapterHelper, bool& attributeValueChanged) {
+        DBusInputStream dbusInputStream(dbusMessage);
+        _AttributeType attributeValue;
+        dbusInputStream >> attributeValue;
+        if (dbusInputStream.hasError())
+            return false;
+
+        attributeValueChanged = (dbusStubAdapterHelper.getRemoteEventHandler()->*onRemoteSetFunctor_)(std::move(attributeValue));
+
+        return this->sendAttributeValueReply(dbusMessage, dbusStubAdapterHelper);
+    }
+
+    inline void notifyOnRemoteChanged(DBusStubAdapterHelperType& dbusStubAdapterHelper) {
+        (dbusStubAdapterHelper.getRemoteEventHandler()->*onRemoteChangedFunctor_)();
+    }
+
+    inline const _AttributeType& getAttributeValue(DBusStubAdapterHelperType& dbusStubAdapterHelper) {
+        return (dbusStubAdapterHelper.getStub().get()->*(this->getStubFunctor_))();
+    }
+
+    const OnRemoteSetFunctor onRemoteSetFunctor_;
+    const OnRemoteChangedFunctor onRemoteChangedFunctor_;
+};
+
+
+template <typename _StubClass, typename _AttributeType>
+class DBusSetObservableAttributeStubDispatcher: public DBusSetAttributeStubDispatcher<_StubClass, _AttributeType> {
+ public:
+    typedef typename DBusSetAttributeStubDispatcher<_StubClass, _AttributeType>::DBusStubAdapterHelperType DBusStubAdapterHelperType;
+    typedef typename DBusStubAdapterHelperType::StubAdapterType StubAdapterType;
+
+    typedef typename DBusSetAttributeStubDispatcher<_StubClass, _AttributeType>::GetStubFunctor GetStubFunctor;
+    typedef typename DBusSetAttributeStubDispatcher<_StubClass, _AttributeType>::OnRemoteSetFunctor OnRemoteSetFunctor;
+    typedef typename DBusSetAttributeStubDispatcher<_StubClass, _AttributeType>::OnRemoteChangedFunctor OnRemoteChangedFunctor;
+    typedef void (StubAdapterType::*FireChangedFunctor)(const _AttributeType&);
+
+    DBusSetObservableAttributeStubDispatcher(GetStubFunctor getStubFunctor,
+                                             OnRemoteSetFunctor onRemoteSetFunctor,
+                                             OnRemoteChangedFunctor onRemoteChangedFunctor,
+                                             FireChangedFunctor fireChangedFunctor,
+                                             const char* dbusSignature) :
+                    DBusSetAttributeStubDispatcher<_StubClass, _AttributeType>(getStubFunctor,
+                                                                               onRemoteSetFunctor,
+                                                                               onRemoteChangedFunctor,
+                                                                               dbusSignature),
+                    fireChangedFunctor_(fireChangedFunctor) {
+    }
+
+    bool dispatchDBusMessage(const DBusMessage& dbusMessage, DBusStubAdapterHelperType& dbusStubAdapterHelper) {
+        bool attributeValueChanged;
+        if (!this->setAttributeValue(dbusMessage, dbusStubAdapterHelper, attributeValueChanged))
+            return false;
+
+        if (attributeValueChanged) {
+            fireAttributeValueChanged(dbusStubAdapterHelper);
+            this->notifyOnRemoteChanged(dbusStubAdapterHelper);
+        }
+        return true;
+    }
+
+ private:
+    inline void fireAttributeValueChanged(DBusStubAdapterHelperType& dbusStubAdapterHelper) {
+        (dbusStubAdapterHelper.getStubAdapter().get()->*fireChangedFunctor_)(this->getAttributeValue(dbusStubAdapterHelper));
+    }
+
+    const FireChangedFunctor fireChangedFunctor_;
+};
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif // COMMONAPI_DBUS_DBUS_STUB_ADAPTER_HELPER_H_
diff --git a/CommonAPI-DBus/src/CommonAPI/DBus/DBusUtils.h b/CommonAPI-DBus/src/CommonAPI/DBus/DBusUtils.h
new file mode 100644 (file)
index 0000000..fa26f0c
--- /dev/null
@@ -0,0 +1,64 @@
+/* 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 DBUSUTILS_H_
+#define DBUSUTILS_H_
+
+#include <algorithm>
+#include <string>
+#include <sstream>
+#include <vector>
+
+namespace CommonAPI {
+namespace DBus {
+
+inline std::vector<std::string>& split(const std::string& s, char delim, std::vector<std::string>& elems) {
+    std::istringstream ss(s);
+    std::string item;
+    while (std::getline(ss, item, delim)) {
+        elems.push_back(item);
+    }
+    return elems;
+}
+
+inline std::vector<std::string> split(const std::string& s, char delim) {
+    std::vector<std::string> elems;
+    return split(s, delim, elems);
+}
+
+inline void findFallbackInstanceIdMapping(const std::string& instanceId,
+                                          std::string& connectionName,
+                                          std::string& objectPath) {
+    connectionName = instanceId;
+    objectPath = '/' + instanceId;
+    std::replace(objectPath.begin(), objectPath.end(), '.', '/');
+}
+
+inline std::string findCommonAPIAddressForDBusAddress(const std::string& conName,
+                                               const std::string& objName,
+                                               const std::string& intName) {
+
+    return "local:" + intName + ":" + conName;
+}
+
+inline std::string findFallbackInstanceIdMapping(const std::string& connectionName, const std::string& objectPath) {
+    return connectionName;
+}
+
+template<typename _FutureWaitType>
+inline bool checkReady(_FutureWaitType&);
+
+template<>
+inline bool checkReady<bool>(bool& returnedValue) {
+       return returnedValue;
+}
+
+template<>
+inline bool checkReady<std::future_status>(std::future_status& returnedValue) {
+       return returnedValue == std::future_status::ready;
+}
+
+}
+}
+
+#endif /* DBUSUTILS_H_ */
diff --git a/CommonAPI-DBus/src/murmurhash/MurmurHash3.cpp b/CommonAPI-DBus/src/murmurhash/MurmurHash3.cpp
new file mode 100644 (file)
index 0000000..c2d2fb7
--- /dev/null
@@ -0,0 +1,335 @@
+//-----------------------------------------------------------------------------\r
+// MurmurHash3 was written by Austin Appleby, and is placed in the public\r
+// domain. The author hereby disclaims copyright to this source code.\r
+\r
+// Note - The x86 and x64 versions do _not_ produce the same results, as the\r
+// algorithms are optimized for their respective platforms. You can still\r
+// compile and run any of them on any platform, but your performance with the\r
+// non-native version will be less than optimal.\r
+\r
+#include "MurmurHash3.h"\r
+\r
+//-----------------------------------------------------------------------------\r
+// Platform-specific functions and macros\r
+\r
+// Microsoft Visual Studio\r
+\r
+#if defined(_MSC_VER)\r
+\r
+#define FORCE_INLINE   __forceinline\r
+\r
+#include <stdlib.h>\r
+\r
+#define ROTL32(x,y)    _rotl(x,y)\r
+#define ROTL64(x,y)    _rotl64(x,y)\r
+\r
+#define BIG_CONSTANT(x) (x)\r
+\r
+// Other compilers\r
+\r
+#else  // defined(_MSC_VER)\r
+\r
+#define        FORCE_INLINE __attribute__((always_inline))\r
+\r
+inline uint32_t rotl32 ( uint32_t x, int8_t r )\r
+{\r
+  return (x << r) | (x >> (32 - r));\r
+}\r
+\r
+inline uint64_t rotl64 ( uint64_t x, int8_t r )\r
+{\r
+  return (x << r) | (x >> (64 - r));\r
+}\r
+\r
+#define        ROTL32(x,y)     rotl32(x,y)\r
+#define ROTL64(x,y)    rotl64(x,y)\r
+\r
+#define BIG_CONSTANT(x) (x##LLU)\r
+\r
+#endif // !defined(_MSC_VER)\r
+\r
+//-----------------------------------------------------------------------------\r
+// Block read - if your platform needs to do endian-swapping or can only\r
+// handle aligned reads, do the conversion here\r
+\r
+inline uint32_t getblock ( const uint32_t * p, int i )\r
+{\r
+  return p[i];\r
+}\r
+\r
+inline uint64_t getblock ( const uint64_t * p, int i )\r
+{\r
+  return p[i];\r
+}\r
+\r
+//-----------------------------------------------------------------------------\r
+// Finalization mix - force all bits of a hash block to avalanche\r
+\r
+inline uint32_t fmix ( uint32_t h )\r
+{\r
+  h ^= h >> 16;\r
+  h *= 0x85ebca6b;\r
+  h ^= h >> 13;\r
+  h *= 0xc2b2ae35;\r
+  h ^= h >> 16;\r
+\r
+  return h;\r
+}\r
+\r
+//----------\r
+\r
+inline uint64_t fmix ( uint64_t k )\r
+{\r
+  k ^= k >> 33;\r
+  k *= BIG_CONSTANT(0xff51afd7ed558ccd);\r
+  k ^= k >> 33;\r
+  k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);\r
+  k ^= k >> 33;\r
+\r
+  return k;\r
+}\r
+\r
+//-----------------------------------------------------------------------------\r
+\r
+void MurmurHash3_x86_32 ( const void * key, int len,\r
+                          uint32_t seed, void * out )\r
+{\r
+  const uint8_t * data = (const uint8_t*)key;\r
+  const int nblocks = len / 4;\r
+\r
+  uint32_t h1 = seed;\r
+\r
+  uint32_t c1 = 0xcc9e2d51;\r
+  uint32_t c2 = 0x1b873593;\r
+\r
+  //----------\r
+  // body\r
+\r
+  const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);\r
+\r
+  for(int i = -nblocks; i; i++)\r
+  {\r
+    uint32_t k1 = getblock(blocks,i);\r
+\r
+    k1 *= c1;\r
+    k1 = ROTL32(k1,15);\r
+    k1 *= c2;\r
+    \r
+    h1 ^= k1;\r
+    h1 = ROTL32(h1,13); \r
+    h1 = h1*5+0xe6546b64;\r
+  }\r
+\r
+  //----------\r
+  // tail\r
+\r
+  const uint8_t * tail = (const uint8_t*)(data + nblocks*4);\r
+\r
+  uint32_t k1 = 0;\r
+\r
+  switch(len & 3)\r
+  {\r
+  case 3: k1 ^= tail[2] << 16;\r
+  case 2: k1 ^= tail[1] << 8;\r
+  case 1: k1 ^= tail[0];\r
+          k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;\r
+  };\r
+\r
+  //----------\r
+  // finalization\r
+\r
+  h1 ^= len;\r
+\r
+  h1 = fmix(h1);\r
+\r
+  *(uint32_t*)out = h1;\r
+} \r
+\r
+//-----------------------------------------------------------------------------\r
+\r
+void MurmurHash3_x86_128 ( const void * key, const int len,\r
+                           uint32_t seed, void * out )\r
+{\r
+  const uint8_t * data = (const uint8_t*)key;\r
+  const int nblocks = len / 16;\r
+\r
+  uint32_t h1 = seed;\r
+  uint32_t h2 = seed;\r
+  uint32_t h3 = seed;\r
+  uint32_t h4 = seed;\r
+\r
+  uint32_t c1 = 0x239b961b; \r
+  uint32_t c2 = 0xab0e9789;\r
+  uint32_t c3 = 0x38b34ae5; \r
+  uint32_t c4 = 0xa1e38b93;\r
+\r
+  //----------\r
+  // body\r
+\r
+  const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);\r
+\r
+  for(int i = -nblocks; i; i++)\r
+  {\r
+    uint32_t k1 = getblock(blocks,i*4+0);\r
+    uint32_t k2 = getblock(blocks,i*4+1);\r
+    uint32_t k3 = getblock(blocks,i*4+2);\r
+    uint32_t k4 = getblock(blocks,i*4+3);\r
+\r
+    k1 *= c1; k1  = ROTL32(k1,15); k1 *= c2; h1 ^= k1;\r
+\r
+    h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;\r
+\r
+    k2 *= c2; k2  = ROTL32(k2,16); k2 *= c3; h2 ^= k2;\r
+\r
+    h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;\r
+\r
+    k3 *= c3; k3  = ROTL32(k3,17); k3 *= c4; h3 ^= k3;\r
+\r
+    h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;\r
+\r
+    k4 *= c4; k4  = ROTL32(k4,18); k4 *= c1; h4 ^= k4;\r
+\r
+    h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;\r
+  }\r
+\r
+  //----------\r
+  // tail\r
+\r
+  const uint8_t * tail = (const uint8_t*)(data + nblocks*16);\r
+\r
+  uint32_t k1 = 0;\r
+  uint32_t k2 = 0;\r
+  uint32_t k3 = 0;\r
+  uint32_t k4 = 0;\r
+\r
+  switch(len & 15)\r
+  {\r
+  case 15: k4 ^= tail[14] << 16;\r
+  case 14: k4 ^= tail[13] << 8;\r
+  case 13: k4 ^= tail[12] << 0;\r
+           k4 *= c4; k4  = ROTL32(k4,18); k4 *= c1; h4 ^= k4;\r
+\r
+  case 12: k3 ^= tail[11] << 24;\r
+  case 11: k3 ^= tail[10] << 16;\r
+  case 10: k3 ^= tail[ 9] << 8;\r
+  case  9: k3 ^= tail[ 8] << 0;\r
+           k3 *= c3; k3  = ROTL32(k3,17); k3 *= c4; h3 ^= k3;\r
+\r
+  case  8: k2 ^= tail[ 7] << 24;\r
+  case  7: k2 ^= tail[ 6] << 16;\r
+  case  6: k2 ^= tail[ 5] << 8;\r
+  case  5: k2 ^= tail[ 4] << 0;\r
+           k2 *= c2; k2  = ROTL32(k2,16); k2 *= c3; h2 ^= k2;\r
+\r
+  case  4: k1 ^= tail[ 3] << 24;\r
+  case  3: k1 ^= tail[ 2] << 16;\r
+  case  2: k1 ^= tail[ 1] << 8;\r
+  case  1: k1 ^= tail[ 0] << 0;\r
+           k1 *= c1; k1  = ROTL32(k1,15); k1 *= c2; h1 ^= k1;\r
+  };\r
+\r
+  //----------\r
+  // finalization\r
+\r
+  h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;\r
+\r
+  h1 += h2; h1 += h3; h1 += h4;\r
+  h2 += h1; h3 += h1; h4 += h1;\r
+\r
+  h1 = fmix(h1);\r
+  h2 = fmix(h2);\r
+  h3 = fmix(h3);\r
+  h4 = fmix(h4);\r
+\r
+  h1 += h2; h1 += h3; h1 += h4;\r
+  h2 += h1; h3 += h1; h4 += h1;\r
+\r
+  ((uint32_t*)out)[0] = h1;\r
+  ((uint32_t*)out)[1] = h2;\r
+  ((uint32_t*)out)[2] = h3;\r
+  ((uint32_t*)out)[3] = h4;\r
+}\r
+\r
+//-----------------------------------------------------------------------------\r
+\r
+void MurmurHash3_x64_128 ( const void * key, const int len,\r
+                           const uint32_t seed, void * out )\r
+{\r
+  const uint8_t * data = (const uint8_t*)key;\r
+  const int nblocks = len / 16;\r
+\r
+  uint64_t h1 = seed;\r
+  uint64_t h2 = seed;\r
+\r
+  uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);\r
+  uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);\r
+\r
+  //----------\r
+  // body\r
+\r
+  const uint64_t * blocks = (const uint64_t *)(data);\r
+\r
+  for(int i = 0; i < nblocks; i++)\r
+  {\r
+    uint64_t k1 = getblock(blocks,i*2+0);\r
+    uint64_t k2 = getblock(blocks,i*2+1);\r
+\r
+    k1 *= c1; k1  = ROTL64(k1,31); k1 *= c2; h1 ^= k1;\r
+\r
+    h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;\r
+\r
+    k2 *= c2; k2  = ROTL64(k2,33); k2 *= c1; h2 ^= k2;\r
+\r
+    h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;\r
+  }\r
+\r
+  //----------\r
+  // tail\r
+\r
+  const uint8_t * tail = (const uint8_t*)(data + nblocks*16);\r
+\r
+  uint64_t k1 = 0;\r
+  uint64_t k2 = 0;\r
+\r
+  switch(len & 15)\r
+  {\r
+  case 15: k2 ^= uint64_t(tail[14]) << 48;\r
+  case 14: k2 ^= uint64_t(tail[13]) << 40;\r
+  case 13: k2 ^= uint64_t(tail[12]) << 32;\r
+  case 12: k2 ^= uint64_t(tail[11]) << 24;\r
+  case 11: k2 ^= uint64_t(tail[10]) << 16;\r
+  case 10: k2 ^= uint64_t(tail[ 9]) << 8;\r
+  case  9: k2 ^= uint64_t(tail[ 8]) << 0;\r
+           k2 *= c2; k2  = ROTL64(k2,33); k2 *= c1; h2 ^= k2;\r
+\r
+  case  8: k1 ^= uint64_t(tail[ 7]) << 56;\r
+  case  7: k1 ^= uint64_t(tail[ 6]) << 48;\r
+  case  6: k1 ^= uint64_t(tail[ 5]) << 40;\r
+  case  5: k1 ^= uint64_t(tail[ 4]) << 32;\r
+  case  4: k1 ^= uint64_t(tail[ 3]) << 24;\r
+  case  3: k1 ^= uint64_t(tail[ 2]) << 16;\r
+  case  2: k1 ^= uint64_t(tail[ 1]) << 8;\r
+  case  1: k1 ^= uint64_t(tail[ 0]) << 0;\r
+           k1 *= c1; k1  = ROTL64(k1,31); k1 *= c2; h1 ^= k1;\r
+  };\r
+\r
+  //----------\r
+  // finalization\r
+\r
+  h1 ^= len; h2 ^= len;\r
+\r
+  h1 += h2;\r
+  h2 += h1;\r
+\r
+  h1 = fmix(h1);\r
+  h2 = fmix(h2);\r
+\r
+  h1 += h2;\r
+  h2 += h1;\r
+\r
+  ((uint64_t*)out)[0] = h1;\r
+  ((uint64_t*)out)[1] = h2;\r
+}\r
+\r
+//-----------------------------------------------------------------------------\r
+\r
diff --git a/CommonAPI-DBus/src/murmurhash/MurmurHash3.h b/CommonAPI-DBus/src/murmurhash/MurmurHash3.h
new file mode 100644 (file)
index 0000000..58e9820
--- /dev/null
@@ -0,0 +1,37 @@
+//-----------------------------------------------------------------------------\r
+// MurmurHash3 was written by Austin Appleby, and is placed in the public\r
+// domain. The author hereby disclaims copyright to this source code.\r
+\r
+#ifndef _MURMURHASH3_H_\r
+#define _MURMURHASH3_H_\r
+\r
+//-----------------------------------------------------------------------------\r
+// Platform-specific functions and macros\r
+\r
+// Microsoft Visual Studio\r
+\r
+#if defined(_MSC_VER)\r
+\r
+typedef unsigned char uint8_t;\r
+typedef unsigned long uint32_t;\r
+typedef unsigned __int64 uint64_t;\r
+\r
+// Other compilers\r
+\r
+#else  // defined(_MSC_VER)\r
+\r
+#include <stdint.h>\r
+\r
+#endif // !defined(_MSC_VER)\r
+\r
+//-----------------------------------------------------------------------------\r
+\r
+void MurmurHash3_x86_32  ( const void * key, int len, uint32_t seed, void * out );\r
+\r
+void MurmurHash3_x86_128 ( const void * key, int len, uint32_t seed, void * out );\r
+\r
+void MurmurHash3_x64_128 ( const void * key, int len, uint32_t seed, void * out );\r
+\r
+//-----------------------------------------------------------------------------\r
+\r
+#endif // _MURMURHASH3_H_\r
diff --git a/CommonAPI-DBus/src/test/DBusBenchmarkingTest.cpp b/CommonAPI-DBus/src/test/DBusBenchmarkingTest.cpp
new file mode 100644 (file)
index 0000000..e9bec02
--- /dev/null
@@ -0,0 +1,217 @@
+/* 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 <CommonAPI/SerializableStruct.h>
+#include <CommonAPI/DBus/DBusInputStream.h>
+#include <CommonAPI/DBus/DBusOutputStream.h>
+
+#include <unordered_map>
+#include <bits/functional_hash.h>
+
+#include <gtest/gtest.h>
+
+#include <dbus/dbus.h>
+
+#include <chrono>
+#include <cstdint>
+#include <vector>
+#include <unordered_map>
+#include <bits/functional_hash.h>
+
+
+class BenchmarkingTest: public ::testing::Test {
+  protected:
+    DBusMessage* libdbusMessage;
+    DBusMessageIter libdbusMessageWriteIter;
+    size_t numOfElements;
+
+    void SetUp() {
+        numOfElements = 2;
+        libdbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
+        ASSERT_TRUE(libdbusMessage != NULL);
+        dbus_message_iter_init_append(libdbusMessage, &libdbusMessageWriteIter);
+    }
+
+    void TearDown() {
+        dbus_message_unref(libdbusMessage);
+    }
+};
+
+template <typename _ArrayElementLibdbusType, typename _ArrayElementCommonApiType>
+void prepareLibdbusArray(DBusMessage* libdbusMessage,
+                         const int arrayElementLibdbusType,
+                         const char* arrayElementLibdbusTypeAsString,
+                         const _ArrayElementLibdbusType& arrayInitElementValue,
+                         const uint32_t arrayInitTime,
+                         size_t& libdbusInitElementCount) {
+
+    DBusMessageIter libdbusMessageIter;
+    DBusMessageIter libdbusMessageContainerIter;
+
+    dbus_message_iter_init_append(libdbusMessage, &libdbusMessageIter);
+
+    dbus_bool_t libdbusSuccess = dbus_message_iter_open_container(&libdbusMessageIter,
+                                                                  DBUS_TYPE_ARRAY,
+                                                                  arrayElementLibdbusTypeAsString,
+                                                                  &libdbusMessageContainerIter);
+    ASSERT_TRUE(libdbusSuccess);
+
+
+    std::chrono::milliseconds libdbusInitTime;
+    std::chrono::time_point<std::chrono::high_resolution_clock> clockStart = std::chrono::high_resolution_clock::now();
+
+    do {
+        for (int i = 0; i < 1000; i++)
+            dbus_message_iter_append_basic(&libdbusMessageContainerIter,
+                                           arrayElementLibdbusType,
+                                           &arrayInitElementValue);
+
+        libdbusInitElementCount += 1000;
+
+        libdbusInitTime = std::chrono::duration_cast<std::chrono::milliseconds>(
+                std::chrono::high_resolution_clock::now() - clockStart);
+    } while (libdbusInitTime.count() < arrayInitTime);
+
+    libdbusSuccess = dbus_message_iter_close_container(&libdbusMessageIter, &libdbusMessageContainerIter);
+    ASSERT_TRUE(libdbusSuccess);
+
+    std::cout << "LibdbusInitTime = " << libdbusInitTime.count() << std::endl;
+    std::cout << "LibdbusInitElementCount = " << libdbusInitElementCount << std::endl;
+}
+
+
+template <typename _ArrayElementLibdbusType, typename _ArrayElementCommonApiType>
+void measureLibdbusArrayReadTime(DBusMessage* libdbusMessage,
+                                 size_t& libdbusInitElementCount,
+                                 std::chrono::milliseconds& libdbusArrayReadTime) {
+
+    DBusMessageIter libdbusMessageIter;
+    DBusMessageIter libdbusMessageContainerIter;
+
+    dbus_bool_t libdbusSuccess;
+
+    libdbusSuccess = dbus_message_iter_init(libdbusMessage, &libdbusMessageIter);
+    ASSERT_TRUE(libdbusSuccess);
+
+    dbus_message_iter_recurse(&libdbusMessageIter, &libdbusMessageContainerIter);
+
+    size_t libdbusReadElementCount = 0;
+    std::chrono::time_point<std::chrono::high_resolution_clock> clockStart = std::chrono::high_resolution_clock::now();
+
+    do {
+        _ArrayElementLibdbusType libdbusValue;
+
+        dbus_message_iter_get_basic(&libdbusMessageContainerIter, &libdbusValue);
+
+        ++libdbusReadElementCount;
+    } while (dbus_message_iter_next(&libdbusMessageContainerIter));
+
+    libdbusArrayReadTime = std::chrono::duration_cast<std::chrono::milliseconds>(
+            std::chrono::high_resolution_clock::now() - clockStart);
+
+    ASSERT_EQ(libdbusInitElementCount, libdbusReadElementCount);
+}
+
+
+template <typename _ArrayElementLibdbusType, typename _ArrayElementCommonApiType>
+void measureCommonApiArrayReadTime(DBusMessage* libdbusMessage,
+                                   std::chrono::milliseconds& commonArrayApiReadTime,
+                                   size_t& libdbusInitElementCount) {
+
+    CommonAPI::DBus::DBusMessage dbusMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream DBusInputStream(dbusMessage);
+    std::vector<_ArrayElementCommonApiType> commonApiVector;
+
+    std::chrono::time_point<std::chrono::high_resolution_clock> clockStart = std::chrono::high_resolution_clock::now();
+
+    DBusInputStream >> commonApiVector;
+
+    commonArrayApiReadTime = std::chrono::duration_cast<std::chrono::milliseconds>(
+            std::chrono::high_resolution_clock::now() - clockStart);
+
+    ASSERT_EQ(libdbusInitElementCount, commonApiVector.size());
+}
+
+
+template <typename _ArrayElementLibdbusType, typename _ArrayElementCommonApiType>
+void measureArrayReadTime(
+               const int arrayElementLibdbusType,
+               const char* arrayElementLibdbusTypeAsString,
+               const _ArrayElementLibdbusType arrayInitElementValue,
+               const uint32_t arrayInitTime,
+               std::chrono::milliseconds& libdbusArrayReadTime,
+               std::chrono::milliseconds& commonArrayApiReadTime) {
+
+       DBusMessage* libdbusMessage;
+    dbus_bool_t libdbusSuccess;
+    size_t libdbusInitElementCount = 0;
+
+    libdbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
+    ASSERT_TRUE(libdbusMessage != NULL);
+
+    prepareLibdbusArray<_ArrayElementLibdbusType, _ArrayElementCommonApiType>(
+                                libdbusMessage,
+                                arrayElementLibdbusType,
+                                arrayElementLibdbusTypeAsString,
+                                arrayInitElementValue,
+                                arrayInitTime,
+                                libdbusInitElementCount);
+
+    measureLibdbusArrayReadTime<_ArrayElementLibdbusType, _ArrayElementCommonApiType>(
+                                libdbusMessage,
+                                libdbusInitElementCount,
+                                libdbusArrayReadTime);
+
+    measureCommonApiArrayReadTime<_ArrayElementLibdbusType, _ArrayElementCommonApiType>(
+                                libdbusMessage,
+                                commonArrayApiReadTime,
+                                libdbusInitElementCount);
+}
+
+
+TEST_F(BenchmarkingTest, InputStreamReadsIntegerArrayFasterThanLibdbus) {
+       std::chrono::milliseconds libdbusArrayReadTime;
+       std::chrono::milliseconds commonApiArrayReadTime;
+
+       measureArrayReadTime<int32_t, int32_t>(DBUS_TYPE_INT32,
+                                                                                  DBUS_TYPE_INT32_AS_STRING,
+                                                                                  1234567890,
+                                                                                  1000,
+                                                                                  libdbusArrayReadTime,
+                                                                                  commonApiArrayReadTime);
+
+       RecordProperty("LibdbusArrayReadTime", libdbusArrayReadTime.count());
+       RecordProperty("CommonApiArrayReadTime", commonApiArrayReadTime.count());
+
+       std::cout << "LibdbusArrayReadTime = " << libdbusArrayReadTime.count() << std::endl;
+       std::cout << "CommonApiArrayReadTime = " << commonApiArrayReadTime.count() << std::endl;
+
+    ASSERT_LT(commonApiArrayReadTime.count(), libdbusArrayReadTime.count() * 0.30)
+       << "CommonAPI::DBus::DBusInputStream must be at least 70% faster than libdbus!";
+}
+
+TEST_F(BenchmarkingTest, InputStreamReadsStringArrayFasterThanLibdbus) {
+       std::chrono::milliseconds libdbusArrayReadTime;
+       std::chrono::milliseconds commonApiArrayReadTime;
+
+       measureArrayReadTime<char*, std::string>(DBUS_TYPE_STRING,
+                                                                                        DBUS_TYPE_STRING_AS_STRING,
+                                                                                        const_cast<char*>("01234567890123456789"),
+                                                                                        1000,
+                                                                                        libdbusArrayReadTime,
+                                                                                        commonApiArrayReadTime);
+
+       RecordProperty("LibdbusArrayReadTime", libdbusArrayReadTime.count());
+       RecordProperty("CommonApiArrayReadTime", commonApiArrayReadTime.count());
+
+       std::cout << "LibdbusArrayReadTime = " << libdbusArrayReadTime.count() << std::endl;
+       std::cout << "CommonApiArrayReadTime = " << commonApiArrayReadTime.count() << std::endl;
+
+    ASSERT_LT(commonApiArrayReadTime.count(), libdbusArrayReadTime.count() * 0.30)
+       << "CommonAPI::DBus::DBusInputStream must be at least 70% faster than libdbus!";
+}
+
+int main(int argc, char** argv) {
+       ::testing::InitGoogleTest(&argc, argv);
+       return RUN_ALL_TESTS();
+}
diff --git a/CommonAPI-DBus/src/test/DBusCommunicationTest.cpp b/CommonAPI-DBus/src/test/DBusCommunicationTest.cpp
new file mode 100644 (file)
index 0000000..d7a0154
--- /dev/null
@@ -0,0 +1,107 @@
+/* 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 <gtest/gtest.h>
+
+#include <cassert>
+#include <cstdint>
+#include <iostream>
+#include <functional>
+#include <memory>
+#include <stdint.h>
+#include <string>
+#include <utility>
+#include <tuple>
+#include <type_traits>
+
+#include <CommonAPI/types.h>
+#include <CommonAPI/AttributeExtension.h>
+#include <CommonAPI/Runtime.h>
+
+#include <CommonAPI/DBus/DBusConnection.h>
+#include <CommonAPI/DBus/DBusProxy.h>
+#include <CommonAPI/DBus/DBusRuntime.h>
+
+#include "commonapi/tests/PredefinedTypeCollection.h"
+#include "commonapi/tests/DerivedTypeCollection.h"
+#include "commonapi/tests/TestInterfaceProxy.h"
+#include "commonapi/tests/TestInterfaceStubDefault.h"
+#include "commonapi/tests/TestInterfaceDBusStubAdapter.h"
+
+#include "commonapi/tests/TestInterfaceDBusProxy.h"
+
+
+class DBusCommunicationTest: public ::testing::Test {
+ protected:
+    virtual void SetUp() {
+        runtime_ = CommonAPI::Runtime::load();
+        ASSERT_TRUE((bool)runtime_);
+        CommonAPI::DBus::DBusRuntime* dbusRuntime = dynamic_cast<CommonAPI::DBus::DBusRuntime*>(&(*runtime_));
+        ASSERT_TRUE(dbusRuntime != NULL);
+    }
+
+    virtual void TearDown() {
+    }
+
+    std::shared_ptr<CommonAPI::Runtime> runtime_;
+
+    static const std::string serviceAddress_;
+};
+
+const std::string DBusCommunicationTest::serviceAddress_ = "local:commonapi.tests.TestInterface:commonapi.tests.TestInterface";
+
+
+
+namespace myExtensions {
+
+template<typename _AttributeType>
+class AttributeTestExtension: public CommonAPI::AttributeExtension<_AttributeType> {
+    typedef CommonAPI::AttributeExtension<_AttributeType> __baseClass_t;
+
+public:
+    typedef typename _AttributeType::ValueType ValueType;
+    typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback;
+
+    AttributeTestExtension(_AttributeType& baseAttribute) :
+                    CommonAPI::AttributeExtension<_AttributeType>(baseAttribute) {}
+
+   ~AttributeTestExtension() {}
+
+   bool testExtensionMethod() const {
+       return true;
+   }
+};
+
+} // namespace myExtensions
+
+//####################################################################################################################
+
+
+TEST_F(DBusCommunicationTest, RemoteMethodCallSucceeds) {
+    std::shared_ptr<CommonAPI::Factory> proxyFactory = runtime_->createFactory();
+    ASSERT_TRUE((bool)proxyFactory);
+
+    auto defaultTestProxy = proxyFactory->buildProxy<commonapi::tests::TestInterfaceProxy>(serviceAddress_);
+    ASSERT_TRUE((bool)defaultTestProxy);
+
+    std::shared_ptr<CommonAPI::Factory> stubFactory = runtime_->createFactory();
+    ASSERT_TRUE((bool)stubFactory);
+
+    auto stub = std::make_shared<commonapi::tests::TestInterfaceStubDefault>();
+    bool success = stubFactory->registerService(stub, serviceAddress_);
+    ASSERT_TRUE(success);
+
+    uint32_t v1 = 5;
+    std::string v2 = "Hai :)";
+    CommonAPI::CallStatus stat;
+    defaultTestProxy->testVoidPredefinedTypeMethod(v1, v2, stat);
+
+    ASSERT_EQ(stat, CommonAPI::CallStatus::SUCCESS);
+}
+
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/CommonAPI-DBus/src/test/DBusConnectionTest.cpp b/CommonAPI-DBus/src/test/DBusConnectionTest.cpp
new file mode 100644 (file)
index 0000000..5882e53
--- /dev/null
@@ -0,0 +1,196 @@
+/* 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 <common-api-dbus/dbus-connection.h>
+#include <common-api-dbus/dbus-output-message-stream.h>
+
+#include <gtest/gtest.h>
+
+#include <cstring>
+
+
+#define        ASSERT_DBUSMESSAGE_EQ(_dbusMessage1, _dbusMessage2) \
+                       ASSERT_FALSE(_dbusMessage1.getSignatureString() == NULL); \
+                       ASSERT_FALSE(_dbusMessage2.getSignatureString() == NULL); \
+                       ASSERT_STREQ(_dbusMessage1.getSignatureString(), _dbusMessage2.getSignatureString()); \
+                       ASSERT_EQ(_dbusMessage1.getBodyLength(), _dbusMessage2.getBodyLength()); \
+                       ASSERT_FALSE(_dbusMessage1.getBodyData() == NULL); \
+                       ASSERT_FALSE(_dbusMessage2.getBodyData() == NULL); \
+                       ASSERT_EQ(memcmp(_dbusMessage1.getBodyData(), _dbusMessage2.getBodyData(), _dbusMessage1.getBodyLength()), 0)
+
+
+namespace {
+
+class DBusConnectionTest: public ::testing::Test {
+ public:
+       void onConnectionStatusEvent(const common::api::AvailabilityStatus& newConnectionStatus) {
+               connectionStatusEventCount_++;
+               connectionStatus_ = newConnectionStatus;
+       }
+
+       bool onInterfaceHandlerDBusMessageReply(const common::api::dbus::DBusMessage& dbusMessage,
+                                                                                       const std::shared_ptr<common::api::dbus::DBusConnection>& dbusConnection) {
+               interfaceHandlerDBusMessageCount_++;
+               interfaceHandlerDBusMessage_ = dbusMessage;
+               interfaceHandlerDBusMessageReply_ = dbusMessage.createMethodReturn("si");
+
+               common::api::dbus::DBusOutputMessageStream dbusOutputMessageStream(interfaceHandlerDBusMessageReply_);
+               dbusOutputMessageStream << "This is a default message reply!" << interfaceHandlerDBusMessageCount_;
+               dbusOutputMessageStream.flush();
+
+               dbusConnection->sendDBusMessage(interfaceHandlerDBusMessageReply_);
+
+               return true;
+       }
+
+       void onDBusMessageHandler(const common::api::dbus::DBusMessage& dbusMessage) {
+               dbusMessageHandlerCount_++;
+               dbusMessageHandlerDBusMessage_ = dbusMessage;
+       }
+
+ protected:
+       virtual void SetUp() {
+               dbusConnection_ = common::api::dbus::DBusConnection::getSessionBus();
+               connectionStatusEventCount_ = 0;
+               interfaceHandlerDBusMessageCount_ = 0;
+               dbusMessageHandlerCount_ = 0;
+       }
+
+       virtual void TearDown() {
+               if (dbusConnection_ && dbusConnection_->isConnected())
+                       dbusConnection_->disconnect();
+
+               // reset DBusMessage
+               interfaceHandlerDBusMessage_ = common::api::dbus::DBusMessage();
+               interfaceHandlerDBusMessageReply_ = common::api::dbus::DBusMessage();
+
+               dbusMessageHandlerDBusMessage_ = common::api::dbus::DBusMessage();
+       }
+
+
+       std::shared_ptr<common::api::dbus::DBusConnection> dbusConnection_;
+
+       uint32_t connectionStatusEventCount_;
+       common::api::AvailabilityStatus connectionStatus_;
+
+       uint32_t interfaceHandlerDBusMessageCount_;
+       common::api::dbus::DBusMessage interfaceHandlerDBusMessage_;
+       common::api::dbus::DBusMessage interfaceHandlerDBusMessageReply_;
+
+       uint32_t dbusMessageHandlerCount_;
+       common::api::dbus::DBusMessage dbusMessageHandlerDBusMessage_;
+};
+
+
+TEST_F(DBusConnectionTest, IsInitiallyDisconnected) {
+       ASSERT_FALSE(dbusConnection_->isConnected());
+}
+
+TEST_F(DBusConnectionTest, ConnectAndDisconnectWork) {
+       ASSERT_TRUE(dbusConnection_->connect());
+       ASSERT_TRUE(dbusConnection_->isConnected());
+
+       dbusConnection_->disconnect();
+       ASSERT_FALSE(dbusConnection_->isConnected());
+}
+
+TEST_F(DBusConnectionTest, ConnectionStatusEventWorks) {
+       ASSERT_EQ(connectionStatusEventCount_, 0);
+
+       auto connectionStatusSubscription = dbusConnection_->getConnectionStatusEvent().subscribe(std::bind(
+                       &DBusConnectionTest::onConnectionStatusEvent,
+                       this,
+                       std::placeholders::_1));
+
+       ASSERT_FALSE(dbusConnection_->isConnected());
+       ASSERT_EQ(connectionStatusEventCount_, 0);
+
+       uint32_t expectedEventCount = 0;
+       while (expectedEventCount < 10) {
+               ASSERT_TRUE(dbusConnection_->connect());
+               ASSERT_TRUE(dbusConnection_->isConnected());
+               ASSERT_EQ(connectionStatusEventCount_, ++expectedEventCount);
+               ASSERT_EQ(connectionStatus_, common::api::AvailabilityStatus::AVAILABLE);
+
+               dbusConnection_->disconnect();
+               ASSERT_FALSE(dbusConnection_->isConnected());
+               ASSERT_EQ(connectionStatusEventCount_, ++expectedEventCount);
+               ASSERT_EQ(connectionStatus_, common::api::AvailabilityStatus::NOT_AVAILABLE);
+       }
+
+       dbusConnection_->getConnectionStatusEvent().unsubscribe(connectionStatusSubscription);
+       ASSERT_EQ(connectionStatusEventCount_, expectedEventCount);
+
+       ASSERT_TRUE(dbusConnection_->connect());
+       ASSERT_TRUE(dbusConnection_->isConnected());
+       ASSERT_EQ(connectionStatusEventCount_, expectedEventCount);
+
+       dbusConnection_->disconnect();
+       ASSERT_FALSE(dbusConnection_->isConnected());
+       ASSERT_EQ(connectionStatusEventCount_, expectedEventCount);
+}
+
+TEST_F(DBusConnectionTest, SendingAsyncDBusMessagesWorks) {
+       const char* busName = "common.api.dbus.test.TestInterfaceHandler";
+       const char* objectPath = "/common/api/dbus/test/TestObject";
+       const char* interfaceName = "common.api.dbus.test.TestInterface";
+       const char* methodName = "TestMethod";
+
+       auto interfaceHandlerDBusConnection = common::api::dbus::DBusConnection::getSessionBus();
+
+       ASSERT_TRUE(interfaceHandlerDBusConnection->connect());
+       ASSERT_TRUE(interfaceHandlerDBusConnection->requestServiceNameAndBlock(busName));
+
+       auto interfaceHandlerToken = interfaceHandlerDBusConnection->registerInterfaceHandler(
+                       objectPath,
+                       interfaceName,
+                       std::bind(&DBusConnectionTest::onInterfaceHandlerDBusMessageReply,
+                                         this,
+                                         std::placeholders::_1,
+                                         interfaceHandlerDBusConnection));
+
+
+       ASSERT_TRUE(dbusConnection_->connect());
+
+       for (uint32_t expectedDBusMessageCount = 1; expectedDBusMessageCount <= 10; expectedDBusMessageCount++) {
+               auto dbusMessageCall = common::api::dbus::DBusMessage::createMethodCall(
+                               busName,
+                               objectPath,
+                               interfaceName,
+                               methodName,
+                               "si");
+               ASSERT_TRUE(dbusMessageCall);
+
+               common::api::dbus::DBusOutputMessageStream dbusOutputMessageStream(dbusMessageCall);
+               dbusOutputMessageStream << "This is a test async call"
+                                                               << expectedDBusMessageCount;
+               dbusOutputMessageStream.flush();
+
+               dbusConnection_->sendDBusMessageWithReplyAsync(
+                               dbusMessageCall,
+                               std::bind(&DBusConnectionTest::onDBusMessageHandler, this, std::placeholders::_1));
+
+               for (int i = 0; i < 10 && interfaceHandlerDBusMessageCount_ < expectedDBusMessageCount; i++)
+                       interfaceHandlerDBusConnection->readWriteDispatch(100);
+
+               ASSERT_EQ(interfaceHandlerDBusMessageCount_, expectedDBusMessageCount);
+               ASSERT_DBUSMESSAGE_EQ(dbusMessageCall, interfaceHandlerDBusMessage_);
+
+               for (int i = 0; i < 10 && dbusMessageHandlerCount_ < expectedDBusMessageCount; i++)
+                       dbusConnection_->readWriteDispatch(100);
+
+               ASSERT_EQ(dbusMessageHandlerCount_, expectedDBusMessageCount);
+               ASSERT_DBUSMESSAGE_EQ(dbusMessageHandlerDBusMessage_, interfaceHandlerDBusMessageReply_);
+       }
+
+       dbusConnection_->disconnect();
+
+
+       interfaceHandlerDBusConnection->unregisterInterfaceHandler(interfaceHandlerToken);
+
+       ASSERT_TRUE(interfaceHandlerDBusConnection->releaseServiceName(busName));
+       interfaceHandlerDBusConnection->disconnect();
+}
+
+} // namespace
diff --git a/CommonAPI-DBus/src/test/DBusDaemonProxyTest.cpp b/CommonAPI-DBus/src/test/DBusDaemonProxyTest.cpp
new file mode 100644 (file)
index 0000000..c1db30e
--- /dev/null
@@ -0,0 +1,159 @@
+/* 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 <CommonAPI/DBus/DBusConnection.h>
+#include <CommonAPI/DBus/DBusDaemonProxy.h>
+
+#include <gtest/gtest.h>
+
+#include <future>
+#include <tuple>
+
+namespace {
+
+void dispatch(std::shared_ptr<CommonAPI::DBus::DBusConnection> dbusConnection) {
+    while (dbusConnection->readWriteDispatch(10)) {}
+}
+
+class DBusDaemonProxyTest: public ::testing::Test {
+ protected:
+
+       std::thread* thread;
+
+       virtual void SetUp() {
+               dbusConnection_ = CommonAPI::DBus::DBusConnection::getSessionBus();
+               ASSERT_TRUE(dbusConnection_->connect());
+               thread = new std::thread(dispatch, dbusConnection_);
+               thread->detach();
+               //readWriteDispatchCount_ = 0;
+       }
+
+       virtual void TearDown() {
+               delete thread;
+               if (dbusConnection_ && dbusConnection_->isConnected()) {
+                       //dbusConnection_->disconnect();
+               }
+       }
+
+       /*bool doReadWriteDispatch(int timeoutMilliseconds = 100) {
+               readWriteDispatchCount_++;
+               return dbusConnection_->readWriteDispatch(timeoutMilliseconds);
+       }*/
+
+       std::shared_ptr<CommonAPI::DBus::DBusConnection> dbusConnection_;
+       //size_t readWriteDispatchCount_;
+};
+
+TEST_F(DBusDaemonProxyTest, ListNames) {
+       std::vector<std::string> busNames;
+       CommonAPI::CallStatus callStatus;
+
+       dbusConnection_->getDBusDaemonProxy()->listNames(callStatus, busNames);
+       ASSERT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
+
+       ASSERT_GT(busNames.size(), 0);
+       for (const std::string& busName : busNames) {
+               ASSERT_FALSE(busName.empty());
+               ASSERT_GT(busName.length(), 1);
+       }
+}
+
+TEST_F(DBusDaemonProxyTest, ListNamesAsync) {
+       std::promise<std::tuple<CommonAPI::CallStatus, std::vector<std::string>>> promise;
+       auto future = promise.get_future();
+
+       auto callStatusFuture = dbusConnection_->getDBusDaemonProxy()->listNamesAsync(
+                       [&](const CommonAPI::CallStatus& callStatus, std::vector<std::string> busNames) {
+               promise.set_value(std::tuple<CommonAPI::CallStatus, std::vector<std::string>>(callStatus, std::move(busNames)));
+       });
+
+       ASSERT_EQ(future.wait_for(std::chrono::milliseconds(200)), std::future_status::ready);
+
+       ASSERT_EQ(callStatusFuture.get(), CommonAPI::CallStatus::SUCCESS);
+
+       auto futureResult = future.get();
+       const CommonAPI::CallStatus& callStatus = std::get<0>(futureResult);
+       const std::vector<std::string>& busNames = std::get<1>(futureResult);
+
+       ASSERT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
+
+       ASSERT_GT(busNames.size(), 0);
+       for (const std::string& busName : busNames) {
+               ASSERT_FALSE(busName.empty());
+               ASSERT_GT(busName.length(), 1);
+       }
+}
+
+TEST_F(DBusDaemonProxyTest, NameHasOwner) {
+       bool nameHasOwner;
+       CommonAPI::CallStatus callStatus;
+
+       dbusConnection_->getDBusDaemonProxy()->nameHasOwner("org.freedesktop.DBus", callStatus, nameHasOwner);
+       ASSERT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
+       ASSERT_TRUE(nameHasOwner);
+
+       dbusConnection_->getDBusDaemonProxy()->nameHasOwner("org.freedesktop.DBus.InvalidName.XXYYZZ", callStatus, nameHasOwner);
+       ASSERT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
+       ASSERT_FALSE(nameHasOwner);
+}
+
+TEST_F(DBusDaemonProxyTest, NameHasOwnerAsync) {
+       std::promise<std::tuple<CommonAPI::CallStatus, bool>> promise;
+       auto future = promise.get_future();
+
+       auto callStatusFuture = dbusConnection_->getDBusDaemonProxy()->nameHasOwnerAsync(
+                       "org.freedesktop.DBus",
+                       [&](const CommonAPI::CallStatus& callStatus, bool nameHasOwner) {
+               promise.set_value(std::tuple<CommonAPI::CallStatus, bool>(callStatus, std::move(nameHasOwner)));
+       });
+
+       //while (readWriteDispatchCount_ < 5) {
+       //      ASSERT_TRUE(doReadWriteDispatch());
+               //if (callStatusFuture.wait_for(std::chrono::milliseconds(100)) == std::future_status::ready)
+               //      break;
+       //}
+       //ASSERT_NE(readWriteDispatchCount_, 5);
+       ASSERT_EQ(future.wait_for(std::chrono::milliseconds(100)), std::future_status::ready);
+
+       ASSERT_EQ(callStatusFuture.get(), CommonAPI::CallStatus::SUCCESS);
+
+       auto futureResult = future.get();
+       const CommonAPI::CallStatus& callStatus = std::get<0>(futureResult);
+       const bool& nameHasOwner = std::get<1>(futureResult);
+
+       ASSERT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
+       ASSERT_TRUE(nameHasOwner);
+}
+
+TEST_F(DBusDaemonProxyTest, NameOwnerChangedEvent) {
+       std::promise<bool> promise;
+       auto future = promise.get_future();
+
+       dbusConnection_->getDBusDaemonProxy()->getNameOwnerChangedEvent().subscribe(
+                       [&](const std::string& name, const std::string& oldOwner, const std::string& newOwner) {
+           static bool promiseIsSet = false;
+           if(!promiseIsSet) {
+               promiseIsSet = true;
+               promise.set_value(!name.empty() && (!oldOwner.empty() || !newOwner.empty()));
+           }
+       });
+
+       // Trigger NameOwnerChanged using a new DBusConnection
+       ASSERT_TRUE(CommonAPI::DBus::DBusConnection::getSessionBus()->connect());
+
+       //while (readWriteDispatchCount_ < 5) {
+       //      ASSERT_TRUE(doReadWriteDispatch());
+               //if (future.wait_for(std::chrono::milliseconds(100)) == std::future_status::ready)
+               //      break;
+       //}
+
+       //ASSERT_NE(readWriteDispatchCount_, 5);
+       ASSERT_TRUE(future.get());
+}
+
+} // namespace
+
+int main(int argc, char** argv) {
+       ::testing::InitGoogleTest(&argc, argv);
+       return RUN_ALL_TESTS();
+}
diff --git a/CommonAPI-DBus/src/test/DBusFactoryTest.cpp b/CommonAPI-DBus/src/test/DBusFactoryTest.cpp
new file mode 100644 (file)
index 0000000..af7d34b
--- /dev/null
@@ -0,0 +1,141 @@
+/* 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 <gtest/gtest.h>
+
+#include <cassert>
+#include <cstdint>
+#include <iostream>
+#include <functional>
+#include <memory>
+#include <stdint.h>
+#include <string>
+#include <utility>
+#include <tuple>
+#include <type_traits>
+
+#include <CommonAPI/types.h>
+#include <CommonAPI/AttributeExtension.h>
+#include <CommonAPI/Runtime.h>
+
+#include <CommonAPI/DBus/DBusConnection.h>
+#include <CommonAPI/DBus/DBusProxy.h>
+#include <CommonAPI/DBus/DBusRuntime.h>
+
+#include "commonapi/tests/PredefinedTypeCollection.h"
+#include "commonapi/tests/DerivedTypeCollection.h"
+#include "commonapi/tests/TestInterfaceProxy.h"
+#include "commonapi/tests/TestInterfaceStubDefault.h"
+#include "commonapi/tests/TestInterfaceDBusStubAdapter.h"
+
+#include "commonapi/tests/TestInterfaceDBusProxy.h"
+
+std::shared_ptr<CommonAPI::Runtime> runtime_;
+std::shared_ptr<CommonAPI::Factory> proxyFactory;
+
+class DBusProxyFactoryTest: public ::testing::Test {
+ protected:
+    virtual void SetUp() {
+         if(!runtime_) {
+             runtime_ = CommonAPI::Runtime::load();
+
+         }
+         ASSERT_TRUE((bool)runtime_);
+         CommonAPI::DBus::DBusRuntime* dbusRuntime = dynamic_cast<CommonAPI::DBus::DBusRuntime*>(&(*runtime_));
+         ASSERT_TRUE(dbusRuntime != NULL);
+    }
+
+    virtual void TearDown() {
+    }
+};
+
+
+
+namespace myExtensions {
+
+template<typename _AttributeType>
+class AttributeTestExtension: public CommonAPI::AttributeExtension<_AttributeType> {
+    typedef CommonAPI::AttributeExtension<_AttributeType> __baseClass_t;
+
+public:
+    typedef typename _AttributeType::ValueType ValueType;
+    typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback;
+
+    AttributeTestExtension(_AttributeType& baseAttribute) :
+                    CommonAPI::AttributeExtension<_AttributeType>(baseAttribute) {}
+
+   ~AttributeTestExtension() {}
+
+   bool testExtensionMethod() const {
+       return true;
+   }
+};
+
+} // namespace myExtensions
+
+//####################################################################################################################
+
+TEST_F(DBusProxyFactoryTest, DBusFactoryCanBeCreated) {
+    proxyFactory = runtime_->createFactory();
+    ASSERT_TRUE((bool)proxyFactory);
+    CommonAPI::DBus::DBusFactory* dbusProxyFactory = dynamic_cast<CommonAPI::DBus::DBusFactory*>(&(*proxyFactory));
+    ASSERT_TRUE(dbusProxyFactory != NULL);
+}
+
+TEST_F(DBusProxyFactoryTest, CreatesDefaultTestProxy) {
+    ASSERT_TRUE((bool)proxyFactory);
+    auto defaultTestProxy = proxyFactory->buildProxy<commonapi::tests::TestInterfaceProxy>("local:commonapi.tests.TestInterface:commonapi.tests.TestInterface");
+    ASSERT_TRUE((bool)defaultTestProxy);
+}
+
+TEST_F(DBusProxyFactoryTest, CreatesDefaultExtendedTestProxy) {
+    ASSERT_TRUE((bool)proxyFactory);
+    auto defaultTestProxy = proxyFactory->buildProxyWithDefaultAttributeExtension<
+                    commonapi::tests::TestInterfaceProxy,
+                    myExtensions::AttributeTestExtension>("local:commonapi.tests.TestInterface:commonapi.tests.TestInterface");
+    ASSERT_TRUE((bool)defaultTestProxy);
+}
+
+TEST_F(DBusProxyFactoryTest, CreatesIndividuallyExtendedTestProxy) {
+    ASSERT_TRUE((bool)proxyFactory);
+    auto specificAttributeExtendedTestProxy = proxyFactory->buildProxy<
+                    commonapi::tests::TestInterfaceProxy,
+                    commonapi::tests::TestInterfaceExtensions::TestDerivedArrayAttributeAttributeExtension<myExtensions::AttributeTestExtension> >
+            ("local:commonapi.tests.TestInterface:commonapi.tests.TestInterface");
+
+    ASSERT_TRUE((bool)specificAttributeExtendedTestProxy);
+
+    auto attributeExtension = specificAttributeExtendedTestProxy->getTestDerivedArrayAttributeAttributeExtension();
+    ASSERT_TRUE(attributeExtension.testExtensionMethod());
+}
+
+TEST_F(DBusProxyFactoryTest, HandlesRegistrationOfStubAdapters) {
+    ASSERT_TRUE((bool)proxyFactory);
+
+    const std::string serviceAddress = "local:commonapi.tests.TestInterface:commonapi.tests.TestInterface";
+
+    auto myStub = std::make_shared<commonapi::tests::TestInterfaceStubDefault>();
+    bool success = proxyFactory->registerService(myStub, serviceAddress);
+    ASSERT_TRUE(success);
+
+    success = proxyFactory->unregisterService("SomeOther:Unknown:Service");
+    ASSERT_FALSE(success);
+
+    success = proxyFactory->unregisterService(serviceAddress);
+    ASSERT_TRUE(success);
+}
+
+TEST_F(DBusProxyFactoryTest, GracefullyHandlesWrongAddresses) {
+    ASSERT_TRUE((bool)proxyFactory);
+    auto myStub = std::make_shared<commonapi::tests::TestInterfaceStubDefault>();
+
+    ASSERT_FALSE(proxyFactory->registerService(myStub, ""));
+    ASSERT_FALSE(proxyFactory->registerService(myStub, "too:much:stuff:here"));
+}
+
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/CommonAPI-DBus/src/test/DBusInputStreamTest.cpp b/CommonAPI-DBus/src/test/DBusInputStreamTest.cpp
new file mode 100644 (file)
index 0000000..354c792
--- /dev/null
@@ -0,0 +1,380 @@
+/* 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 <CommonAPI/SerializableStruct.h>
+#include <CommonAPI/DBus/DBusInputStream.h>
+#include <CommonAPI/DBus/DBusOutputStream.h>
+
+#include <unordered_map>
+#include <bits/functional_hash.h>
+
+#include <gtest/gtest.h>
+
+#include <dbus/dbus.h>
+
+#include <chrono>
+#include <cstdint>
+#include <vector>
+#include <unordered_map>
+#include <bits/functional_hash.h>
+
+
+class InputStreamTest: public ::testing::Test {
+  protected:
+    DBusMessage* libdbusMessage;
+    DBusMessageIter libdbusMessageWriteIter;
+    size_t numOfElements;
+
+    void SetUp() {
+        numOfElements = 2;
+        libdbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
+        ASSERT_TRUE(libdbusMessage != NULL);
+        dbus_message_iter_init_append(libdbusMessage, &libdbusMessageWriteIter);
+    }
+
+    void TearDown() {
+        dbus_message_unref(libdbusMessage);
+    }
+};
+
+TEST_F(InputStreamTest, CanBeConstructed) {
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+}
+
+TEST_F(InputStreamTest, ReadsEmptyMessages) {
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    EXPECT_EQ(0, scopedMessage.getBodyLength());
+}
+
+TEST_F(InputStreamTest, ReadsBytes) {
+    uint8_t val = 0xff;
+    for (int i = 0; i < numOfElements; i += 1) {
+        dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BYTE, &val);
+    }
+
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    EXPECT_EQ(numOfElements, scopedMessage.getBodyLength());
+    for (int i = 0; i < numOfElements; i += 1) {
+        uint8_t readVal;
+        inStream >> readVal;
+        EXPECT_EQ(val, readVal);
+    }
+}
+
+TEST_F(InputStreamTest, ReadsBools) {
+    dbus_bool_t f = FALSE;
+    dbus_bool_t t = TRUE;
+    for (int i = 0; i < numOfElements; i += 2) {
+        dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BOOLEAN, &t);
+        dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BOOLEAN, &f);
+    }
+
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
+    for (int i = 0; i < numOfElements; i += 2) {
+        bool readVal;
+        inStream >> readVal;
+        EXPECT_EQ(t, readVal);
+        inStream >> readVal;
+        EXPECT_EQ(f, readVal);
+    }
+}
+
+TEST_F(InputStreamTest, ReadsUint16) {
+
+    uint16_t val = 0xffff;
+    for (int i = 0; i < numOfElements; i += 1) {
+        dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT16, &val);
+    }
+
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    EXPECT_EQ(numOfElements*2, scopedMessage.getBodyLength());
+    for (int i = 0; i < numOfElements; i += 1) {
+        uint16_t readVal;
+        inStream >> readVal;
+        EXPECT_EQ(val, readVal);
+    }
+}
+
+TEST_F(InputStreamTest, ReadsInt16) {
+
+    int16_t val = 0x7fff;
+    for (int i = 0; i < numOfElements; i += 1) {
+        dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT16, &val);
+    }
+
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    EXPECT_EQ(numOfElements*2, scopedMessage.getBodyLength());
+    for (int i = 0; i < numOfElements; i += 1) {
+        int16_t readVal;
+        inStream >> readVal;
+        EXPECT_EQ(val, readVal);
+    }
+}
+
+TEST_F(InputStreamTest, ReadsUint32) {
+
+    uint32_t val = 0xffffffff;
+    for (int i = 0; i < numOfElements; i += 1) {
+        dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT32, &val);
+    }
+
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
+    for (int i = 0; i < numOfElements; i += 1) {
+        uint32_t readVal;
+        inStream >> readVal;
+        EXPECT_EQ(val, readVal);
+    }
+}
+
+TEST_F(InputStreamTest, ReadsInt32) {
+
+    int32_t val = 0x7fffffff;
+    for (int i = 0; i < numOfElements; i += 1) {
+        dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT32, &val);
+    }
+
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
+    for (int i = 0; i < numOfElements; i += 1) {
+        int32_t readVal;
+        inStream >> readVal;
+        EXPECT_EQ(val, readVal);
+    }
+}
+
+TEST_F(InputStreamTest, ReadsUint64) {
+
+    uint64_t val = 0xffffffffffffffff;
+    for (int i = 0; i < numOfElements; i += 1) {
+        dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT64, &val);
+    }
+
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
+    for (int i = 0; i < numOfElements; i += 1) {
+        uint64_t readVal;
+        inStream >> readVal;
+        EXPECT_EQ(val, readVal);
+    }
+}
+
+TEST_F(InputStreamTest, ReadsInt64) {
+
+    int64_t val = 0x7fffffffffffffff;
+    for (int i = 0; i < numOfElements; i += 1) {
+        dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT64, &val);
+    }
+
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
+    for (int i = 0; i < numOfElements; i += 1) {
+        int64_t readVal;
+        inStream >> readVal;
+        EXPECT_EQ(val, readVal);
+    }
+}
+
+TEST_F(InputStreamTest, ReadsDoubles) {
+
+    double val = 13.37;
+    for (int i = 0; i < numOfElements; i += 1) {
+        dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_DOUBLE, &val);
+    }
+
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
+    for (int i = 0; i < numOfElements; i += 1) {
+        double readVal;
+        inStream >> readVal;
+        EXPECT_EQ(val, readVal);
+    }
+}
+
+TEST_F(InputStreamTest, ReadsStrings) {
+
+    std::string val = "hai";
+    for (int i = 0; i < numOfElements; i += 1) {
+        dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_STRING, &val);
+    }
+
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    EXPECT_EQ(numOfElements*4 + numOfElements*4, scopedMessage.getBodyLength());
+    for (int i = 0; i < numOfElements; i += 1) {
+        std::string readVal;
+        inStream >> readVal;
+        EXPECT_EQ(val, readVal);
+    }
+}
+
+namespace bmw {
+namespace test {
+
+struct TestSerializableStruct: CommonAPI::SerializableStruct {
+    uint32_t a;
+    int16_t b;
+    bool c;
+    std::string d;
+    double e;
+
+       virtual void readFromInputStream(CommonAPI::InputStream& inputStream) {
+               inputStream >> a >> b >> c >> d >> e;
+       }
+
+       virtual void writeToOutputStream(CommonAPI::OutputStream& outputStream) const {
+               outputStream << a << b << c << d << e;
+       }
+};
+
+} //namespace test
+} //namespace bmw
+
+TEST_F(InputStreamTest, ReadsStructs) {
+
+    bmw::test::TestSerializableStruct testStruct;
+    testStruct.a = 15;
+    testStruct.b = -32;
+    testStruct.c = FALSE;
+    testStruct.d = "Hello all";
+    testStruct.e = 3.414;
+
+    DBusMessageIter subIter;
+    dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &subIter);
+    dbus_message_iter_append_basic(&subIter, DBUS_TYPE_UINT32, &testStruct.a);
+    dbus_message_iter_append_basic(&subIter, DBUS_TYPE_INT16, &testStruct.b);
+    dbus_bool_t dbusBool = static_cast<dbus_bool_t>(testStruct.c);
+    dbus_message_iter_append_basic(&subIter, DBUS_TYPE_BOOLEAN, &dbusBool);
+    dbus_message_iter_append_basic(&subIter, DBUS_TYPE_STRING, &testStruct.d);
+    dbus_message_iter_append_basic(&subIter, DBUS_TYPE_DOUBLE, &testStruct.e);
+    dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
+
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    //40(byte length of struct) = 4(uint32_t) + 2(int16_t) + 2(padding) + 4(bool) + 4(strlength)
+    //                          + 9(string) + 1(terminating '\0' of string) + 6(padding) + 8 (double)
+    EXPECT_EQ(40, scopedMessage.getBodyLength());
+
+    bmw::test::TestSerializableStruct verifyStruct;
+    inStream >> verifyStruct;
+    EXPECT_EQ(testStruct.a, verifyStruct.a);
+    EXPECT_EQ(testStruct.b, verifyStruct.b);
+    EXPECT_EQ(testStruct.c, verifyStruct.c);
+    EXPECT_EQ(testStruct.d, verifyStruct.d);
+    EXPECT_EQ(testStruct.e, verifyStruct.e);
+}
+
+TEST_F(InputStreamTest, ReadsArrays) {
+
+    std::vector<int32_t> testVector;
+    int32_t val1 = 0xffffffff;
+    int32_t val2 = 0x7fffffff;
+    for (int i = 0; i < numOfElements; i += 2) {
+        testVector.push_back(val1);
+        testVector.push_back(val2);
+    }
+
+    DBusMessageIter subIter;
+    dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_ARRAY, "i", &subIter);
+    for (int i = 0; i < numOfElements; i++) {
+        dbus_message_iter_append_basic(&subIter, DBUS_TYPE_INT32, &testVector[i]);
+    }
+    dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
+
+    CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    EXPECT_EQ(scopedMessage.getBodyLength(), numOfElements*4 + 4);
+    std::vector<int32_t> verifyVector;
+    inStream >> verifyVector;
+    int32_t res1;
+    int32_t res2;
+    for (int i = 0; i < numOfElements; i += 2) {
+        res1 = verifyVector[i];
+        EXPECT_EQ(val1, res1);
+        res2 = verifyVector[i + 1];
+        EXPECT_EQ(val2, res2);
+    }
+}
+
+TEST_F(InputStreamTest, ReadsArraysInArrays) {
+    size_t numOfElements = 2;
+    DBusMessage* dbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
+    ASSERT_TRUE(dbusMessage != NULL);
+
+    DBusMessageIter writeIter;
+    dbus_message_iter_init_append(dbusMessage, &writeIter);
+
+    std::vector<std::vector<int32_t>> testVector;
+    int32_t val1 = 0xffffffff;
+    int32_t val2 = 0x7fffffff;
+    for (int i = 0; i < numOfElements; i++) {
+        std::vector<int32_t> inner;
+        for (int j = 0; j < numOfElements; j += 2) {
+            inner.push_back(val1);
+            inner.push_back(val2);
+        }
+        testVector.push_back(inner);
+    }
+
+    DBusMessageIter subIter;
+    dbus_message_iter_open_container(&writeIter, DBUS_TYPE_ARRAY, "ai", &subIter);
+    for (int i = 0; i < numOfElements; i++) {
+        DBusMessageIter subsubIter;
+        dbus_message_iter_open_container(&subIter, DBUS_TYPE_ARRAY, "i", &subsubIter);
+        for (int j = 0; j < numOfElements; j++) {
+            dbus_message_iter_append_basic(&subsubIter, DBUS_TYPE_INT32, &(testVector[i][j]));
+        }
+        dbus_message_iter_close_container(&subIter, &subsubIter);
+    }
+    dbus_message_iter_close_container(&writeIter, &subIter);
+
+    CommonAPI::DBus::DBusMessage scopedMessage(dbusMessage);
+    CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
+
+    // 5*5*int32_t + 5*lengthField_inner(int32_t) + lengthField_outer(int32_t)
+    EXPECT_EQ(numOfElements*numOfElements*4 + numOfElements*4 + 4, scopedMessage.getBodyLength());
+    std::vector<std::vector<int32_t>> verifyVector;
+    inStream >> verifyVector;
+
+    int32_t res1;
+    int32_t res2;
+    for (int i = 0; i < numOfElements; i++) {
+        std::vector<int32_t> innerVerify = verifyVector[i];
+        for (int j = 0; j < numOfElements; j += 2) {
+            res1 = innerVerify[j];
+            EXPECT_EQ(val1, res1);
+            res2 = innerVerify[j + 1];
+            EXPECT_EQ(val2, res2);
+        }
+    }
+}
+
+int main(int argc, char** argv) {
+       ::testing::InitGoogleTest(&argc, argv);
+       return RUN_ALL_TESTS();
+}
diff --git a/CommonAPI-DBus/src/test/DBusMultipleConnectionTest.cpp b/CommonAPI-DBus/src/test/DBusMultipleConnectionTest.cpp
new file mode 100644 (file)
index 0000000..910547a
--- /dev/null
@@ -0,0 +1,125 @@
+/* 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 <gtest/gtest.h>
+
+#include <cassert>
+#include <cstdint>
+#include <iostream>
+#include <functional>
+#include <memory>
+#include <stdint.h>
+#include <string>
+#include <utility>
+#include <tuple>
+#include <type_traits>
+
+#include <CommonAPI/types.h>
+#include <CommonAPI/Runtime.h>
+
+#include "commonapi/tests/TestInterfaceProxy.h"
+#include "commonapi/tests/TestInterfaceStubDefault.h"
+const std::string serviceAddress = "local:commonapi.tests.TestInterface:commonapi.tests.TestInterface";
+
+class DBusMultipleConnectionTest: public ::testing::Test {
+ protected:
+    virtual void SetUp() {
+        proxyFactory = CommonAPI::Runtime::load()->createFactory();
+        stubFactory = CommonAPI::Runtime::load()->createFactory();
+        ASSERT_TRUE((bool)proxyFactory);
+        ASSERT_TRUE((bool)stubFactory);
+
+        stub = std::make_shared<commonapi::tests::TestInterfaceStubDefault>();
+        bool success = stubFactory->registerService(stub, serviceAddress);
+        ASSERT_TRUE(success);
+
+        proxy = proxyFactory->buildProxy<commonapi::tests::TestInterfaceProxy>(serviceAddress);
+        ASSERT_TRUE((bool)proxy);
+    }
+
+    virtual void TearDown() {
+    }
+
+    std::shared_ptr<CommonAPI::Factory> proxyFactory;
+    std::shared_ptr<CommonAPI::Factory> stubFactory;
+    std::shared_ptr<commonapi::tests::TestInterfaceStubDefault> stub;
+    std::shared_ptr<commonapi::tests::TestInterfaceProxy<> > proxy;
+
+};
+
+
+TEST_F(DBusMultipleConnectionTest, SetAttribute) {
+    uint32_t v1 = 5;
+    uint32_t v2;
+    CommonAPI::CallStatus stat;
+    proxy->getTestPredefinedTypeAttributeAttribute().setValue(v1, stat, v2);
+    ASSERT_EQ(stat, CommonAPI::CallStatus::SUCCESS);
+    ASSERT_EQ(v1, v2);
+}
+
+TEST_F(DBusMultipleConnectionTest, SetAttributeBroadcast) {
+    uint32_t v1 = 6;
+    uint32_t v2;
+    uint32_t v3 = 0;
+
+    std::promise<bool> promise;
+    auto future = promise.get_future();
+
+    proxy->getTestPredefinedTypeAttributeAttribute().getChangedEvent().subscribe([&](
+                    const uint32_t intVal) {
+        v3 = intVal;
+        promise.set_value(true);
+    });
+
+    CommonAPI::CallStatus stat;
+    proxy->getTestPredefinedTypeAttributeAttribute().setValue(v1, stat, v2);
+    ASSERT_EQ(stat, CommonAPI::CallStatus::SUCCESS);
+    ASSERT_EQ(v1, v2);
+
+    ASSERT_TRUE(future.get());
+    ASSERT_EQ(v1, v3);
+
+}
+
+
+TEST_F(DBusMultipleConnectionTest, GetAttribute) {
+    uint32_t v1;
+    CommonAPI::CallStatus stat = proxy->getTestPredefinedTypeAttributeAttribute().getValue(v1);
+    ASSERT_EQ(stat, CommonAPI::CallStatus::SUCCESS);
+}
+
+TEST_F(DBusMultipleConnectionTest, RemoteMethodCall) {
+    uint32_t v1 = 5;
+    std::string v2 = "Hai :)";
+    CommonAPI::CallStatus stat;
+    proxy->testVoidPredefinedTypeMethod(v1, v2, stat);
+    ASSERT_EQ(stat, CommonAPI::CallStatus::SUCCESS);
+}
+
+TEST_F(DBusMultipleConnectionTest, Broadcast) {
+    uint32_t v1 = 5;
+    uint32_t v3 = 0;
+    std::string v2 = "Hai :)";
+
+    std::promise<bool> promise;
+    auto future = promise.get_future();
+
+    proxy->getTestPredefinedTypeBroadcastEvent().subscribe([&](
+                    const uint32_t intVal, const std::string& strVal) {
+        v3 = intVal;
+        promise.set_value(true);
+    });
+
+    stub->firePredefinedBroadcast(v1, v2);
+
+    ASSERT_TRUE(future.get());
+    ASSERT_EQ(v1, v3);
+}
+
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
+
diff --git a/CommonAPI-DBus/src/test/DBusNameCacheTest.cpp b/CommonAPI-DBus/src/test/DBusNameCacheTest.cpp
new file mode 100644 (file)
index 0000000..91061bc
--- /dev/null
@@ -0,0 +1,28 @@
+/* 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 <common-api-dbus/dbus-connection.h>
+#include <common-api-dbus/dbus-name-cache.h>
+
+
+
+int main(void) {
+       auto dbusConnection = common::api::dbus::DBusConnection::getSessionBus();
+
+       dbusConnection->connect();
+
+       common::api::dbus::DBusNameCache dbusNameCache(dbusConnection);
+
+       dbusConnection->requestServiceNameAndBlock("common.api.dbus.test.DBusNameCache");
+
+       for (int i = 0; i < 5; i++)
+               dbusConnection->readWriteDispatch(100);
+
+       dbusConnection->releaseServiceName("common.api.dbus.test.DBusNameCache");
+
+       for (int i = 0; i < 5; i++)
+               dbusConnection->readWriteDispatch(100);
+
+       return 0;
+}
diff --git a/CommonAPI-DBus/src/test/DBusOutputStreamTest.cpp b/CommonAPI-DBus/src/test/DBusOutputStreamTest.cpp
new file mode 100644 (file)
index 0000000..184b852
--- /dev/null
@@ -0,0 +1,706 @@
+/* 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 <dbus/dbus.h>
+#include <gtest/gtest.h>
+
+#include <CommonAPI/DBus/DBusMessage.h>
+#include <CommonAPI/DBus/DBusOutputStream.h>
+#include <CommonAPI/DBus/DBusInputStream.h>
+#include <CommonAPI/SerializableStruct.h>
+
+
+class OutputStreamTest: public ::testing::Test {
+protected:
+  size_t numOfElements;
+  CommonAPI::DBus::DBusMessage message;
+  const char* busName;
+  const char* objectPath;
+  const char* interfaceName;
+  const char* methodName;
+
+  void SetUp() {
+    numOfElements = 10;
+    busName = "no.bus.here";
+    objectPath = "/no/object/here";
+    interfaceName = "no.interface.here";
+    methodName = "noMethodHere";
+  }
+
+  void TearDown() {
+  }
+};
+
+TEST_F(OutputStreamTest, CanBeConstructed) {
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+}
+
+TEST_F(OutputStreamTest, WritesBytes) {
+  const char* signature = "yyyyyyyyyy";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  outStream.reserveMemory(numOfElements);
+  uint8_t val1 = 0xff;
+  uint8_t val2 = 0x00;
+  for (int i = 0; i < numOfElements; i += 2) {
+    outStream << val1;
+    outStream << val2;
+  }
+  outStream.flush();
+
+  EXPECT_EQ(numOfElements, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+
+  uint8_t verifyVal1;
+  uint8_t verifyVal2;
+  for (int i = 0; i < numOfElements; i += 2) {
+    inStream >> verifyVal1;
+    EXPECT_EQ(val1, verifyVal1);
+
+    inStream >> verifyVal2;
+    EXPECT_EQ(val2, verifyVal2);
+  }
+}
+
+TEST_F(OutputStreamTest, WritesBools) {
+  const char* signature = "bbbbbbbbbb";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  outStream.reserveMemory(numOfElements * 4);
+  bool val1 = TRUE;
+  bool val2 = FALSE;
+  for (int i = 0; i < numOfElements; i += 2) {
+    outStream << val1;
+    outStream << val2;
+  }
+  outStream.flush();
+
+  EXPECT_EQ(numOfElements*4, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+
+  bool verifyVal1;
+  bool verifyVal2;
+  for (int i = 0; i < numOfElements; i += 2) {
+    inStream >> verifyVal1;
+    EXPECT_EQ(val1, verifyVal1);
+
+    inStream >> verifyVal2;
+    EXPECT_EQ(val2, verifyVal2);
+  }
+}
+
+TEST_F(OutputStreamTest, WritesUInt16) {
+  const char* signature = "qqqqqqqqqq";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  outStream.reserveMemory(numOfElements * 2);
+  uint16_t val1 = 0x0000;
+  uint16_t val2 = 0xffff;
+  for (int i = 0; i < numOfElements; i += 2) {
+    outStream << val1;
+    outStream << val2;
+  }
+  outStream.flush();
+
+  EXPECT_EQ(numOfElements*2, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+
+  uint16_t verifyVal1;
+  uint16_t verifyVal2;
+  for (int i = 0; i < numOfElements; i += 2) {
+    inStream >> verifyVal1;
+    EXPECT_EQ(val1, verifyVal1);
+
+    inStream >> verifyVal2;
+    EXPECT_EQ(val2, verifyVal2);
+  }
+}
+
+TEST_F(OutputStreamTest, WritesInt16) {
+  const char* signature = "nnnnnnnnnn";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  outStream.reserveMemory(numOfElements * 2);
+  int16_t val1 = 0x7fff;
+  int16_t val2 = 0xffff;
+  for (int i = 0; i < numOfElements; i += 2) {
+    outStream << val1;
+    outStream << val2;
+  }
+  outStream.flush();
+
+  EXPECT_EQ(numOfElements*2, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+
+  int16_t verifyVal1;
+  int16_t verifyVal2;
+  for (int i = 0; i < numOfElements; i += 2) {
+    inStream >> verifyVal1;
+    EXPECT_EQ(val1, verifyVal1);
+
+    inStream >> verifyVal2;
+    EXPECT_EQ(val2, verifyVal2);
+  }
+}
+
+TEST_F(OutputStreamTest, WritesUInt32) {
+  const char* signature = "uuuuuuuuuu";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  outStream.reserveMemory(numOfElements * 4);
+  uint32_t val1 = 0x00000000;
+  uint32_t val2 = 0xffffffff;
+  for (int i = 0; i < numOfElements; i += 2) {
+    outStream << val1;
+    outStream << val2;
+  }
+  outStream.flush();
+
+  EXPECT_EQ(numOfElements*4, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+
+  uint32_t verifyVal1;
+  uint32_t verifyVal2;
+  for (int i = 0; i < numOfElements; i += 2) {
+    inStream >> verifyVal1;
+    EXPECT_EQ(val1, verifyVal1);
+
+    inStream >> verifyVal2;
+    EXPECT_EQ(val2, verifyVal2);
+  }
+}
+
+TEST_F(OutputStreamTest, WritesInt32) {
+  const char* signature = "iiiiiiiiii";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  outStream.reserveMemory(numOfElements * 4);
+  int32_t val1 = 0x7fffffff;
+  int32_t val2 = 0xffffffff;
+  for (int i = 0; i < numOfElements; i += 2) {
+    outStream << val1;
+    outStream << val2;
+  }
+  outStream.flush();
+
+  EXPECT_EQ(numOfElements*4, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+
+  int32_t verifyVal1;
+  int32_t verifyVal2;
+  for (int i = 0; i < numOfElements; i += 2) {
+    inStream >> verifyVal1;
+    EXPECT_EQ(val1, verifyVal1);
+
+    inStream >> verifyVal2;
+    EXPECT_EQ(val2, verifyVal2);
+  }
+}
+
+TEST_F(OutputStreamTest, WritesUInt64) {
+  const char* signature = "tttttttttt";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  outStream.reserveMemory(numOfElements * 8);
+  uint64_t val1 = 0x0000000000000000;
+  uint64_t val2 = 0xffffffffffffffff;
+  for (int i = 0; i < numOfElements; i += 2) {
+    outStream << val1;
+    outStream << val2;
+  }
+  outStream.flush();
+
+  EXPECT_EQ(numOfElements*8, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+
+  uint64_t verifyVal1;
+  uint64_t verifyVal2;
+  for (int i = 0; i < numOfElements; i += 2) {
+    inStream >> verifyVal1;
+    EXPECT_EQ(val1, verifyVal1);
+
+    inStream >> verifyVal2;
+    EXPECT_EQ(val2, verifyVal2);
+  }
+}
+
+TEST_F(OutputStreamTest, WritesInt64) {
+  const char* signature = "xxxxxxxxxx";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  outStream.reserveMemory(numOfElements * 8);
+  int64_t val1 = 0x7fffffffffffffff;
+  int64_t val2 = 0xffffffffffffffff;
+  for (int i = 0; i < numOfElements; i += 2) {
+    outStream << val1;
+    outStream << val2;
+  }
+  outStream.flush();
+
+  EXPECT_EQ(numOfElements*8, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+
+  int64_t verifyVal1;
+  int64_t verifyVal2;
+  for (int i = 0; i < numOfElements; i += 2) {
+    inStream >> verifyVal1;
+    EXPECT_EQ(val1, verifyVal1);
+
+    inStream >> verifyVal2;
+    EXPECT_EQ(val2, verifyVal2);
+  }
+}
+
+TEST_F(OutputStreamTest, WritesDouble) {
+  const char* signature = "dddddddddd";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  outStream.reserveMemory(numOfElements * 8);
+  double val1 = 13.37;
+  double val2 = 3.414;
+  for (int i = 0; i < numOfElements; i += 2) {
+    outStream << val1;
+    outStream << val2;
+  }
+  outStream.flush();
+
+  EXPECT_EQ(numOfElements*8, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+
+  double verifyVal1;
+  double verifyVal2;
+  std::string verifySignature;
+  for (int i = 0; i < numOfElements; i += 2) {
+    inStream >> verifyVal1;
+    EXPECT_EQ(val1, verifyVal1);
+
+    inStream >> verifyVal2;
+    EXPECT_EQ(val2, verifyVal2);
+  }
+}
+
+TEST_F(OutputStreamTest, WritesStrings) {
+  const char* signature = "sss";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  std::string val1 = "hai";
+  std::string val2 = "ciao";
+  std::string val3 = "salut";
+
+  //sizes of the strings + terminating null-bytes (each 1 byte) + length-fields (each 4 bytes)
+  outStream.reserveMemory(val1.size() + val2.size() + val3.size() + 3 + 3 * 4);
+  outStream << val1 << val2 << val3;
+  outStream.flush();
+
+  //Length fields + actual strings + terminating '\0's + 3(padding)
+  EXPECT_EQ(3*4 + 3 + 4 + 5 + 3 + 3, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+
+  std::string verifyVal1;
+  std::string verifyVal2;
+  std::string verifyVal3;
+  std::string verifySignature;
+
+  inStream >> verifyVal1;
+  inStream >> verifyVal2;
+  inStream >> verifyVal3;
+
+  EXPECT_EQ(val1, verifyVal1);
+  EXPECT_EQ(val2, verifyVal2);
+  EXPECT_EQ(val3, verifyVal3);
+}
+
+namespace bmw {
+namespace test {
+
+struct myStruct: CommonAPI::SerializableStruct {
+  ~myStruct();
+
+  uint32_t a;
+  int16_t b;
+  bool c;
+  std::string d;
+  double e;
+
+  virtual void readFromInputStream(CommonAPI::InputStream& inputMessageStream);
+  virtual void writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const;
+};
+
+myStruct::~myStruct() {
+}
+
+void myStruct::readFromInputStream(CommonAPI::InputStream& inputMessageStream) {
+  inputMessageStream >> a >> b >> c >> d >> e;
+}
+
+void myStruct::writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const {
+  outputMessageStream << a << b << c << d << e;
+}
+
+} //namespace test
+} //namespace bmw
+
+TEST_F(OutputStreamTest, WritesStructs) {
+  const char* signature = "(unbsd)";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  bmw::test::myStruct testStruct;
+  testStruct.a = 15;
+  testStruct.b = -32;
+  testStruct.c = FALSE;
+  testStruct.d = "Hello all";
+  testStruct.e = 3.414;
+
+  // 40(byte length of struct) = 4(uint32_t) + 2(int16_t) + 2(padding) + 4(bool) + 4(strlength)
+  //                           + 9(string) + 1(terminating '\0' of string) + 6(padding) + 8 (double)
+  outStream.reserveMemory(40);
+  outStream << testStruct;
+  outStream.flush();
+
+  EXPECT_EQ(40, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+  bmw::test::myStruct verifyStruct;
+  inStream >> verifyStruct;
+
+  EXPECT_EQ(testStruct.a, verifyStruct.a);
+  EXPECT_EQ(testStruct.b, verifyStruct.b);
+  EXPECT_EQ(testStruct.c, verifyStruct.c);
+  EXPECT_EQ(testStruct.d, verifyStruct.d);
+  EXPECT_EQ(testStruct.e, verifyStruct.e);
+}
+
+TEST_F(OutputStreamTest, WritesArrays) {
+  const char* signature = "ai";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  std::vector<int32_t> testVector;
+  int32_t val1 = 0xffffffff;
+  int32_t val2 = 0x7fffffff;
+  for (int i = 0; i < numOfElements; i += 2) {
+    testVector.push_back(val1);
+    testVector.push_back(val2);
+  }
+
+  outStream.reserveMemory(numOfElements * 4 + 4);
+  outStream << testVector;
+  outStream.flush();
+
+  EXPECT_EQ(numOfElements*4 + 4, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+  std::vector<int32_t> verifyVector;
+  inStream >> verifyVector;
+
+  int32_t res1;
+  int32_t res2;
+  for (int i = 0; i < numOfElements; i += 2) {
+    res1 = verifyVector[i];
+    EXPECT_EQ(val1, res1);
+    res2 = verifyVector[i + 1];
+    EXPECT_EQ(val2, res2);
+  }
+}
+
+TEST_F(OutputStreamTest, WritesArraysOfStrings) {
+  const char* signature = "as";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  std::vector<std::string> testVector;
+  std::string val1 = "Hai";
+  std::string val2 = "Ciao";
+  for (int i = 0; i < numOfElements; i += 2) {
+    testVector.push_back(val1);
+    testVector.push_back(val2);
+  }
+
+  // 101 = 4(lengthFieldOfArray) +
+  //       4*(4(lengthField1) + 4(string1 mit \0-byte) + 4(lengthField2) + 5(string2 mit \0-byte) + 3(paddingTo4)) +
+  //         (4(lengthField1) + 4(string1 mit \0-byte) + 4(lengthField2) + 5(string2 mit \0-byte))
+  size_t vectorLength = 101;
+  outStream.reserveMemory(vectorLength);
+  outStream << testVector;
+  outStream.flush();
+
+  EXPECT_EQ(vectorLength, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+  std::vector<std::string> verifyVector;
+  inStream >> verifyVector;
+
+  std::string res1;
+  std::string res2;
+  for (int i = 0; i < numOfElements; i += 2) {
+    res1 = verifyVector[i];
+    EXPECT_EQ(val1, res1);
+    res2 = verifyVector[i + 1];
+    EXPECT_EQ(val2, res2);
+  }
+}
+
+TEST_F(OutputStreamTest, WritesArraysInArrays) {
+  const char* signature = "aai";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  std::vector<std::vector<int32_t>> testVector;
+  int32_t val1 = 0xffffffff;
+  int32_t val2 = 0x7fffffff;
+  for (int i = 0; i < numOfElements; i++) {
+    std::vector<int32_t> inner;
+    for (int j = 0; j < numOfElements; j += 2) {
+      inner.push_back(val1);
+      inner.push_back(val2);
+    }
+    testVector.push_back(inner);
+  }
+
+  outStream.reserveMemory(numOfElements * numOfElements * 4 + numOfElements * 4 + 4);
+  outStream << testVector;
+  outStream.flush();
+
+  EXPECT_EQ(numOfElements*numOfElements*4 + numOfElements*4 + 4, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+  std::vector<std::vector<int32_t>> verifyVector;
+  inStream >> verifyVector;
+
+  int32_t res1;
+  int32_t res2;
+  for (int i = 0; i < numOfElements; i++) {
+    std::vector<int32_t> innerVerify = verifyVector[i];
+    for (int j = 0; j < numOfElements; j += 2) {
+      res1 = innerVerify[j];
+      EXPECT_EQ(val1, res1);
+      res2 = innerVerify[j + 1];
+      EXPECT_EQ(val2, res2);
+    }
+  }
+}
+
+namespace com {
+namespace bmw {
+namespace test {
+
+struct TestStruct: CommonAPI::SerializableStruct {
+  TestStruct();
+  TestStruct(int32_t v1, double v2, double v3, std::string v4);
+  ~TestStruct();
+
+  int32_t val1;
+  double val2;
+  double val3;
+  std::string val4;
+
+  virtual void readFromInputStream(CommonAPI::InputStream& inputMessageStream);
+  virtual void writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const;
+};
+
+typedef std::vector<TestStruct> TestStructList;
+
+TestStruct::TestStruct() :
+    val1(0), val2(0), val3(0), val4("") {
+}
+
+TestStruct::TestStruct(int32_t v1, double v2, double v3, std::string v4) :
+    val1(v1), val2(v2), val3(v3), val4(v4) {
+}
+
+TestStruct::~TestStruct() {
+}
+
+void TestStruct::readFromInputStream(CommonAPI::InputStream& inputMessageStream) {
+  inputMessageStream >> val1 >> val2 >> val3 >> val4;
+}
+
+void TestStruct::writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const {
+  outputMessageStream << val1 << val2 << val3 << val4;
+}
+
+} // namespace test
+} // namespace bmw
+} // namespace com
+
+
+TEST_F(OutputStreamTest, WritesTestStructs) {
+  const char* signature = "(idds)";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  com::bmw::test::TestStruct testStruct(1, 12.6, 1e40, "XXXXXXXXXXXXXXXXXXXX");
+
+  //4(int32_t) + 4(padding) + 8(double) + 8(double) + 4(str_length) + 20(string) + 1(null-termination)
+  uint32_t expectedSize = 49;
+  outStream.reserveMemory(expectedSize);
+  outStream << testStruct;
+  outStream.flush();
+
+  EXPECT_EQ(expectedSize, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+  com::bmw::test::TestStruct verifyStruct;
+  inStream >> verifyStruct;
+
+  EXPECT_EQ(testStruct.val1, verifyStruct.val1);
+  EXPECT_EQ(testStruct.val2, verifyStruct.val2);
+  EXPECT_EQ(testStruct.val3, verifyStruct.val3);
+  EXPECT_EQ(testStruct.val4, verifyStruct.val4);
+}
+
+TEST_F(OutputStreamTest, WritesTestStructLists) {
+  const char* signature = "a(idds)";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  com::bmw::test::TestStructList testList;
+  for (int i = 0; i < numOfElements; i++) {
+    testList.emplace_back(1, 12.6, 1e40, "XXXXXXXXXXXXXXXXXXXX");
+  }
+
+  //struct size: 49 = 4(int32_t) + 4(padding) + 8(double) + 8(double) + 4(str_length) + 20(string) + 1(null-termination)
+  //array size:  4(array_length) + 4(struct_padding) + (numElements-1)*(49(struct) + 7(struct_padding)) + 49(struct)
+  uint32_t expectedSize = 8 + (numOfElements - 1) * (49 + 7) + 49;
+  outStream.reserveMemory(expectedSize);
+  outStream << testList;
+  outStream.flush();
+
+  EXPECT_EQ(expectedSize, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+  com::bmw::test::TestStructList verifyList;
+  inStream >> verifyList;
+
+  EXPECT_EQ(numOfElements, verifyList.size());
+}
+
+
+
+namespace com {
+namespace bmw {
+namespace test {
+
+struct ArrayStruct: CommonAPI::SerializableStruct {
+  ArrayStruct();
+  ArrayStruct(std::vector<int64_t> v1, std::vector<std::string> v2, std::vector<double> v3, std::vector<std::string> v4, std::vector<uint16_t> v5);
+  ~ArrayStruct();
+
+  std::vector<int64_t> val1;
+  std::vector<std::string> val2;
+  std::vector<double> val3;
+  std::vector<std::string> val4;
+  std::vector<uint16_t> val5;
+
+  virtual void readFromInputStream(CommonAPI::InputStream& inputMessageStream);
+  virtual void writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const;
+};
+
+typedef std::vector<TestStruct> TestStructList;
+
+ArrayStruct::ArrayStruct() {
+}
+
+ArrayStruct::ArrayStruct(std::vector<int64_t> v1, std::vector<std::string> v2, std::vector<double> v3, std::vector<std::string> v4, std::vector<uint16_t> v5) :
+    val1(v1), val2(v2), val3(v3), val4(v4), val5(v5) {
+}
+
+ArrayStruct::~ArrayStruct() {
+}
+
+void ArrayStruct::readFromInputStream(CommonAPI::InputStream& inputMessageStream) {
+  inputMessageStream >> val1 >> val2 >> val3 >> val4 >> val5;
+}
+
+void ArrayStruct::writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const {
+  outputMessageStream << val1 << val2 << val3 << val4 << val5;
+}
+
+} // namespace test
+} // namespace bmw
+} // namespace com
+
+
+TEST_F(OutputStreamTest, WritesStructsOfArraysWithSthBefore) {
+  const char* signature = "(axasadasaq)";
+  message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
+  CommonAPI::DBus::DBusOutputStream outStream(message);
+
+  com::bmw::test::ArrayStruct arrayStruct;
+  for (int i = 0; i < numOfElements; i++) {
+      arrayStruct.val1.push_back(i*50);
+      arrayStruct.val2.push_back("Hai");
+      arrayStruct.val3.push_back(3.414);
+      arrayStruct.val4.push_back("Ciao");
+      arrayStruct.val5.push_back(i*5);
+  }
+  uint16_t frontValue = 0;
+
+  // 2(uint16) + 6(padding)                                             --> 8
+  // 4(LengthField) + 4(padding) + 10 * 8(int64)                        --> 88  --> 96
+  // 4(LengthField) + 10 * (4(LengthField) + 4("Hai\0"))                --> 84  --> 180
+  // 4(LengthField) + 10 * 8(double)                                    --> 84  --> 264
+  // 4(LengthField) + 10 * (4(LengthField) + 5("Ciao\0") + 3(padding))  --> 124 --> 388
+  // 4(LengthField) + 10 * 2(uint16)                                    --> 24  --> 412
+  size_t structLength = 412;
+  outStream.reserveMemory(structLength);
+  outStream << frontValue << arrayStruct;
+  outStream.flush();
+
+  EXPECT_EQ(structLength, message.getBodyLength());
+
+  CommonAPI::DBus::DBusInputStream inStream(message);
+  com::bmw::test::ArrayStruct verifyStruct;
+
+  uint16_t frontVerification;
+  inStream >> frontVerification >> verifyStruct;
+
+  EXPECT_EQ(frontValue, frontVerification);
+
+  int64_t res1;
+  std::string res2;
+  double res3;
+  std::string res4;
+  uint16_t res5;
+
+  for (int i = 0; i < numOfElements; i++) {
+    res1 = verifyStruct.val1[i];
+    res2 = verifyStruct.val2[i];
+    res3 = verifyStruct.val3[i];
+    res4 = verifyStruct.val4[i];
+    res5 = verifyStruct.val5[i];
+
+    EXPECT_EQ(i*50, res1);
+    EXPECT_EQ(std::string("Hai"), res2);
+    EXPECT_EQ(3.414, res3);
+    EXPECT_EQ(std::string("Ciao"), res4);
+    EXPECT_EQ(i*5, res5);
+  }
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/CommonAPI-DBus/src/test/DBusProxyTest.cpp b/CommonAPI-DBus/src/test/DBusProxyTest.cpp
new file mode 100644 (file)
index 0000000..1c9beb8
--- /dev/null
@@ -0,0 +1,156 @@
+/* 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 <dbus/dbus.h>
+#include <CommonAPI/DBus/DBusInputStream.h>
+#include <CommonAPI/DBus/DBusMessage.h>
+#include <CommonAPI/DBus/DBusProxy.h>
+#include <CommonAPI/DBus/DBusConnection.h>
+#include <CommonAPI/DBus/DBusStubAdapter.h>
+#include <stdint.h>
+#include <vector>
+#include <gtest/gtest.h>
+#include <iostream>
+#include <algorithm>
+#include <string>
+
+
+class TestProxy: public CommonAPI::DBus::DBusProxy {
+public:
+  TestProxy(const std::shared_ptr<CommonAPI::DBus::DBusConnection>& dbusConnection);
+  ~TestProxy() = default;
+
+protected:
+  void getOwnVersion(uint16_t& ownVersionMajor, uint16_t& ownVersionMinor) const;
+
+};
+
+class TestStubAdapter: public CommonAPI::DBus::DBusStubAdapter {
+public:
+    TestStubAdapter(const std::shared_ptr<CommonAPI::DBus::DBusConnection>& dbusConnection);
+protected:
+    bool onInterfaceDBusMessage(const CommonAPI::DBus::DBusMessage& dbusMessage);
+    const char* getMethodsDBusIntrospectionXmlData() const;
+};
+
+const char* TestStubAdapter::getMethodsDBusIntrospectionXmlData() const {
+    return "";
+}
+
+bool TestStubAdapter::onInterfaceDBusMessage(const CommonAPI::DBus::DBusMessage& dbusMessage) {
+    return true;
+}
+
+TestStubAdapter::TestStubAdapter(const std::shared_ptr<CommonAPI::DBus::DBusConnection>& dbusConnection) :
+        CommonAPI::DBus::DBusStubAdapter(
+        "com.bmw.test.Echo",
+        "/com/bmw/test/Echo",
+        "com.bmw.test.Echo",
+        dbusConnection) {
+}
+
+TestProxy::TestProxy(const std::shared_ptr<CommonAPI::DBus::DBusConnection>& dbusConnection) :
+               CommonAPI::DBus::DBusProxy(
+        "com.bmw.test.Echo",
+        "/com/bmw/test/Echo",
+        "com.bmw.test.Echo",
+        dbusConnection) {
+}
+
+void TestProxy::getOwnVersion(uint16_t& ownVersionMajor, uint16_t& ownVersionMinor) const {
+}
+
+
+const static std::string ID = "com.bmw.test.Echo";
+
+
+class ProxyTest: public ::testing::Test {
+protected:
+
+    virtual void TearDown() {
+        dbusConnection_->disconnect();
+    }
+
+    void SetUp() {
+        dbusConnection_ = CommonAPI::DBus::DBusConnection::getSessionBus();
+        ASSERT_TRUE(dbusConnection_->connect());
+        proxy_ = std::make_shared<TestProxy>(dbusConnection_);
+    }
+
+    std::shared_ptr<CommonAPI::DBus::DBusConnection> dbusConnection_;
+    std::shared_ptr<TestProxy> proxy_;
+};
+
+TEST_F(ProxyTest, HasCorrectBusName) {
+  std::string actualName = proxy_->getDBusBusName();
+  EXPECT_EQ("com.bmw.test.Echo", actualName);
+}
+
+TEST_F(ProxyTest, HasCorrectObjectPath) {
+  std::string actualPath = proxy_->getDBusObjectPath();
+  EXPECT_EQ("/com/bmw/test/Echo", actualPath);
+}
+
+TEST_F(ProxyTest, HasCorrectInterfaceName) {
+  std::string actualName = proxy_->getInterfaceName();
+  EXPECT_EQ("com.bmw.test.Echo", actualName);
+}
+
+TEST_F(ProxyTest, IsNotAvailable) {
+       bool isAvailable = proxy_->isAvailable();
+       EXPECT_FALSE(isAvailable);
+}
+
+TEST_F(ProxyTest, ServiceRegistry) {
+       std::shared_ptr<CommonAPI::DBus::DBusProxyConnection> connection = proxy_->getDBusConnection();
+       auto registry = connection->getDBusServiceRegistry();
+       ASSERT_FALSE(!registry);
+}
+
+TEST_F(ProxyTest, ServiceStatus) {
+    std::shared_ptr<TestStubAdapter> stub_ = std::make_shared<TestStubAdapter>(dbusConnection_);
+       stub_->init();
+    dbusConnection_->requestServiceNameAndBlock(ID);
+
+       std::vector<std::string> actuallyAvailableServices;
+
+
+       actuallyAvailableServices = dbusConnection_->getDBusServiceRegistry()->getAvailableServiceInstances("com.bmw.test.Echo",
+                       "local");
+
+       std::string toFind = "com.bmw.test.Echo";
+       auto found = std::find(actuallyAvailableServices.begin(), actuallyAvailableServices.end(), toFind);
+
+       ASSERT_TRUE(actuallyAvailableServices.begin() != actuallyAvailableServices.end());
+}
+
+TEST_F(ProxyTest, IsAvailableBlocking) {
+    std::shared_ptr<TestStubAdapter> stub = std::make_shared<TestStubAdapter>(dbusConnection_);
+    stub->init();
+    dbusConnection_->requestServiceNameAndBlock(ID);
+
+    bool isAvailable = proxy_->isAvailableBlocking();
+    EXPECT_TRUE(isAvailable);
+}
+
+TEST_F(ProxyTest, HasNecessaryAttributesAndEvents) {
+       CommonAPI::InterfaceVersionAttribute& versionAttribute = (proxy_->getInterfaceVersionAttribute());
+       CommonAPI::ProxyStatusEvent& statusEvent = (proxy_->getProxyStatusEvent());
+}
+
+TEST_F(ProxyTest, IsConnected) {
+  ASSERT_TRUE(proxy_->getDBusConnection()->isConnected());
+}
+
+TEST_F(ProxyTest, TestInterfaceVersionAttribute) {
+       CommonAPI::InterfaceVersionAttribute& versionAttribute = proxy_->getInterfaceVersionAttribute();
+       CommonAPI::Version version;
+       CommonAPI::CallStatus status = versionAttribute.getValue(version);
+       ASSERT_EQ(CommonAPI::CallStatus::NOT_AVAILABLE, status);
+}
+
+int main(int argc, char** argv) {
+       ::testing::InitGoogleTest(&argc, argv);
+       return RUN_ALL_TESTS();
+}
diff --git a/CommonAPI-DBus/src/test/DBusRuntimeTest.cpp b/CommonAPI-DBus/src/test/DBusRuntimeTest.cpp
new file mode 100644 (file)
index 0000000..33f4017
--- /dev/null
@@ -0,0 +1,78 @@
+/* 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 <gtest/gtest.h>
+
+#include <cstring>
+
+#include <CommonAPI/DBus/DBusRuntime.h>
+#include <CommonAPI/DBus/DBusFactory.h>
+
+
+
+class DBusRuntimeTest: public ::testing::Test {
+ protected:
+       virtual void SetUp() {
+       }
+
+       virtual void TearDown() {
+       }
+};
+
+
+
+TEST_F(DBusRuntimeTest, LoadsDefaultStaticallyLinkedDBusLibrary) {
+    std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::load();
+    ASSERT_TRUE((bool)runtime);
+    CommonAPI::DBus::DBusRuntime* dbusRuntime = dynamic_cast<CommonAPI::DBus::DBusRuntime*>(&(*runtime));
+    ASSERT_TRUE(dbusRuntime != NULL);
+}
+
+
+TEST_F(DBusRuntimeTest, LoadsSpecifiedStaticallyLinkedDBusLibrary) {
+    std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::load("DBus");
+    ASSERT_TRUE((bool)runtime);
+    CommonAPI::DBus::DBusRuntime* dbusRuntime = dynamic_cast<CommonAPI::DBus::DBusRuntime*>(&(*runtime));
+    ASSERT_TRUE(dbusRuntime != NULL);
+}
+
+
+TEST_F(DBusRuntimeTest, LoadsDBusLibraryAsSingleton) {
+    std::shared_ptr<CommonAPI::Runtime> runtime1 = CommonAPI::Runtime::load("DBus");
+    std::shared_ptr<CommonAPI::Runtime> runtime2 = CommonAPI::Runtime::load("DBus");
+    ASSERT_TRUE((bool)runtime1);
+    ASSERT_TRUE((bool)runtime2);
+
+    CommonAPI::DBus::DBusRuntime* dbusRuntime1 = dynamic_cast<CommonAPI::DBus::DBusRuntime*>(&(*runtime1));
+    CommonAPI::DBus::DBusRuntime* dbusRuntime2 = dynamic_cast<CommonAPI::DBus::DBusRuntime*>(&(*runtime2));
+    ASSERT_TRUE(dbusRuntime1 != NULL);
+    ASSERT_TRUE(dbusRuntime2 != NULL);
+
+    ASSERT_TRUE(dbusRuntime1 == dbusRuntime2);
+}
+
+
+TEST_F(DBusRuntimeTest, ReturnsEmptyPointerOnRequestForUnknownMiddleware) {
+    std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::load("UnknownMiddlewareId");
+    ASSERT_FALSE((bool)runtime);
+}
+
+
+TEST_F(DBusRuntimeTest, DBusRuntimeLoadsDBusFactory) {
+    std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::load("DBus");
+    ASSERT_TRUE((bool)runtime);
+    CommonAPI::DBus::DBusRuntime* dbusRuntime = dynamic_cast<CommonAPI::DBus::DBusRuntime*>(&(*runtime));
+    ASSERT_TRUE(dbusRuntime != NULL);
+
+    std::shared_ptr<CommonAPI::Factory> proxyFactory = runtime->createFactory();
+    ASSERT_TRUE((bool)proxyFactory);
+    CommonAPI::DBus::DBusFactory* dbusProxyFactory = dynamic_cast<CommonAPI::DBus::DBusFactory*>(&(*proxyFactory));
+    ASSERT_TRUE(dbusProxyFactory != NULL);
+}
+
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/CommonAPI-DBus/src/test/DBusSerializableStructTest.cpp b/CommonAPI-DBus/src/test/DBusSerializableStructTest.cpp
new file mode 100644 (file)
index 0000000..21a41dc
--- /dev/null
@@ -0,0 +1,77 @@
+/* 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 <iostream>
+
+#include <common-api-dbus/dbus-message.h>
+
+#include "TestDBusSerializableStruct.h"
+
+
+#define COMMON_API_TEST_TEST_STRUCT_SIGNATURE                                  "(ud)"
+#define COMMON_API_TEST_TEST_STRUCT_ARRAY_SIGNATURE                            "a" COMMON_API_TEST_TEST_STRUCT_SIGNATURE
+
+#define COMMON_API_TEST_TEST_STRUCT_EXTENDED_SIGNATURE                 "(uds)"
+#define COMMON_API_TEST_TEST_STRUCT_EXTENDED_ARRAY_SIGNATURE   "a" COMMON_API_TEST_TEST_STRUCT_EXTENDED_SIGNATURE
+
+
+namespace common {
+namespace api {
+namespace test {
+
+
+TestStruct::TestStruct(const uint32_t& fromIntValue, const double& fromDoubleValue):
+               intValue(fromIntValue),
+               doubleValue(fromDoubleValue) {
+}
+
+common::api::dbus::DBusInputMessageStream& TestStruct::readFromDBusInputMessageStream(
+               common::api::dbus::DBusInputMessageStream& inputMessageStream) {
+       return inputMessageStream >> intValue
+                                                         >> doubleValue;
+}
+
+common::api::dbus::DBusOutputMessageStream& TestStruct::writeToDBusOutputMessageStream(
+               common::api::dbus::DBusOutputMessageStream& outputMessageStream) const {
+       return outputMessageStream << intValue
+                                                          << doubleValue;
+}
+
+
+TestStructExtended::TestStructExtended(const uint32_t& fromIntValue, const double& fromDoubleValue, const std::string& fromStringValue):
+               TestStruct(fromIntValue, fromDoubleValue),
+               stringValue(fromStringValue) {
+}
+
+common::api::dbus::DBusInputMessageStream& TestStructExtended::readFromDBusInputMessageStream(
+               common::api::dbus::DBusInputMessageStream& inputMessageStream) {
+  return TestStruct::readFromDBusInputMessageStream(inputMessageStream) >> stringValue;
+}
+
+common::api::dbus::DBusOutputMessageStream& TestStructExtended::writeToDBusOutputMessageStream(
+               common::api::dbus::DBusOutputMessageStream& outputMessageStream) const {
+  return TestStruct::writeToDBusOutputMessageStream(outputMessageStream) << stringValue;
+}
+
+} //namespace test
+} //namespace api
+} //namespace common
+
+
+int main(void) {
+       using namespace common::api::test;
+
+       TestStructExtended testStructExtended(123, 456.789, "TestStructExtended");
+
+       common::api::dbus::DBusMessage message = common::api::dbus::DBusMessage::createMethodCall(
+                       "com.bmw.test.TestStruct",
+                       "/com/bmw/test/TestStruct",
+                       "com.bmw.test.TestStruct",
+                       "SingleTestStruct",
+                       COMMON_API_TEST_TEST_STRUCT_EXTENDED_SIGNATURE);
+
+       common::api::dbus::DBusOutputMessageStream outStream(message);
+       outStream << testStructExtended;
+       outStream.flush();
+}
diff --git a/CommonAPI-DBus/src/test/DBusSerializableStructTest.h b/CommonAPI-DBus/src/test/DBusSerializableStructTest.h
new file mode 100644 (file)
index 0000000..63b7233
--- /dev/null
@@ -0,0 +1,66 @@
+/* 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 DEMO_POSITIONING_H_
+#define DEMO_POSITIONING_H_
+
+
+#include <common-api-dbus/dbus-serializable-struct.h>
+#include <vector>
+
+
+namespace common {
+namespace api {
+namespace test {
+
+
+struct TestStruct: public common::api::dbus::SerializableStruct {
+       TestStruct() = default;
+       TestStruct(const uint32_t& fromIntValue, const double& fromDoubleValue);
+
+       virtual common::api::dbus::DBusInputMessageStream& readFromDBusInputMessageStream(
+                       common::api::dbus::DBusInputMessageStream& inputMessageStream);
+
+       virtual common::api::dbus::DBusOutputMessageStream& writeToDBusOutputMessageStream(
+                       common::api::dbus::DBusOutputMessageStream& outputMessageStream) const;
+
+       uint32_t intValue;
+       double doubleValue;
+};
+
+
+struct TestStructExtended: public TestStruct {
+       TestStructExtended() = default;
+
+       TestStructExtended(const uint32_t& fromIntValue, const double& fromDoubleValue, const std::string& fromStringValue);
+
+       virtual common::api::dbus::DBusInputMessageStream& readFromDBusInputMessageStream(
+                       common::api::dbus::DBusInputMessageStream& inputMessageStream);
+
+       virtual common::api::dbus::DBusOutputMessageStream& writeToDBusOutputMessageStream(
+                       common::api::dbus::DBusOutputMessageStream& outputMessageStream) const;
+
+       std::string stringValue;
+};
+
+
+typedef std::vector<TestStruct> TestStructArray;
+typedef std::vector<TestStructExtended> TestStructExtendedArray;
+
+
+} //namespace test
+
+namespace dbus {
+
+template<>
+struct Alignment<common::api::test::TestStruct>: SizeConstant<8> { };
+
+template<>
+struct Alignment<common::api::test::TestStructExtended>: SizeConstant<8> { };
+
+} //namespace dbus
+} //namespace api
+} //namespace common
+
+#endif /* DEMO_POSITIONING_H_ */
diff --git a/CommonAPI-DBus/src/test/DBusServiceRegistryTest.cpp b/CommonAPI-DBus/src/test/DBusServiceRegistryTest.cpp
new file mode 100644 (file)
index 0000000..f709631
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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 <CommonAPI/Runtime.h>
+
+
+//#define      ASSERT_DBUSMESSAGE_EQ(_dbusMessage1, _dbusMessage2) \
+//                     ASSERT_FALSE(_dbusMessage1.getSignatureString() == NULL); \
+//                     ASSERT_FALSE(_dbusMessage2.getSignatureString() == NULL); \
+//                     ASSERT_STREQ(_dbusMessage1.getSignatureString(), _dbusMessage2.getSignatureString()); \
+//                     ASSERT_EQ(_dbusMessage1.getBodyLength(), _dbusMessage2.getBodyLength()); \
+//                     ASSERT_FALSE(_dbusMessage1.getBodyData() == NULL); \
+//                     ASSERT_FALSE(_dbusMessage2.getBodyData() == NULL); \
+//                     ASSERT_EQ(memcmp(_dbusMessage1.getBodyData(), _dbusMessage2.getBodyData(), _dbusMessage1.getBodyLength()), 0)
+//
+//
+//namespace {
+//
+//class DBusConnectionTest: public ::testing::Test {
+// protected:
+//     virtual void SetUp() {
+//     }
+//
+//     virtual void TearDown() {
+//     }
+//};
+//
+//
+//TEST_F(DBusConnectionTest, CanBeConstructed) {
+//    std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::load("");
+//    std::shared_ptr<CommonAPI::ProxyFactory> proxyFactory_ = runtime->createProxyFactory();
+//}
+//
+//}
+
+
+int main() {
+
+}
diff --git a/CommonAPI-DBus/src/test/DBusStubAdapterTest.cpp b/CommonAPI-DBus/src/test/DBusStubAdapterTest.cpp
new file mode 100644 (file)
index 0000000..20abe1d
--- /dev/null
@@ -0,0 +1,221 @@
+/* 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 <CommonAPI/DBus/DBusFunctionalHash.h>
+#include <CommonAPI/DBus/DBusStubAdapterHelper.h>
+
+#include <cassert>
+#include <iostream>
+#include <tuple>
+
+static uint32_t dispatchedMessageCount;
+
+class TestStubRemoteEventHandler {
+ public:
+    virtual ~TestStubRemoteEventHandler() { }
+
+    virtual bool onRemoteSetTestAttribute(int32_t testValue) = 0;
+
+    virtual void onRemoteTestAttributeChanged() = 0;
+};
+
+class TestStubAdapter: virtual public CommonAPI::StubAdapter {
+ public:
+    virtual void fireTestAttributeChanged(const int32_t& testValue)  = 0;
+};
+
+class TestStub: public CommonAPI::Stub<TestStubAdapter, TestStubRemoteEventHandler> {
+ public:
+    TestStub(): remoteEventHandler_(this) {
+    }
+
+    virtual TestStubRemoteEventHandler* initStubAdapter(const std::shared_ptr<TestStubAdapter>& stubAdapter) {
+        return &remoteEventHandler_;
+    }
+
+    void getEmptyResponse() {
+        std::cout << "onGetEmptyResponse()\n";
+        dispatchedMessageCount++;
+    }
+
+    void getDeepCopy(int32_t inValue, int32_t& outValue) {
+        outValue = inValue;
+        std::cout << "getDeepCopy(inValue=" << inValue << ", outValue=" << outValue << ")\n";
+        dispatchedMessageCount++;
+    }
+
+    void getDeepCopies(std::vector<int32_t> inValues, std::vector<int32_t>& outValues) {
+        outValues = inValues;
+        std::cout << "getDeepCopies(inValues=" << inValues.size() << ", outValues=" << outValues.size() << ")\n";
+        dispatchedMessageCount++;
+    }
+
+    void getShallowCopy(int32_t inValue, int32_t& outValue) {
+        outValue = inValue;
+        std::cout << "getShallowCopy(inValue=" << inValue << ", outValue=" << outValue << ")\n";
+        dispatchedMessageCount++;
+    }
+
+    void getShallowCopies(std::vector<int32_t> inValues, std::vector<int32_t>& outValues) {
+        outValues = inValues;
+        std::cout << "getShallowCopies(inValues=" << inValues.size() << ", outValues=" << outValues.size() << ")\n";
+        dispatchedMessageCount++;
+    }
+
+    const int32_t& getTestAttribute() {
+        return testAttributeValue_;
+    }
+
+ private:
+    class RemoteEventHandler: public TestStubRemoteEventHandler {
+     public:
+        RemoteEventHandler(TestStub* stub): stub_(stub) {
+        }
+
+        virtual bool onRemoteSetTestAttribute(int32_t testValue) {
+            std::cout << "RemoteEventHandler::onRemoteSetTestAttribute(" << testValue << "): oldValue = " << stub_->testAttributeValue_ << "\n";
+            const bool valueChanged = (stub_->testAttributeValue_ != testValue);
+            stub_->testAttributeValue_ = testValue;
+            return valueChanged;
+        }
+
+        virtual void onRemoteTestAttributeChanged() {
+            std::cout << "RemoteEventHandler::onRemoteTestAttributeChanged()\n";
+        }
+
+     private:
+        TestStub* stub_;
+    };
+
+    RemoteEventHandler remoteEventHandler_;
+    int32_t testAttributeValue_;
+};
+
+typedef CommonAPI::DBus::DBusStubAdapterHelper<TestStub> TestStubAdapterHelper;
+
+class TestDBusStubAdapter: public TestStubAdapter,  public TestStubAdapterHelper {
+ public:
+    TestDBusStubAdapter(const std::string& dbusBusName,
+                    const std::string& dbusObjectPath,
+                    const std::shared_ptr<CommonAPI::DBus::DBusConnection>& dbusConnection,
+                    const std::shared_ptr<TestStub>& testStub) :
+                    TestStubAdapterHelper(
+                                    dbusBusName,
+                                    dbusObjectPath,
+                                    "org.genivi.CommonAPI.DBus.TestInterface",
+                                    dbusConnection,
+                                    testStub) {
+    }
+
+    virtual void fireTestAttributeChanged(const int32_t& testValue) {
+        std::cout << "TestDBusStubAdapter::fireTestAttributeChanged(" << testValue << ")\n";
+    }
+
+ protected:
+    virtual const char* getMethodsDBusIntrospectionXmlData() const;
+};
+
+const char* TestDBusStubAdapter::getMethodsDBusIntrospectionXmlData() const {
+    return "<method name=\"GetEmptyResponse\">\n"
+           "</method>\n"
+           "<method name=\"GetDeepCopy\">\n"
+                    "<arg type=\"i\" name=\"int32InValue\" direction=\"in\"/>\n"
+                    "<arg type=\"i\" name=\"int32OutValue\" direction=\"out\"/>\n"
+           "</method>\n"
+           "<method name=\"GetDeepCopies\">\n"
+                    "<arg type=\"ai\" name=\"int32InValues\" direction=\"in\"/>\n"
+                    "<arg type=\"ai\" name=\"int32OutValues\" direction=\"out\"/>\n"
+           "</method>\n"
+           "<method name=\"GetShallowCopy\">\n"
+                    "<arg type=\"i\" name=\"int32InValue\" direction=\"in\"/>\n"
+                    "<arg type=\"i\" name=\"int32OutValue\" direction=\"out\"/>\n"
+           "</method>\n"
+           "<method name=\"GetShallowCopies\">\n"
+                    "<arg type=\"ai\" name=\"int32InValues\" direction=\"in\"/>\n"
+                    "<arg type=\"ai\" name=\"int32OutValues\" direction=\"out\"/>\n"
+           "</method>"
+           "<method name=\"SetTestAttribute\">\n"
+                    "<arg type=\"i\" name=\"value\" direction=\"in\"/>\n"
+                    "<arg type=\"i\" name=\"value\" direction=\"out\"/>\n"
+           "</method>"
+           ;
+}
+
+namespace {
+static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
+                    TestStub,
+                    std::tuple<>,
+                    std::tuple<> > getEmptyResponseStubDispatcher(&TestStub::getEmptyResponse, "");
+static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
+                    TestStub,
+                    std::tuple<int32_t>,
+                    std::tuple<int32_t> > getDeepCopyStubDispatcher(&TestStub::getDeepCopy, "i");
+static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
+                    TestStub,
+                    std::tuple<std::vector<int32_t>>,
+                    std::tuple<std::vector<int32_t>> > getDeepCopiesStubDispatcher(&TestStub::getDeepCopies, "ai");
+static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
+                    TestStub,
+                    std::tuple<int32_t>,
+                    std::tuple<int32_t> > getShallowCopyStubDispatcher(&TestStub::getShallowCopy, "i");
+static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
+                    TestStub,
+                    std::tuple<std::vector<int32_t>>,
+                    std::tuple<std::vector<int32_t>> > getShallowCopiesStubDispatcher(&TestStub::getShallowCopies, "ai");
+static CommonAPI::DBus::DBusSetObservableAttributeStubDispatcher<TestStub, int32_t> setTestAttributeStubDispatcher(
+                                    &TestStub::getTestAttribute,
+                                    &TestStubRemoteEventHandler::onRemoteSetTestAttribute,
+                                    &TestStubRemoteEventHandler::onRemoteTestAttributeChanged,
+                                    &TestStubAdapter::fireTestAttributeChanged,
+                                    "i");
+}
+
+template<>
+const TestStubAdapterHelper::StubDispatcherTable TestStubAdapterHelper::stubDispatcherTable_ = {
+     { {"GetEmptyResponse", ""}, &getEmptyResponseStubDispatcher },
+     { {"GetDeepCopy", "i"}, &getDeepCopyStubDispatcher },
+     { {"GetDeepCopies", "ai"}, &getDeepCopiesStubDispatcher },
+     { {"GetShallowCopy", "i"}, &getShallowCopyStubDispatcher },
+     { {"GetShallowCopies", "ai"}, &getShallowCopiesStubDispatcher },
+     { {"SetTestAttribute", "i"}, &setTestAttributeStubDispatcher }
+};
+
+int main(void) {
+    auto dbusConnection = CommonAPI::DBus::DBusConnection::getSessionBus();
+
+    if (!dbusConnection->isConnected())
+        dbusConnection->connect();
+
+    assert(dbusConnection->isConnected());
+
+    const bool serviceNameAcquired = dbusConnection->requestServiceNameAndBlock(
+                    "org.genivi.CommonAPI.DBus.TestDBusInterfaceAdapter");
+    assert(serviceNameAcquired);
+
+    auto testStub = std::make_shared<TestStub>();
+    auto testStubAdapter = std::make_shared<TestDBusStubAdapter>(
+                    "org.genivi.CommonAPI.DBus.TestDBusInterfaceAdapter",
+                    "/common/api/dbus/TestDBusInterfaceAdapter",
+                    dbusConnection,
+                    testStub);
+    testStubAdapter->init();
+
+    auto dbusMessageCall = CommonAPI::DBus::DBusMessage::createMethodCall(
+                    "org.genivi.CommonAPI.DBus.TestDBusInterfaceAdapter",
+                    testStubAdapter->getObjectPath().c_str(),
+                    testStubAdapter->getServiceId().c_str(),
+                    "GetEmptyResponse");
+
+    const bool messageSent = dbusConnection->sendDBusMessage(dbusMessageCall);
+    assert(messageSent);
+
+    for (int i = 0; i < 10; i++)
+        dbusConnection->readWriteDispatch(100);
+
+//    while (dbusConnection->readWriteDispatch(100))
+//        ;
+
+    assert(dispatchedMessageCount > 0);
+
+    return 0;
+}
diff --git a/CommonAPI-DBus/src/test/DBusVariantTest.cpp b/CommonAPI-DBus/src/test/DBusVariantTest.cpp
new file mode 100644 (file)
index 0000000..7928b16
--- /dev/null
@@ -0,0 +1,98 @@
+/* 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 <iostream>
+#include <string>
+#include <tuple>
+#include <type_traits>
+
+template <typename _SearchType, typename _CurrentType, typename... _RestTypes>
+struct VariantTypeSelector: VariantTypeSelector<_SearchType, _RestTypes...> {
+};
+
+template <typename _SearchType, typename... _RestTypes>
+struct VariantTypeSelector<_SearchType, _SearchType, _RestTypes...> {
+    typedef _SearchType type;
+};
+
+template <typename... _Types>
+class Variant {
+ private:
+    typedef std::tuple_size<std::tuple<_Types...>> TypesTupleSize;
+
+ public:
+    Variant(): valueType_(TypesTupleSize::value) {
+    }
+
+    Variant(const Variant& fromVariant):
+        valueType_(fromVariant.valueType_),
+        valueStorage_(fromVariant.valueStorage_) {
+    }
+
+    Variant(Variant&& fromVariant):
+        valueType_(std::move(fromVariant.valueType_)),
+        valueStorage_(std::move(fromVariant.valueStorage_)) {
+        fromVariant.valueType_ = TypesTupleSize::value;
+    }
+
+    ~Variant() {
+        if (hasValue()) {
+            // TODO call value destructor
+        }
+    }
+
+    Variant& operator=(const Variant& fromVariant) {
+        // TODO
+        return *this;
+    }
+
+    Variant& operator=(Variant&& fromVariant) {
+        // TODO
+        return *this;
+    }
+
+    // TODO use std::enable_if
+    template <typename _Type>
+    Variant(const _Type& value) {
+        // TODO index by type
+        valueType_ = 0;
+        new (&valueStorage_) _Type(value);
+    }
+
+    // TODO use std::enable_if
+    template <typename _Type>
+    Variant(_Type && value) {
+        // TODO index by type
+        valueType_ = 0;
+        new (&valueStorage_) typename std::remove_reference<_Type>::type(std::move(value));
+    }
+
+    template <typename _Type>
+    const typename VariantTypeSelector<_Type, _Types...>::type & get(bool& success) const {
+        // TODO assert _Type in _Types
+        success = true;
+        return *(reinterpret_cast<const _Type *>(&valueStorage_));
+    }
+
+ private:
+    inline bool hasValue() const {
+        return valueType_ < TypesTupleSize::value;
+    }
+
+    size_t valueType_;
+    // TODO calculate maximum storage
+    std::aligned_storage<80>::type valueStorage_;
+};
+
+
+
+int main(int argc, char** argv) {
+    int fromInt = 5;
+    Variant<int, double, double, std::string> myVariant(fromInt);
+    bool success;
+    const int& myInt = myVariant.get<int>(success);
+//    const float& myFloat = myVariant.get<float>(success);
+
+    std::cout << "myInt = " << myInt << " (" << std::boolalpha << success << ")\n";
+    return 0;
+}
diff --git a/CommonAPI-DBus/src/test/commonapi/tests/DerivedTypeCollection.cpp b/CommonAPI-DBus/src/test/commonapi/tests/DerivedTypeCollection.cpp
new file mode 100644 (file)
index 0000000..9087e4d
--- /dev/null
@@ -0,0 +1,63 @@
+/* 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 "DerivedTypeCollection.h"
+
+namespace commonapi {
+namespace tests {
+namespace DerivedTypeCollection {
+
+TestStruct::TestStruct(const PredefinedTypeCollection::TestString& testStringValue, const uint16_t& uintValueValue):
+        testString(testStringValue),
+        uintValue(uintValueValue)
+{
+}
+
+bool operator==(const TestStruct& lhs, const TestStruct& rhs) {
+    if (&lhs == &rhs)
+        return true;
+
+    return
+        lhs.testString == rhs.testString &&
+        lhs.uintValue == rhs.uintValue
+    ;
+}
+
+void TestStruct::readFromInputStream(CommonAPI::InputStream& inputStream) {
+    inputStream >> testString;
+    inputStream >> uintValue;
+}
+
+void TestStruct::writeToOutputStream(CommonAPI::OutputStream& outputStream) const {
+    outputStream << testString;
+    outputStream << uintValue;
+}
+TestStructExtended::TestStructExtended(const PredefinedTypeCollection::TestString& testStringValue, const uint16_t& uintValueValue, const TestEnumExtended2& testEnumExtended2Value):
+        TestStruct(testStringValue, uintValueValue),
+        testEnumExtended2(testEnumExtended2Value)
+{
+}
+
+bool operator==(const TestStructExtended& lhs, const TestStructExtended& rhs) {
+    if (&lhs == &rhs)
+        return true;
+
+    return
+        static_cast<TestStructExtended::TestStruct>(lhs) == static_cast<TestStructExtended::TestStruct>(rhs) &&
+        lhs.testEnumExtended2 == rhs.testEnumExtended2
+    ;
+}
+
+void TestStructExtended::readFromInputStream(CommonAPI::InputStream& inputStream) {
+    TestStruct::readFromInputStream(inputStream);
+    inputStream >> testEnumExtended2;
+}
+
+void TestStructExtended::writeToOutputStream(CommonAPI::OutputStream& outputStream) const {
+    TestStruct::writeToOutputStream(outputStream);
+    outputStream << testEnumExtended2;
+}
+
+} // namespace DerivedTypeCollection
+} // namespace tests
+} // namespace commonapi
diff --git a/CommonAPI-DBus/src/test/commonapi/tests/DerivedTypeCollection.h b/CommonAPI-DBus/src/test/commonapi/tests/DerivedTypeCollection.h
new file mode 100644 (file)
index 0000000..40d4287
--- /dev/null
@@ -0,0 +1,208 @@
+/* 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_TESTS_DERIVED_TYPE_COLLECTION_H_
+#define COMMONAPI_TESTS_DERIVED_TYPE_COLLECTION_H_
+
+#include <CommonAPI/InputStream.h>
+#include <CommonAPI/OutputStream.h>
+#include <CommonAPI/SerializableStruct.h>
+#include <CommonAPI/types.h>
+#include "PredefinedTypeCollection.h"
+#include <cstdint>
+#include <unordered_map>
+#include <vector>
+
+namespace commonapi {
+namespace tests {
+
+namespace DerivedTypeCollection {
+
+enum class TestEnum: int32_t {
+    E_UNKNOWN = 0,
+    E_OK = 1,
+    E_OUT_OF_RANGE = 2,
+    E_NOT_USED = 3
+};
+
+// XXX Definition of a comparator still is necessary for GCC 4.4.1, topic is fixed since 4.5.1
+struct TestEnumComparator;
+
+enum class TestEnumMissingValue: int32_t {
+    E1 = 10,
+    E2,
+    E3 = 2
+};
+
+// XXX Definition of a comparator still is necessary for GCC 4.4.1, topic is fixed since 4.5.1
+struct TestEnumMissingValueComparator;
+
+enum class TestEnumExtended: int32_t {
+    E_UNKNOWN = TestEnum::E_UNKNOWN,
+    E_OK = TestEnum::E_OK,
+    E_OUT_OF_RANGE = TestEnum::E_OUT_OF_RANGE,
+    E_NOT_USED = TestEnum::E_NOT_USED
+    ,
+    E_NEW = 4
+};
+
+// XXX Definition of a comparator still is necessary for GCC 4.4.1, topic is fixed since 4.5.1
+struct TestEnumExtendedComparator;
+
+enum class TestEnumExtended2: int32_t {
+    E_UNKNOWN = TestEnum::E_UNKNOWN,
+    E_OK = TestEnum::E_OK,
+    E_OUT_OF_RANGE = TestEnum::E_OUT_OF_RANGE,
+    E_NOT_USED = TestEnum::E_NOT_USED,
+    
+    E_NEW = TestEnumExtended::E_NEW
+    ,
+    E_NEW2 = 5
+};
+
+// XXX Definition of a comparator still is necessary for GCC 4.4.1, topic is fixed since 4.5.1
+struct TestEnumExtended2Comparator;
+
+struct TestStruct: CommonAPI::SerializableStruct {
+    PredefinedTypeCollection::TestString testString;
+    uint16_t uintValue;
+    
+    TestStruct() = default;
+    TestStruct(const PredefinedTypeCollection::TestString& testString, const uint16_t& uintValue);
+
+    virtual void readFromInputStream(CommonAPI::InputStream& inputStream);
+    virtual void writeToOutputStream(CommonAPI::OutputStream& outputStream) const;
+};
+
+struct TestStructExtended: TestStruct {
+    TestEnumExtended2 testEnumExtended2;
+    
+    TestStructExtended() = default;
+    TestStructExtended(const PredefinedTypeCollection::TestString& testString, const uint16_t& uintValue, const TestEnumExtended2& testEnumExtended2);
+
+    virtual void readFromInputStream(CommonAPI::InputStream& inputStream);
+    virtual void writeToOutputStream(CommonAPI::OutputStream& outputStream) const;
+};
+
+typedef std::vector<uint64_t> TestArrayUInt64;
+
+typedef std::vector<TestStruct> TestArrayTestStruct;
+
+typedef std::unordered_map<uint32_t, TestArrayTestStruct> TestMap;
+
+inline CommonAPI::InputStream& operator>>(CommonAPI::InputStream& inputStream, TestEnum& enumValue) {
+    return inputStream.readEnumValue<int32_t>(enumValue);
+}
+
+inline CommonAPI::OutputStream& operator<<(CommonAPI::OutputStream& outputStream, const TestEnum& enumValue) {
+    return outputStream.writeEnumValue(static_cast<int32_t>(enumValue));
+}
+
+struct TestEnumComparator {
+    inline bool operator()(const TestEnum& lhs, const TestEnum& rhs) const {
+        return static_cast<int32_t>(lhs) < static_cast<int32_t>(rhs);
+    }
+};
+
+inline CommonAPI::InputStream& operator>>(CommonAPI::InputStream& inputStream, TestEnumMissingValue& enumValue) {
+    return inputStream.readEnumValue<int32_t>(enumValue);
+}
+
+inline CommonAPI::OutputStream& operator<<(CommonAPI::OutputStream& outputStream, const TestEnumMissingValue& enumValue) {
+    return outputStream.writeEnumValue(static_cast<int32_t>(enumValue));
+}
+
+struct TestEnumMissingValueComparator {
+    inline bool operator()(const TestEnumMissingValue& lhs, const TestEnumMissingValue& rhs) const {
+        return static_cast<int32_t>(lhs) < static_cast<int32_t>(rhs);
+    }
+};
+
+inline CommonAPI::InputStream& operator>>(CommonAPI::InputStream& inputStream, TestEnumExtended& enumValue) {
+    return inputStream.readEnumValue<int32_t>(enumValue);
+}
+
+inline CommonAPI::OutputStream& operator<<(CommonAPI::OutputStream& outputStream, const TestEnumExtended& enumValue) {
+    return outputStream.writeEnumValue(static_cast<int32_t>(enumValue));
+}
+
+struct TestEnumExtendedComparator {
+    inline bool operator()(const TestEnumExtended& lhs, const TestEnumExtended& rhs) const {
+        return static_cast<int32_t>(lhs) < static_cast<int32_t>(rhs);
+    }
+};
+
+
+inline bool operator==(const TestEnumExtended& lhs, const TestEnum& rhs) {
+    return static_cast<int32_t>(lhs) == static_cast<int32_t>(rhs);
+}
+inline bool operator==(const TestEnum& lhs, const TestEnumExtended& rhs) {
+    return static_cast<int32_t>(lhs) == static_cast<int32_t>(rhs);
+}
+inline bool operator!=(const TestEnumExtended& lhs, const TestEnum& rhs) {
+    return static_cast<int32_t>(lhs) != static_cast<int32_t>(rhs);
+}
+inline bool operator!=(const TestEnum& lhs, const TestEnumExtended& rhs) {
+    return static_cast<int32_t>(lhs) != static_cast<int32_t>(rhs);
+}
+inline CommonAPI::InputStream& operator>>(CommonAPI::InputStream& inputStream, TestEnumExtended2& enumValue) {
+    return inputStream.readEnumValue<int32_t>(enumValue);
+}
+
+inline CommonAPI::OutputStream& operator<<(CommonAPI::OutputStream& outputStream, const TestEnumExtended2& enumValue) {
+    return outputStream.writeEnumValue(static_cast<int32_t>(enumValue));
+}
+
+struct TestEnumExtended2Comparator {
+    inline bool operator()(const TestEnumExtended2& lhs, const TestEnumExtended2& rhs) const {
+        return static_cast<int32_t>(lhs) < static_cast<int32_t>(rhs);
+    }
+};
+
+
+inline bool operator==(const TestEnumExtended2& lhs, const TestEnum& rhs) {
+    return static_cast<int32_t>(lhs) == static_cast<int32_t>(rhs);
+}
+inline bool operator==(const TestEnum& lhs, const TestEnumExtended2& rhs) {
+    return static_cast<int32_t>(lhs) == static_cast<int32_t>(rhs);
+}
+inline bool operator!=(const TestEnumExtended2& lhs, const TestEnum& rhs) {
+    return static_cast<int32_t>(lhs) != static_cast<int32_t>(rhs);
+}
+inline bool operator!=(const TestEnum& lhs, const TestEnumExtended2& rhs) {
+    return static_cast<int32_t>(lhs) != static_cast<int32_t>(rhs);
+}
+
+inline bool operator==(const TestEnumExtended2& lhs, const TestEnumExtended& rhs) {
+    return static_cast<int32_t>(lhs) == static_cast<int32_t>(rhs);
+}
+inline bool operator==(const TestEnumExtended& lhs, const TestEnumExtended2& rhs) {
+    return static_cast<int32_t>(lhs) == static_cast<int32_t>(rhs);
+}
+inline bool operator!=(const TestEnumExtended2& lhs, const TestEnumExtended& rhs) {
+    return static_cast<int32_t>(lhs) != static_cast<int32_t>(rhs);
+}
+inline bool operator!=(const TestEnumExtended& lhs, const TestEnumExtended2& rhs) {
+    return static_cast<int32_t>(lhs) != static_cast<int32_t>(rhs);
+}
+bool operator==(const TestStruct& lhs, const TestStruct& rhs);
+inline bool operator!=(const TestStruct& lhs, const TestStruct& rhs) {
+    return !(lhs == rhs);
+}
+bool operator==(const TestStructExtended& lhs, const TestStructExtended& rhs);
+inline bool operator!=(const TestStructExtended& lhs, const TestStructExtended& rhs) {
+    return !(lhs == rhs);
+}
+
+
+static inline const char* getTypeCollectionName() {
+    return "commonapi.tests.DerivedTypeCollection";
+}
+
+
+} // namespace DerivedTypeCollection
+
+} // namespace tests
+} // namespace commonapi
+
+#endif // COMMONAPI_TESTS_DERIVED_TYPE_COLLECTION_H_
diff --git a/CommonAPI-DBus/src/test/commonapi/tests/PredefinedTypeCollection.h b/CommonAPI-DBus/src/test/commonapi/tests/PredefinedTypeCollection.h
new file mode 100644 (file)
index 0000000..8b6493c
--- /dev/null
@@ -0,0 +1,55 @@
+/* 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_TESTS_PREDEFINED_TYPE_COLLECTION_H_
+#define COMMONAPI_TESTS_PREDEFINED_TYPE_COLLECTION_H_
+
+#include <CommonAPI/ByteBuffer.h>
+#include <CommonAPI/types.h>
+#include <cstdint>
+#include <string>
+
+namespace commonapi {
+namespace tests {
+
+namespace PredefinedTypeCollection {
+
+typedef uint8_t TestUInt8;
+
+typedef uint16_t TestUInt16;
+
+typedef uint32_t TestUInt32;
+
+typedef uint64_t TestUInt64;
+
+typedef int8_t TestInt8;
+
+typedef int16_t TestInt16;
+
+typedef int32_t TestInt32;
+
+typedef int64_t TestInt64;
+
+typedef bool TestBoolean;
+
+typedef CommonAPI::ByteBuffer TestByteBuffer;
+
+typedef double TestDouble;
+
+typedef float TestFloat;
+
+typedef std::string TestString;
+
+
+
+static inline const char* getTypeCollectionName() {
+    return "commonapi.tests.PredefinedTypeCollection";
+}
+
+
+} // namespace PredefinedTypeCollection
+
+} // namespace tests
+} // namespace commonapi
+
+#endif // COMMONAPI_TESTS_PREDEFINED_TYPE_COLLECTION_H_
diff --git a/CommonAPI-DBus/src/test/commonapi/tests/TestInterface.h b/CommonAPI-DBus/src/test/commonapi/tests/TestInterface.h
new file mode 100644 (file)
index 0000000..2252237
--- /dev/null
@@ -0,0 +1,32 @@
+/* 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_TESTS_TEST_INTERFACE_H_
+#define COMMONAPI_TESTS_TEST_INTERFACE_H_
+
+#include <CommonAPI/types.h>
+
+namespace commonapi {
+namespace tests {
+
+class TestInterface {
+ public:
+    virtual ~TestInterface() { }
+
+    static inline const char* getInterfaceName();
+    static inline CommonAPI::Version getInterfaceVersion();
+};
+
+const char* TestInterface::getInterfaceName() {
+    return "commonapi.tests.TestInterface";
+}
+
+CommonAPI::Version TestInterface::getInterfaceVersion() {
+    return CommonAPI::Version(1, 0);
+}
+
+
+} // namespace tests
+} // namespace commonapi
+
+#endif // COMMONAPI_TESTS_TEST_INTERFACE_H_
diff --git a/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceDBusProxy.cpp b/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceDBusProxy.cpp
new file mode 100644 (file)
index 0000000..46bedeb
--- /dev/null
@@ -0,0 +1,126 @@
+/* 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 "TestInterfaceDBusProxy.h"
+
+namespace commonapi {
+namespace tests {
+
+std::shared_ptr<CommonAPI::DBus::DBusProxy> createTestInterfaceDBusProxy(const char* busName,
+                                       const char* objectPath,
+                                       std::shared_ptr<CommonAPI::DBus::DBusProxyConnection> dbusProxyConnection) {
+    return std::make_shared<TestInterfaceDBusProxy>(busName, objectPath, dbusProxyConnection);
+}
+
+__attribute__((constructor)) void registerTestInterfaceDBusProxy(void) {
+    CommonAPI::DBus::DBusFactory::registerProxyFactoryMethod(TestInterface::getInterfaceName(),
+       &createTestInterfaceDBusProxy);
+}
+
+TestInterfaceDBusProxy::TestInterfaceDBusProxy(const std::string& busName, const std::string& objectPath, const std::shared_ptr<CommonAPI::DBus::DBusProxyConnection>& dbusProxyconnection):
+        CommonAPI::DBus::DBusProxy(busName, objectPath, TestInterface::getInterfaceName(), dbusProxyconnection)
+,        testPredefinedTypeAttribute_(*this, "onTestPredefinedTypeAttributeAttributeChanged", "setTestPredefinedTypeAttributeAttribute", "u", "getTestPredefinedTypeAttributeAttribute"),
+        testDerivedStructAttribute_(*this, "onTestDerivedStructAttributeAttributeChanged", "setTestDerivedStructAttributeAttribute", "(sqi)", "getTestDerivedStructAttributeAttribute"),
+        testDerivedArrayAttribute_(*this, "onTestDerivedArrayAttributeAttributeChanged", "setTestDerivedArrayAttributeAttribute", "at", "getTestDerivedArrayAttributeAttribute")
+,        testPredefinedTypeBroadcast_(*this, "TestPredefinedTypeBroadcast", "us")
+                 {
+}
+
+TestInterfaceDBusProxy::TestPredefinedTypeAttributeAttribute& TestInterfaceDBusProxy::getTestPredefinedTypeAttributeAttribute() {
+    return testPredefinedTypeAttribute_;
+}
+TestInterfaceDBusProxy::TestDerivedStructAttributeAttribute& TestInterfaceDBusProxy::getTestDerivedStructAttributeAttribute() {
+    return testDerivedStructAttribute_;
+}
+TestInterfaceDBusProxy::TestDerivedArrayAttributeAttribute& TestInterfaceDBusProxy::getTestDerivedArrayAttributeAttribute() {
+    return testDerivedArrayAttribute_;
+}
+
+TestInterfaceDBusProxy::TestPredefinedTypeBroadcastEvent& TestInterfaceDBusProxy::getTestPredefinedTypeBroadcastEvent() {
+    return testPredefinedTypeBroadcast_;
+}
+
+void TestInterfaceDBusProxy::testVoidPredefinedTypeMethod(const uint32_t& uint32Value, const std::string& stringValue, CommonAPI::CallStatus& callStatus) {
+    CommonAPI::DBus::DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<uint32_t, std::string>,
+                                     CommonAPI::DBus::DBusSerializableArguments<> >::callMethodWithReply(
+        *this,
+        "testVoidPredefinedTypeMethod",
+        "us",
+        uint32Value, stringValue, 
+        callStatus
+        );
+}
+std::future<CommonAPI::CallStatus> TestInterfaceDBusProxy::testVoidPredefinedTypeMethodAsync(const uint32_t& uint32Value, const std::string& stringValue, TestVoidPredefinedTypeMethodAsyncCallback callback) {
+    return CommonAPI::DBus::DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<uint32_t, std::string>,
+                                     CommonAPI::DBus::DBusSerializableArguments<> >::callMethodAsync(
+        *this,
+        "testVoidPredefinedTypeMethod",
+        "us",
+        uint32Value, stringValue, 
+        std::move(callback));
+}
+void TestInterfaceDBusProxy::testPredefinedTypeMethod(const uint32_t& uint32InValue, const std::string& stringInValue, CommonAPI::CallStatus& callStatus, uint32_t& uint32OutValue, std::string& stringOutValue) {
+    CommonAPI::DBus::DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<uint32_t, std::string>,
+                                     CommonAPI::DBus::DBusSerializableArguments<uint32_t, std::string> >::callMethodWithReply(
+        *this,
+        "testPredefinedTypeMethod",
+        "us",
+        uint32InValue, stringInValue, 
+        callStatus
+        , uint32OutValue, stringOutValue);
+}
+std::future<CommonAPI::CallStatus> TestInterfaceDBusProxy::testPredefinedTypeMethodAsync(const uint32_t& uint32InValue, const std::string& stringInValue, TestPredefinedTypeMethodAsyncCallback callback) {
+    return CommonAPI::DBus::DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<uint32_t, std::string>,
+                                     CommonAPI::DBus::DBusSerializableArguments<uint32_t, std::string> >::callMethodAsync(
+        *this,
+        "testPredefinedTypeMethod",
+        "us",
+        uint32InValue, stringInValue, 
+        std::move(callback));
+}
+void TestInterfaceDBusProxy::testVoidDerivedTypeMethod(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2Value, const DerivedTypeCollection::TestMap& testMapValue, CommonAPI::CallStatus& callStatus) {
+    CommonAPI::DBus::DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<DerivedTypeCollection::TestEnumExtended2, DerivedTypeCollection::TestMap>,
+                                     CommonAPI::DBus::DBusSerializableArguments<> >::callMethodWithReply(
+        *this,
+        "testVoidDerivedTypeMethod",
+        "ia{ua(sq)}",
+        testEnumExtended2Value, testMapValue, 
+        callStatus
+        );
+}
+std::future<CommonAPI::CallStatus> TestInterfaceDBusProxy::testVoidDerivedTypeMethodAsync(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2Value, const DerivedTypeCollection::TestMap& testMapValue, TestVoidDerivedTypeMethodAsyncCallback callback) {
+    return CommonAPI::DBus::DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<DerivedTypeCollection::TestEnumExtended2, DerivedTypeCollection::TestMap>,
+                                     CommonAPI::DBus::DBusSerializableArguments<> >::callMethodAsync(
+        *this,
+        "testVoidDerivedTypeMethod",
+        "ia{ua(sq)}",
+        testEnumExtended2Value, testMapValue, 
+        std::move(callback));
+}
+void TestInterfaceDBusProxy::testDerivedTypeMethod(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2InValue, const DerivedTypeCollection::TestMap& testMapInValue, CommonAPI::CallStatus& callStatus, DerivedTypeCollection::TestEnumExtended2& testEnumExtended2OutValue, DerivedTypeCollection::TestMap& testMapOutValue) {
+    CommonAPI::DBus::DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<DerivedTypeCollection::TestEnumExtended2, DerivedTypeCollection::TestMap>,
+                                     CommonAPI::DBus::DBusSerializableArguments<DerivedTypeCollection::TestEnumExtended2, DerivedTypeCollection::TestMap> >::callMethodWithReply(
+        *this,
+        "testDerivedTypeMethod",
+        "ia{ua(sq)}",
+        testEnumExtended2InValue, testMapInValue, 
+        callStatus
+        , testEnumExtended2OutValue, testMapOutValue);
+}
+std::future<CommonAPI::CallStatus> TestInterfaceDBusProxy::testDerivedTypeMethodAsync(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2InValue, const DerivedTypeCollection::TestMap& testMapInValue, TestDerivedTypeMethodAsyncCallback callback) {
+    return CommonAPI::DBus::DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<DerivedTypeCollection::TestEnumExtended2, DerivedTypeCollection::TestMap>,
+                                     CommonAPI::DBus::DBusSerializableArguments<DerivedTypeCollection::TestEnumExtended2, DerivedTypeCollection::TestMap> >::callMethodAsync(
+        *this,
+        "testDerivedTypeMethod",
+        "ia{ua(sq)}",
+        testEnumExtended2InValue, testMapInValue, 
+        std::move(callback));
+}
+
+void TestInterfaceDBusProxy::getOwnVersion(uint16_t& ownVersionMajor, uint16_t& ownVersionMinor) const {
+    ownVersionMajor = 1;
+    ownVersionMinor = 0;
+}
+
+} // namespace tests
+} // namespace commonapi
diff --git a/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceDBusProxy.h b/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceDBusProxy.h
new file mode 100644 (file)
index 0000000..bf0981a
--- /dev/null
@@ -0,0 +1,54 @@
+/* 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_TESTS_TEST_INTERFACE_DBUS_PROXY_H_
+#define COMMONAPI_TESTS_TEST_INTERFACE_DBUS_PROXY_H_
+
+#include "TestInterfaceProxyBase.h"
+#include <CommonAPI/DBus/DBusFactory.h>
+#include <CommonAPI/DBus/DBusProxy.h>
+#include <CommonAPI/DBus/DBusAttribute.h>
+#include <CommonAPI/DBus/DBusEvent.h>
+
+#include <string>
+
+namespace commonapi {
+namespace tests {
+
+class TestInterfaceDBusProxy: virtual public TestInterfaceProxyBase, virtual public CommonAPI::DBus::DBusProxy {
+ public:
+    TestInterfaceDBusProxy(const std::string& busName, const std::string& objectPath, const std::shared_ptr<CommonAPI::DBus::DBusProxyConnection>& dbusProxyconnection);
+
+    virtual TestPredefinedTypeAttributeAttribute& getTestPredefinedTypeAttributeAttribute();
+    virtual TestDerivedStructAttributeAttribute& getTestDerivedStructAttributeAttribute();
+    virtual TestDerivedArrayAttributeAttribute& getTestDerivedArrayAttributeAttribute();
+
+    virtual TestPredefinedTypeBroadcastEvent& getTestPredefinedTypeBroadcastEvent();
+
+
+    virtual void testVoidPredefinedTypeMethod(const uint32_t& uint32Value, const std::string& stringValue, CommonAPI::CallStatus& callStatus);
+    virtual std::future<CommonAPI::CallStatus> testVoidPredefinedTypeMethodAsync(const uint32_t& uint32Value, const std::string& stringValue, TestVoidPredefinedTypeMethodAsyncCallback callback);
+
+    virtual void testPredefinedTypeMethod(const uint32_t& uint32InValue, const std::string& stringInValue, CommonAPI::CallStatus& callStatus, uint32_t& uint32OutValue, std::string& stringOutValue);
+    virtual std::future<CommonAPI::CallStatus> testPredefinedTypeMethodAsync(const uint32_t& uint32InValue, const std::string& stringInValue, TestPredefinedTypeMethodAsyncCallback callback);
+
+    virtual void testVoidDerivedTypeMethod(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2Value, const DerivedTypeCollection::TestMap& testMapValue, CommonAPI::CallStatus& callStatus);
+    virtual std::future<CommonAPI::CallStatus> testVoidDerivedTypeMethodAsync(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2Value, const DerivedTypeCollection::TestMap& testMapValue, TestVoidDerivedTypeMethodAsyncCallback callback);
+
+    virtual void testDerivedTypeMethod(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2InValue, const DerivedTypeCollection::TestMap& testMapInValue, CommonAPI::CallStatus& callStatus, DerivedTypeCollection::TestEnumExtended2& testEnumExtended2OutValue, DerivedTypeCollection::TestMap& testMapOutValue);
+    virtual std::future<CommonAPI::CallStatus> testDerivedTypeMethodAsync(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2InValue, const DerivedTypeCollection::TestMap& testMapInValue, TestDerivedTypeMethodAsyncCallback callback);
+    
+    virtual void getOwnVersion(uint16_t& ownVersionMajor, uint16_t& ownVersionMinor) const;
+
+ private:
+    CommonAPI::DBus::DBusObservableAttribute<CommonAPI::DBus::DBusAttribute<TestPredefinedTypeAttributeAttribute>> testPredefinedTypeAttribute_;
+    CommonAPI::DBus::DBusObservableAttribute<CommonAPI::DBus::DBusAttribute<TestDerivedStructAttributeAttribute>> testDerivedStructAttribute_;
+    CommonAPI::DBus::DBusObservableAttribute<CommonAPI::DBus::DBusAttribute<TestDerivedArrayAttributeAttribute>> testDerivedArrayAttribute_;
+
+    CommonAPI::DBus::DBusEvent<TestPredefinedTypeBroadcastEvent> testPredefinedTypeBroadcast_;
+};
+
+} // namespace tests
+} // namespace commonapi
+
+#endif // COMMONAPI_TESTS_TEST_INTERFACE_DBUS_PROXY_H_
diff --git a/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceDBusStubAdapter.cpp b/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceDBusStubAdapter.cpp
new file mode 100644 (file)
index 0000000..6a9fd96
--- /dev/null
@@ -0,0 +1,216 @@
+/* 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 "TestInterfaceDBusStubAdapter.h"
+#include "TestInterface.h"
+
+namespace commonapi {
+namespace tests {
+
+std::shared_ptr<CommonAPI::DBus::DBusStubAdapter> createTestInterfaceDBusStubAdapter(std::string busName,
+                                                           std::string objectPath,
+                                                           std::shared_ptr<CommonAPI::DBus::DBusProxyConnection> dbusProxyConnection,
+                                                           std::shared_ptr<CommonAPI::StubBase> stubBase) {
+    return std::make_shared<TestInterfaceDBusStubAdapter>(busName, objectPath, dbusProxyConnection, stubBase);
+}
+
+__attribute__((constructor)) void registerTestInterfaceDBusStubAdapter(void) {
+    CommonAPI::DBus::DBusFactory::registerAdapterFactoryMethod(TestInterface::getInterfaceName(),
+                                                               &createTestInterfaceDBusStubAdapter);
+}
+
+TestInterfaceDBusStubAdapter::TestInterfaceDBusStubAdapter(
+        const std::string& dbusBusName,
+        const std::string& dbusObjectPath,
+        const std::shared_ptr<CommonAPI::DBus::DBusProxyConnection>& dbusConnection,
+        const std::shared_ptr<CommonAPI::StubBase>& stub):
+        TestInterfaceDBusStubAdapterHelper(dbusBusName, dbusObjectPath, TestInterface::getInterfaceName(), dbusConnection, std::dynamic_pointer_cast<TestInterfaceStub>(stub)) {
+}
+
+const char* TestInterfaceDBusStubAdapter::getMethodsDBusIntrospectionXmlData() const {
+    return
+        "<method name=\"getTestPredefinedTypeAttributeAttribute\">\n"
+               "<arg name=\"value\" type=\"u\" direction=\"out\" />"
+        "</method>\n"
+        "<method name=\"setTestPredefinedTypeAttributeAttribute\">\n"
+            "<arg name=\"requestedValue\" type=\"u\" direction=\"in\" />\n"
+            "<arg name=\"setValue\" type=\"u\" direction=\"out\" />\n"
+        "</method>\n"
+        "<signal name=\"onTestPredefinedTypeAttributeAttributeChanged\">\n"
+            "<arg name=\"changedValue\" type=\"u\" />\n"
+        "</signal>\n"
+        "<method name=\"getTestDerivedStructAttributeAttribute\">\n"
+               "<arg name=\"value\" type=\"(sqi)\" direction=\"out\" />"
+        "</method>\n"
+        "<method name=\"setTestDerivedStructAttributeAttribute\">\n"
+            "<arg name=\"requestedValue\" type=\"(sqi)\" direction=\"in\" />\n"
+            "<arg name=\"setValue\" type=\"(sqi)\" direction=\"out\" />\n"
+        "</method>\n"
+        "<signal name=\"onTestDerivedStructAttributeAttributeChanged\">\n"
+            "<arg name=\"changedValue\" type=\"(sqi)\" />\n"
+        "</signal>\n"
+        "<method name=\"getTestDerivedArrayAttributeAttribute\">\n"
+               "<arg name=\"value\" type=\"at\" direction=\"out\" />"
+        "</method>\n"
+        "<method name=\"setTestDerivedArrayAttributeAttribute\">\n"
+            "<arg name=\"requestedValue\" type=\"at\" direction=\"in\" />\n"
+            "<arg name=\"setValue\" type=\"at\" direction=\"out\" />\n"
+        "</method>\n"
+        "<signal name=\"onTestDerivedArrayAttributeAttributeChanged\">\n"
+            "<arg name=\"changedValue\" type=\"at\" />\n"
+        "</signal>\n"
+        "<signal name=\"TestPredefinedTypeBroadcast\">\n"
+            "<arg name=\"uint32Value\" type=\"u\" />\n"
+            "<arg name=\"stringValue\" type=\"s\" />\n"
+        "</signal>\n"
+        "<method name=\"testVoidPredefinedTypeMethod\">\n"
+            "<arg name=\"uint32Value\" type=\"u\" direction=\"in\" />\n"
+            "<arg name=\"stringValue\" type=\"s\" direction=\"in\" />\n"
+            "<arg name=\"uint32Value\" type=\"u\" direction=\"out\" />\n"
+            "<arg name=\"stringValue\" type=\"s\" direction=\"out\" />\n"
+        "</method>\n"
+        "<method name=\"testPredefinedTypeMethod\">\n"
+            "<arg name=\"uint32InValue\" type=\"u\" direction=\"in\" />\n"
+            "<arg name=\"stringInValue\" type=\"s\" direction=\"in\" />\n"
+            "<arg name=\"uint32InValue\" type=\"u\" direction=\"out\" />\n"
+            "<arg name=\"stringInValue\" type=\"s\" direction=\"out\" />\n"
+        "</method>\n"
+        "<method name=\"testVoidDerivedTypeMethod\">\n"
+            "<arg name=\"testEnumExtended2Value\" type=\"i\" direction=\"in\" />\n"
+            "<arg name=\"testMapValue\" type=\"a{ua(sq)}\" direction=\"in\" />\n"
+            "<arg name=\"testEnumExtended2Value\" type=\"i\" direction=\"out\" />\n"
+            "<arg name=\"testMapValue\" type=\"a{ua(sq)}\" direction=\"out\" />\n"
+        "</method>\n"
+        "<method name=\"testDerivedTypeMethod\">\n"
+            "<arg name=\"testEnumExtended2InValue\" type=\"i\" direction=\"in\" />\n"
+            "<arg name=\"testMapInValue\" type=\"a{ua(sq)}\" direction=\"in\" />\n"
+            "<arg name=\"testEnumExtended2InValue\" type=\"i\" direction=\"out\" />\n"
+            "<arg name=\"testMapInValue\" type=\"a{ua(sq)}\" direction=\"out\" />\n"
+        "</method>\n"
+    ;
+}
+
+
+static CommonAPI::DBus::DBusGetAttributeStubDispatcher<
+        TestInterfaceStub,
+        uint32_t
+        > getTestPredefinedTypeAttributeAttributeStubDispatcher(&TestInterfaceStub::getTestPredefinedTypeAttributeAttribute, "u");
+static CommonAPI::DBus::DBusSetObservableAttributeStubDispatcher<
+        TestInterfaceStub,
+        uint32_t
+        > setTestPredefinedTypeAttributeAttributeStubDispatcher(
+                &TestInterfaceStub::getTestPredefinedTypeAttributeAttribute,
+                &TestInterfaceStubRemoteEvent::onRemoteSetTestPredefinedTypeAttributeAttribute,
+                &TestInterfaceStubRemoteEvent::onRemoteTestPredefinedTypeAttributeAttributeChanged,
+                &TestInterfaceStubAdapter::fireTestPredefinedTypeAttributeAttributeChanged,
+                "u");
+
+static CommonAPI::DBus::DBusGetAttributeStubDispatcher<
+        TestInterfaceStub,
+        DerivedTypeCollection::TestStructExtended
+        > getTestDerivedStructAttributeAttributeStubDispatcher(&TestInterfaceStub::getTestDerivedStructAttributeAttribute, "(sqi)");
+static CommonAPI::DBus::DBusSetObservableAttributeStubDispatcher<
+        TestInterfaceStub,
+        DerivedTypeCollection::TestStructExtended
+        > setTestDerivedStructAttributeAttributeStubDispatcher(
+                &TestInterfaceStub::getTestDerivedStructAttributeAttribute,
+                &TestInterfaceStubRemoteEvent::onRemoteSetTestDerivedStructAttributeAttribute,
+                &TestInterfaceStubRemoteEvent::onRemoteTestDerivedStructAttributeAttributeChanged,
+                &TestInterfaceStubAdapter::fireTestDerivedStructAttributeAttributeChanged,
+                "(sqi)");
+
+static CommonAPI::DBus::DBusGetAttributeStubDispatcher<
+        TestInterfaceStub,
+        DerivedTypeCollection::TestArrayUInt64
+        > getTestDerivedArrayAttributeAttributeStubDispatcher(&TestInterfaceStub::getTestDerivedArrayAttributeAttribute, "at");
+static CommonAPI::DBus::DBusSetObservableAttributeStubDispatcher<
+        TestInterfaceStub,
+        DerivedTypeCollection::TestArrayUInt64
+        > setTestDerivedArrayAttributeAttributeStubDispatcher(
+                &TestInterfaceStub::getTestDerivedArrayAttributeAttribute,
+                &TestInterfaceStubRemoteEvent::onRemoteSetTestDerivedArrayAttributeAttribute,
+                &TestInterfaceStubRemoteEvent::onRemoteTestDerivedArrayAttributeAttributeChanged,
+                &TestInterfaceStubAdapter::fireTestDerivedArrayAttributeAttributeChanged,
+                "at");
+
+
+static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
+    TestInterfaceStub,
+    std::tuple<uint32_t, std::string>,
+    std::tuple<>
+    > testVoidPredefinedTypeMethodStubDispatcher(&TestInterfaceStub::testVoidPredefinedTypeMethod, "");
+
+static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
+    TestInterfaceStub,
+    std::tuple<uint32_t, std::string>,
+    std::tuple<uint32_t, std::string>
+    > testPredefinedTypeMethodStubDispatcher(&TestInterfaceStub::testPredefinedTypeMethod, "us");
+
+static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
+    TestInterfaceStub,
+    std::tuple<DerivedTypeCollection::TestEnumExtended2, DerivedTypeCollection::TestMap>,
+    std::tuple<>
+    > testVoidDerivedTypeMethodStubDispatcher(&TestInterfaceStub::testVoidDerivedTypeMethod, "");
+
+static CommonAPI::DBus::DBusMethodWithReplyStubDispatcher<
+    TestInterfaceStub,
+    std::tuple<DerivedTypeCollection::TestEnumExtended2, DerivedTypeCollection::TestMap>,
+    std::tuple<DerivedTypeCollection::TestEnumExtended2, DerivedTypeCollection::TestMap>
+    > testDerivedTypeMethodStubDispatcher(&TestInterfaceStub::testDerivedTypeMethod, "ia{ua(sq)}");
+
+
+template<>
+const TestInterfaceDBusStubAdapterHelper::StubDispatcherTable TestInterfaceDBusStubAdapterHelper::stubDispatcherTable_ = {
+    { { "getTestPredefinedTypeAttributeAttribute", "" }, &commonapi::tests::getTestPredefinedTypeAttributeAttributeStubDispatcher }
+    , { { "setTestPredefinedTypeAttributeAttribute", "u" }, &commonapi::tests::setTestPredefinedTypeAttributeAttributeStubDispatcher },
+    { { "getTestDerivedStructAttributeAttribute", "" }, &commonapi::tests::getTestDerivedStructAttributeAttributeStubDispatcher }
+    , { { "setTestDerivedStructAttributeAttribute", "(sqi)" }, &commonapi::tests::setTestDerivedStructAttributeAttributeStubDispatcher },
+    { { "getTestDerivedArrayAttributeAttribute", "" }, &commonapi::tests::getTestDerivedArrayAttributeAttributeStubDispatcher }
+    , { { "setTestDerivedArrayAttributeAttribute", "at" }, &commonapi::tests::setTestDerivedArrayAttributeAttributeStubDispatcher }
+    ,
+    { { "testVoidPredefinedTypeMethod", "us" }, &commonapi::tests::testVoidPredefinedTypeMethodStubDispatcher },
+    { { "testPredefinedTypeMethod", "us" }, &commonapi::tests::testPredefinedTypeMethodStubDispatcher },
+    { { "testVoidDerivedTypeMethod", "ia{ua(sq)}" }, &commonapi::tests::testVoidDerivedTypeMethodStubDispatcher },
+    { { "testDerivedTypeMethod", "ia{ua(sq)}" }, &commonapi::tests::testDerivedTypeMethodStubDispatcher }
+};
+
+void TestInterfaceDBusStubAdapter::fireTestPredefinedTypeAttributeAttributeChanged(const uint32_t& value) {
+    CommonAPI::DBus::DBusStubSignalHelper<CommonAPI::DBus::DBusSerializableArguments<uint32_t>>
+        ::sendSignal(
+            *this,
+            "onTestPredefinedTypeAttributeAttributeChanged",
+            "u",
+            value
+    );
+}
+void TestInterfaceDBusStubAdapter::fireTestDerivedStructAttributeAttributeChanged(const DerivedTypeCollection::TestStructExtended& value) {
+       CommonAPI::DBus::DBusStubSignalHelper<CommonAPI::DBus::DBusSerializableArguments<DerivedTypeCollection::TestStructExtended>>
+        ::sendSignal(
+            *this,
+            "onTestDerivedStructAttributeAttributeChanged",
+            "(sqi)",
+            value
+    );
+}
+void TestInterfaceDBusStubAdapter::fireTestDerivedArrayAttributeAttributeChanged(const DerivedTypeCollection::TestArrayUInt64& value) {
+       CommonAPI::DBus::DBusStubSignalHelper<CommonAPI::DBus::DBusSerializableArguments<DerivedTypeCollection::TestArrayUInt64>>
+        ::sendSignal(
+            *this,
+            "onTestDerivedArrayAttributeAttributeChanged",
+            "at",
+            value
+    );
+}
+
+void TestInterfaceDBusStubAdapter::fireTestPredefinedTypeBroadcastEvent(const uint32_t& uint32Value, const std::string& stringValue) {
+    CommonAPI::DBus::DBusStubSignalHelper<CommonAPI::DBus::DBusSerializableArguments<uint32_t, std::string>>
+            ::sendSignal(
+                *this,
+                "TestPredefinedTypeBroadcast",
+                "us",
+                uint32Value, stringValue
+        );
+}
+
+} // namespace tests
+} // namespace commonapi
diff --git a/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceDBusStubAdapter.h b/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceDBusStubAdapter.h
new file mode 100644 (file)
index 0000000..ef32fd2
--- /dev/null
@@ -0,0 +1,38 @@
+/* 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_TESTS_TEST_INTERFACE_DBUS_STUB_ADAPTER_H_
+#define COMMONAPI_TESTS_TEST_INTERFACE_DBUS_STUB_ADAPTER_H_
+
+#include "TestInterfaceStub.h"
+
+#include <CommonAPI/DBus/DBusStubAdapterHelper.h>
+#include <CommonAPI/DBus/DBusFactory.h>
+
+namespace commonapi {
+namespace tests {
+
+typedef CommonAPI::DBus::DBusStubAdapterHelper<TestInterfaceStub> TestInterfaceDBusStubAdapterHelper;
+
+class TestInterfaceDBusStubAdapter: public TestInterfaceStubAdapter, public TestInterfaceDBusStubAdapterHelper {
+ public:
+    TestInterfaceDBusStubAdapter(
+            const std::string& dbusBusName,
+            const std::string& dbusObjectPath,
+            const std::shared_ptr<CommonAPI::DBus::DBusProxyConnection>& dbusConnection,
+            const std::shared_ptr<CommonAPI::StubBase>& stub);
+    
+    void fireTestPredefinedTypeAttributeAttributeChanged(const uint32_t& value);
+    void fireTestDerivedStructAttributeAttributeChanged(const DerivedTypeCollection::TestStructExtended& value);
+    void fireTestDerivedArrayAttributeAttributeChanged(const DerivedTypeCollection::TestArrayUInt64& value);
+
+    void fireTestPredefinedTypeBroadcastEvent(const uint32_t& uint32Value, const std::string& stringValue);
+
+ protected:
+    virtual const char* getMethodsDBusIntrospectionXmlData() const;
+};
+
+} // namespace tests
+} // namespace commonapi
+
+#endif // COMMONAPI_TESTS_TEST_INTERFACE_DBUS_STUB_ADAPTER_H_
diff --git a/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceProxy.h b/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceProxy.h
new file mode 100644 (file)
index 0000000..749d8d3
--- /dev/null
@@ -0,0 +1,237 @@
+/* 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_TESTS_TEST_INTERFACE_PROXY_H_
+#define COMMONAPI_TESTS_TEST_INTERFACE_PROXY_H_
+
+#include "TestInterfaceProxyBase.h"
+#include <CommonAPI/AttributeExtension.h>
+
+namespace commonapi {
+namespace tests {
+
+template <typename ... _AttributeExtensions>
+class TestInterfaceProxy: virtual public TestInterface, virtual public TestInterfaceProxyBase, public _AttributeExtensions... {
+ public:
+    TestInterfaceProxy(std::shared_ptr<CommonAPI::Proxy> delegate);
+    ~TestInterfaceProxy();
+
+    virtual TestPredefinedTypeAttributeAttribute& getTestPredefinedTypeAttributeAttribute();
+    virtual TestDerivedStructAttributeAttribute& getTestDerivedStructAttributeAttribute();
+    virtual TestDerivedArrayAttributeAttribute& getTestDerivedArrayAttributeAttribute();
+
+    virtual TestPredefinedTypeBroadcastEvent& getTestPredefinedTypeBroadcastEvent();
+
+
+    virtual void testVoidPredefinedTypeMethod(const uint32_t& uint32Value, const std::string& stringValue, CommonAPI::CallStatus& callStatus);
+    virtual std::future<CommonAPI::CallStatus> testVoidPredefinedTypeMethodAsync(const uint32_t& uint32Value, const std::string& stringValue, TestVoidPredefinedTypeMethodAsyncCallback callback);
+
+    virtual void testPredefinedTypeMethod(const uint32_t& uint32InValue, const std::string& stringInValue, CommonAPI::CallStatus& callStatus, uint32_t& uint32OutValue, std::string& stringOutValue);
+    virtual std::future<CommonAPI::CallStatus> testPredefinedTypeMethodAsync(const uint32_t& uint32InValue, const std::string& stringInValue, TestPredefinedTypeMethodAsyncCallback callback);
+
+    virtual void testVoidDerivedTypeMethod(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2Value, const DerivedTypeCollection::TestMap& testMapValue, CommonAPI::CallStatus& callStatus);
+    virtual std::future<CommonAPI::CallStatus> testVoidDerivedTypeMethodAsync(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2Value, const DerivedTypeCollection::TestMap& testMapValue, TestVoidDerivedTypeMethodAsyncCallback callback);
+
+    virtual void testDerivedTypeMethod(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2InValue, const DerivedTypeCollection::TestMap& testMapInValue, CommonAPI::CallStatus& callStatus, DerivedTypeCollection::TestEnumExtended2& testEnumExtended2OutValue, DerivedTypeCollection::TestMap& testMapOutValue);
+    virtual std::future<CommonAPI::CallStatus> testDerivedTypeMethodAsync(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2InValue, const DerivedTypeCollection::TestMap& testMapInValue, TestDerivedTypeMethodAsyncCallback callback);
+
+    virtual std::string getAddress() const;
+    virtual const std::string& getDomain() const;
+    virtual const std::string& getServiceId() const;
+    virtual const std::string& getInstanceId() const;
+    virtual bool isAvailable() const;
+    virtual CommonAPI::ProxyStatusEvent& getProxyStatusEvent();
+    virtual CommonAPI::InterfaceVersionAttribute& getInterfaceVersionAttribute();
+
+ private:
+    std::shared_ptr<TestInterfaceProxyBase> delegate_;
+};
+
+namespace TestInterfaceExtensions {
+    template <template <typename > class _ExtensionType>
+    class TestPredefinedTypeAttributeAttributeExtension {
+     public:
+        typedef _ExtensionType<TestInterfaceProxyBase::TestPredefinedTypeAttributeAttribute> extension_type;
+    
+        static_assert(std::is_base_of<typename CommonAPI::AttributeExtension<TestInterfaceProxyBase::TestPredefinedTypeAttributeAttribute>, extension_type>::value,
+                      "Not CommonAPI Attribute Extension!");
+    
+        TestPredefinedTypeAttributeAttributeExtension(TestInterfaceProxyBase& proxy): attributeExtension_(proxy.getTestPredefinedTypeAttributeAttribute()) {
+        }
+    
+        inline extension_type& getTestPredefinedTypeAttributeAttributeExtension() {
+            return attributeExtension_;
+        }
+    
+     private:
+        extension_type attributeExtension_;
+    };
+
+    template <template <typename > class _ExtensionType>
+    class TestDerivedStructAttributeAttributeExtension {
+     public:
+        typedef _ExtensionType<TestInterfaceProxyBase::TestDerivedStructAttributeAttribute> extension_type;
+    
+        static_assert(std::is_base_of<typename CommonAPI::AttributeExtension<TestInterfaceProxyBase::TestDerivedStructAttributeAttribute>, extension_type>::value,
+                      "Not CommonAPI Attribute Extension!");
+    
+        TestDerivedStructAttributeAttributeExtension(TestInterfaceProxyBase& proxy): attributeExtension_(proxy.getTestDerivedStructAttributeAttribute()) {
+        }
+    
+        inline extension_type& getTestDerivedStructAttributeAttributeExtension() {
+            return attributeExtension_;
+        }
+    
+     private:
+        extension_type attributeExtension_;
+    };
+
+    template <template <typename > class _ExtensionType>
+    class TestDerivedArrayAttributeAttributeExtension {
+     public:
+        typedef _ExtensionType<TestInterfaceProxyBase::TestDerivedArrayAttributeAttribute> extension_type;
+    
+        static_assert(std::is_base_of<typename CommonAPI::AttributeExtension<TestInterfaceProxyBase::TestDerivedArrayAttributeAttribute>, extension_type>::value,
+                      "Not CommonAPI Attribute Extension!");
+    
+        TestDerivedArrayAttributeAttributeExtension(TestInterfaceProxyBase& proxy): attributeExtension_(proxy.getTestDerivedArrayAttributeAttribute()) {
+        }
+    
+        inline extension_type& getTestDerivedArrayAttributeAttributeExtension() {
+            return attributeExtension_;
+        }
+    
+     private:
+        extension_type attributeExtension_;
+    };
+
+} // namespace TestInterfaceExtensions
+
+//
+// TestInterfaceProxy Implementation
+//
+template <typename ... _AttributeExtensions>
+TestInterfaceProxy<_AttributeExtensions...>::TestInterfaceProxy(std::shared_ptr<CommonAPI::Proxy> delegate):
+        delegate_(std::dynamic_pointer_cast<TestInterfaceProxyBase>(delegate)),
+        _AttributeExtensions(*(std::dynamic_pointer_cast<TestInterfaceProxyBase>(delegate)))... {
+}
+
+template <typename ... _AttributeExtensions>
+TestInterfaceProxy<_AttributeExtensions...>::~TestInterfaceProxy() {
+}
+
+template <typename ... _AttributeExtensions>
+typename TestInterfaceProxy<_AttributeExtensions...>::TestPredefinedTypeAttributeAttribute& TestInterfaceProxy<_AttributeExtensions...>::getTestPredefinedTypeAttributeAttribute() {
+    return delegate_->getTestPredefinedTypeAttributeAttribute();
+}
+
+template <typename ... _AttributeExtensions>
+typename TestInterfaceProxy<_AttributeExtensions...>::TestDerivedStructAttributeAttribute& TestInterfaceProxy<_AttributeExtensions...>::getTestDerivedStructAttributeAttribute() {
+    return delegate_->getTestDerivedStructAttributeAttribute();
+}
+
+template <typename ... _AttributeExtensions>
+typename TestInterfaceProxy<_AttributeExtensions...>::TestDerivedArrayAttributeAttribute& TestInterfaceProxy<_AttributeExtensions...>::getTestDerivedArrayAttributeAttribute() {
+    return delegate_->getTestDerivedArrayAttributeAttribute();
+}
+
+
+template <typename ... _AttributeExtensions>
+typename TestInterfaceProxy<_AttributeExtensions...>::TestPredefinedTypeBroadcastEvent& TestInterfaceProxy<_AttributeExtensions...>::getTestPredefinedTypeBroadcastEvent() {
+    return delegate_->getTestPredefinedTypeBroadcastEvent();
+}
+
+
+template <typename ... _AttributeExtensions>
+void TestInterfaceProxy<_AttributeExtensions...>::testVoidPredefinedTypeMethod(const uint32_t& uint32Value, const std::string& stringValue, CommonAPI::CallStatus& callStatus) {
+    delegate_->testVoidPredefinedTypeMethod(uint32Value, stringValue, callStatus);
+}
+
+template <typename ... _AttributeExtensions>
+std::future<CommonAPI::CallStatus> TestInterfaceProxy<_AttributeExtensions...>::testVoidPredefinedTypeMethodAsync(const uint32_t& uint32Value, const std::string& stringValue, TestVoidPredefinedTypeMethodAsyncCallback callback) {
+    return delegate_->testVoidPredefinedTypeMethodAsync(uint32Value, stringValue, callback);
+}
+
+template <typename ... _AttributeExtensions>
+void TestInterfaceProxy<_AttributeExtensions...>::testPredefinedTypeMethod(const uint32_t& uint32InValue, const std::string& stringInValue, CommonAPI::CallStatus& callStatus, uint32_t& uint32OutValue, std::string& stringOutValue) {
+    delegate_->testPredefinedTypeMethod(uint32InValue, stringInValue, callStatus, uint32OutValue, stringOutValue);
+}
+
+template <typename ... _AttributeExtensions>
+std::future<CommonAPI::CallStatus> TestInterfaceProxy<_AttributeExtensions...>::testPredefinedTypeMethodAsync(const uint32_t& uint32InValue, const std::string& stringInValue, TestPredefinedTypeMethodAsyncCallback callback) {
+    return delegate_->testPredefinedTypeMethodAsync(uint32InValue, stringInValue, callback);
+}
+
+template <typename ... _AttributeExtensions>
+void TestInterfaceProxy<_AttributeExtensions...>::testVoidDerivedTypeMethod(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2Value, const DerivedTypeCollection::TestMap& testMapValue, CommonAPI::CallStatus& callStatus) {
+    delegate_->testVoidDerivedTypeMethod(testEnumExtended2Value, testMapValue, callStatus);
+}
+
+template <typename ... _AttributeExtensions>
+std::future<CommonAPI::CallStatus> TestInterfaceProxy<_AttributeExtensions...>::testVoidDerivedTypeMethodAsync(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2Value, const DerivedTypeCollection::TestMap& testMapValue, TestVoidDerivedTypeMethodAsyncCallback callback) {
+    return delegate_->testVoidDerivedTypeMethodAsync(testEnumExtended2Value, testMapValue, callback);
+}
+
+template <typename ... _AttributeExtensions>
+void TestInterfaceProxy<_AttributeExtensions...>::testDerivedTypeMethod(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2InValue, const DerivedTypeCollection::TestMap& testMapInValue, CommonAPI::CallStatus& callStatus, DerivedTypeCollection::TestEnumExtended2& testEnumExtended2OutValue, DerivedTypeCollection::TestMap& testMapOutValue) {
+    delegate_->testDerivedTypeMethod(testEnumExtended2InValue, testMapInValue, callStatus, testEnumExtended2OutValue, testMapOutValue);
+}
+
+template <typename ... _AttributeExtensions>
+std::future<CommonAPI::CallStatus> TestInterfaceProxy<_AttributeExtensions...>::testDerivedTypeMethodAsync(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2InValue, const DerivedTypeCollection::TestMap& testMapInValue, TestDerivedTypeMethodAsyncCallback callback) {
+    return delegate_->testDerivedTypeMethodAsync(testEnumExtended2InValue, testMapInValue, callback);
+}
+
+
+template <typename ... _AttributeExtensions>
+std::string TestInterfaceProxy<_AttributeExtensions...>::getAddress() const {
+    return delegate_->getAddress();
+}
+
+template <typename ... _AttributeExtensions>
+const std::string& TestInterfaceProxy<_AttributeExtensions...>::getDomain() const {
+    return delegate_->getDomain();
+}
+
+template <typename ... _AttributeExtensions>
+const std::string& TestInterfaceProxy<_AttributeExtensions...>::getServiceId() const {
+    return delegate_->getServiceId();
+}
+
+template <typename ... _AttributeExtensions>
+const std::string& TestInterfaceProxy<_AttributeExtensions...>::getInstanceId() const {
+    return delegate_->getInstanceId();
+}
+
+template <typename ... _AttributeExtensions>
+bool TestInterfaceProxy<_AttributeExtensions...>::isAvailable() const {
+    return delegate_->isAvailable();
+}
+
+template <typename ... _AttributeExtensions>
+CommonAPI::ProxyStatusEvent& TestInterfaceProxy<_AttributeExtensions...>::getProxyStatusEvent() {
+    return delegate_->getProxyStatusEvent();
+}
+
+template <typename ... _AttributeExtensions>
+CommonAPI::InterfaceVersionAttribute& TestInterfaceProxy<_AttributeExtensions...>::getInterfaceVersionAttribute() {
+    return delegate_->getInterfaceVersionAttribute();
+}
+
+} // namespace tests
+} // namespace commonapi
+
+namespace CommonAPI {
+template<template<typename > class _AttributeExtension>
+struct DefaultAttributeProxyFactoryHelper<commonapi::tests::TestInterfaceProxy,
+    _AttributeExtension> {
+    typedef typename commonapi::tests::TestInterfaceProxy<
+            commonapi::tests::TestInterfaceExtensions::TestPredefinedTypeAttributeAttributeExtension<_AttributeExtension>, 
+            commonapi::tests::TestInterfaceExtensions::TestDerivedStructAttributeAttributeExtension<_AttributeExtension>, 
+            commonapi::tests::TestInterfaceExtensions::TestDerivedArrayAttributeAttributeExtension<_AttributeExtension>
+    > class_t;
+};
+}
+
+
+#endif // COMMONAPI_TESTS_TEST_INTERFACE_PROXY_H_
diff --git a/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceProxyBase.h b/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceProxyBase.h
new file mode 100644 (file)
index 0000000..7ce380f
--- /dev/null
@@ -0,0 +1,58 @@
+/* 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_TESTS_TEST_INTERFACE_PROXY_BASE_H_
+#define COMMONAPI_TESTS_TEST_INTERFACE_PROXY_BASE_H_
+
+#include "TestInterface.h"
+#include <unordered_map>
+#include <cstdint>
+#include "DerivedTypeCollection.h"
+#include <CommonAPI/InputStream.h>
+#include <vector>
+#include <CommonAPI/OutputStream.h>
+#include <CommonAPI/Attribute.h>
+#include <CommonAPI/Event.h>
+#include <CommonAPI/Proxy.h>
+#include <functional>
+#include <future>
+
+namespace commonapi {
+namespace tests {
+
+class TestInterfaceProxyBase: virtual public CommonAPI::Proxy {
+ public:
+    typedef CommonAPI::ObservableAttribute<uint32_t> TestPredefinedTypeAttributeAttribute;
+    typedef CommonAPI::ObservableAttribute<DerivedTypeCollection::TestStructExtended> TestDerivedStructAttributeAttribute;
+    typedef CommonAPI::ObservableAttribute<DerivedTypeCollection::TestArrayUInt64> TestDerivedArrayAttributeAttribute;
+    typedef CommonAPI::Event<uint32_t, std::string> TestPredefinedTypeBroadcastEvent;
+    typedef std::function<void(const CommonAPI::CallStatus&)> TestVoidPredefinedTypeMethodAsyncCallback;
+    typedef std::function<void(const CommonAPI::CallStatus&, const uint32_t&, const std::string&)> TestPredefinedTypeMethodAsyncCallback;
+    typedef std::function<void(const CommonAPI::CallStatus&)> TestVoidDerivedTypeMethodAsyncCallback;
+    typedef std::function<void(const CommonAPI::CallStatus&, const DerivedTypeCollection::TestEnumExtended2&, const DerivedTypeCollection::TestMap&)> TestDerivedTypeMethodAsyncCallback;
+
+    virtual TestPredefinedTypeAttributeAttribute& getTestPredefinedTypeAttributeAttribute() = 0;
+    virtual TestDerivedStructAttributeAttribute& getTestDerivedStructAttributeAttribute() = 0;
+    virtual TestDerivedArrayAttributeAttribute& getTestDerivedArrayAttributeAttribute() = 0;
+
+    virtual TestPredefinedTypeBroadcastEvent& getTestPredefinedTypeBroadcastEvent() = 0;
+
+
+    virtual void testVoidPredefinedTypeMethod(const uint32_t& uint32Value, const std::string& stringValue, CommonAPI::CallStatus& callStatus) = 0;
+    virtual std::future<CommonAPI::CallStatus> testVoidPredefinedTypeMethodAsync(const uint32_t& uint32Value, const std::string& stringValue, TestVoidPredefinedTypeMethodAsyncCallback callback) = 0;
+
+    virtual void testPredefinedTypeMethod(const uint32_t& uint32InValue, const std::string& stringInValue, CommonAPI::CallStatus& callStatus, uint32_t& uint32OutValue, std::string& stringOutValue) = 0;
+    virtual std::future<CommonAPI::CallStatus> testPredefinedTypeMethodAsync(const uint32_t& uint32InValue, const std::string& stringInValue, TestPredefinedTypeMethodAsyncCallback callback) = 0;
+
+    virtual void testVoidDerivedTypeMethod(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2Value, const DerivedTypeCollection::TestMap& testMapValue, CommonAPI::CallStatus& callStatus) = 0;
+    virtual std::future<CommonAPI::CallStatus> testVoidDerivedTypeMethodAsync(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2Value, const DerivedTypeCollection::TestMap& testMapValue, TestVoidDerivedTypeMethodAsyncCallback callback) = 0;
+
+    virtual void testDerivedTypeMethod(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2InValue, const DerivedTypeCollection::TestMap& testMapInValue, CommonAPI::CallStatus& callStatus, DerivedTypeCollection::TestEnumExtended2& testEnumExtended2OutValue, DerivedTypeCollection::TestMap& testMapOutValue) = 0;
+    virtual std::future<CommonAPI::CallStatus> testDerivedTypeMethodAsync(const DerivedTypeCollection::TestEnumExtended2& testEnumExtended2InValue, const DerivedTypeCollection::TestMap& testMapInValue, TestDerivedTypeMethodAsyncCallback callback) = 0;
+};
+
+
+} // namespace tests
+} // namespace commonapi
+
+#endif // COMMONAPI_TESTS_TEST_INTERFACE_PROXY_BASE_H_
diff --git a/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceStub.h b/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceStub.h
new file mode 100644 (file)
index 0000000..0181f0a
--- /dev/null
@@ -0,0 +1,64 @@
+/* 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_TESTS_TEST_INTERFACE_STUB_H_
+#define COMMONAPI_TESTS_TEST_INTERFACE_STUB_H_
+
+#include <unordered_map>
+#include <cstdint>
+#include "DerivedTypeCollection.h"
+#include <CommonAPI/InputStream.h>
+#include <vector>
+#include <CommonAPI/OutputStream.h>
+#include "TestInterface.h"
+#include <CommonAPI/Stub.h>
+
+namespace commonapi {
+namespace tests {
+
+class TestInterfaceStubAdapter: virtual public CommonAPI::StubAdapter, public TestInterface {
+ public:
+    virtual void fireTestPredefinedTypeAttributeAttributeChanged(const uint32_t& TestPredefinedTypeAttribute) = 0;
+    virtual void fireTestDerivedStructAttributeAttributeChanged(const DerivedTypeCollection::TestStructExtended& TestDerivedStructAttribute) = 0;
+    virtual void fireTestDerivedArrayAttributeAttributeChanged(const DerivedTypeCollection::TestArrayUInt64& TestDerivedArrayAttribute) = 0;
+
+    virtual void fireTestPredefinedTypeBroadcastEvent(const uint32_t& uint32Value, const std::string& stringValue) = 0;
+};
+
+
+class TestInterfaceStubRemoteEvent {
+ public:
+    virtual ~TestInterfaceStubRemoteEvent() { }
+
+    virtual bool onRemoteSetTestPredefinedTypeAttributeAttribute(uint32_t TestPredefinedTypeAttribute) = 0;
+    virtual void onRemoteTestPredefinedTypeAttributeAttributeChanged() = 0;
+
+    virtual bool onRemoteSetTestDerivedStructAttributeAttribute(DerivedTypeCollection::TestStructExtended TestDerivedStructAttribute) = 0;
+    virtual void onRemoteTestDerivedStructAttributeAttributeChanged() = 0;
+
+    virtual bool onRemoteSetTestDerivedArrayAttributeAttribute(DerivedTypeCollection::TestArrayUInt64 TestDerivedArrayAttribute) = 0;
+    virtual void onRemoteTestDerivedArrayAttributeAttributeChanged() = 0;
+
+};
+
+
+class TestInterfaceStub : public CommonAPI::Stub<TestInterfaceStubAdapter , TestInterfaceStubRemoteEvent> {
+ public:
+    virtual const uint32_t& getTestPredefinedTypeAttributeAttribute() = 0;
+    virtual const DerivedTypeCollection::TestStructExtended& getTestDerivedStructAttributeAttribute() = 0;
+    virtual const DerivedTypeCollection::TestArrayUInt64& getTestDerivedArrayAttributeAttribute() = 0;
+
+    virtual void testVoidPredefinedTypeMethod(uint32_t uint32Value, std::string stringValue) = 0;
+
+    virtual void testPredefinedTypeMethod(uint32_t uint32InValue, std::string stringInValue, uint32_t& uint32OutValue, std::string& stringOutValue) = 0;
+
+    virtual void testVoidDerivedTypeMethod(DerivedTypeCollection::TestEnumExtended2 testEnumExtended2Value, DerivedTypeCollection::TestMap testMapValue) = 0;
+
+    virtual void testDerivedTypeMethod(DerivedTypeCollection::TestEnumExtended2 testEnumExtended2InValue, DerivedTypeCollection::TestMap testMapInValue, DerivedTypeCollection::TestEnumExtended2& testEnumExtended2OutValue, DerivedTypeCollection::TestMap& testMapOutValue) = 0;
+
+};
+
+} // namespace tests
+} // namespace commonapi
+
+#endif // COMMONAPI_TESTS_TEST_INTERFACE_STUB_H_
diff --git a/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceStubDefault.cpp b/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceStubDefault.cpp
new file mode 100644 (file)
index 0000000..2ba4e9b
--- /dev/null
@@ -0,0 +1,151 @@
+/* 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 "TestInterfaceStubDefault.h"
+
+namespace commonapi {
+namespace tests {
+
+TestInterfaceStubDefault::TestInterfaceStubDefault():
+        remoteEventHandler_(this) {
+}
+
+TestInterfaceStubRemoteEvent* TestInterfaceStubDefault::initStubAdapter(const std::shared_ptr<TestInterfaceStubAdapter>& stubAdapter) {
+    stubAdapter_ = stubAdapter;
+    return &remoteEventHandler_;
+}
+
+const uint32_t& TestInterfaceStubDefault::getTestPredefinedTypeAttributeAttribute() {
+    return testPredefinedTypeAttributeAttributeValue_;
+}
+
+void TestInterfaceStubDefault::setTestPredefinedTypeAttributeAttribute(uint32_t value) {
+    const bool valueChanged = trySetTestPredefinedTypeAttributeAttribute(std::move(value));
+    if (valueChanged)
+        stubAdapter_->fireTestPredefinedTypeAttributeAttributeChanged(testPredefinedTypeAttributeAttributeValue_);
+}
+
+void TestInterfaceStubDefault::onRemoteTestPredefinedTypeAttributeAttributeChanged() {
+    // No operation in default
+}
+
+bool TestInterfaceStubDefault::trySetTestPredefinedTypeAttributeAttribute(uint32_t value) {
+    if (!validateTestPredefinedTypeAttributeAttributeRequestedValue(value))
+        return false;
+
+    const bool valueChanged = (testPredefinedTypeAttributeAttributeValue_ != value);
+    testPredefinedTypeAttributeAttributeValue_ = std::move(value);
+    return valueChanged;
+}
+
+bool TestInterfaceStubDefault::validateTestPredefinedTypeAttributeAttributeRequestedValue(const uint32_t& value) {
+    return true;
+}
+
+const DerivedTypeCollection::TestStructExtended& TestInterfaceStubDefault::getTestDerivedStructAttributeAttribute() {
+    return testDerivedStructAttributeAttributeValue_;
+}
+
+void TestInterfaceStubDefault::setTestDerivedStructAttributeAttribute(DerivedTypeCollection::TestStructExtended value) {
+    const bool valueChanged = trySetTestDerivedStructAttributeAttribute(std::move(value));
+    if (valueChanged)
+        stubAdapter_->fireTestDerivedStructAttributeAttributeChanged(testDerivedStructAttributeAttributeValue_);
+}
+
+void TestInterfaceStubDefault::onRemoteTestDerivedStructAttributeAttributeChanged() {
+    // No operation in default
+}
+
+bool TestInterfaceStubDefault::trySetTestDerivedStructAttributeAttribute(DerivedTypeCollection::TestStructExtended value) {
+    if (!validateTestDerivedStructAttributeAttributeRequestedValue(value))
+        return false;
+
+    const bool valueChanged = (testDerivedStructAttributeAttributeValue_ != value);
+    testDerivedStructAttributeAttributeValue_ = std::move(value);
+    return valueChanged;
+}
+
+bool TestInterfaceStubDefault::validateTestDerivedStructAttributeAttributeRequestedValue(const DerivedTypeCollection::TestStructExtended& value) {
+    return true;
+}
+
+const DerivedTypeCollection::TestArrayUInt64& TestInterfaceStubDefault::getTestDerivedArrayAttributeAttribute() {
+    return testDerivedArrayAttributeAttributeValue_;
+}
+
+void TestInterfaceStubDefault::setTestDerivedArrayAttributeAttribute(DerivedTypeCollection::TestArrayUInt64 value) {
+    const bool valueChanged = trySetTestDerivedArrayAttributeAttribute(std::move(value));
+    if (valueChanged)
+        stubAdapter_->fireTestDerivedArrayAttributeAttributeChanged(testDerivedArrayAttributeAttributeValue_);
+}
+
+void TestInterfaceStubDefault::onRemoteTestDerivedArrayAttributeAttributeChanged() {
+    // No operation in default
+}
+
+bool TestInterfaceStubDefault::trySetTestDerivedArrayAttributeAttribute(DerivedTypeCollection::TestArrayUInt64 value) {
+    if (!validateTestDerivedArrayAttributeAttributeRequestedValue(value))
+        return false;
+
+    const bool valueChanged = (testDerivedArrayAttributeAttributeValue_ != value);
+    testDerivedArrayAttributeAttributeValue_ = std::move(value);
+    return valueChanged;
+}
+
+bool TestInterfaceStubDefault::validateTestDerivedArrayAttributeAttributeRequestedValue(const DerivedTypeCollection::TestArrayUInt64& value) {
+    return true;
+}
+
+
+void TestInterfaceStubDefault::testVoidPredefinedTypeMethod(uint32_t uint32Value, std::string stringValue) {
+    // No operation in default
+}
+
+void TestInterfaceStubDefault::testPredefinedTypeMethod(uint32_t uint32InValue, std::string stringInValue, uint32_t& uint32OutValue, std::string& stringOutValue) {
+    // No operation in default
+}
+
+void TestInterfaceStubDefault::testVoidDerivedTypeMethod(DerivedTypeCollection::TestEnumExtended2 testEnumExtended2Value, DerivedTypeCollection::TestMap testMapValue) {
+    // No operation in default
+}
+
+void TestInterfaceStubDefault::testDerivedTypeMethod(DerivedTypeCollection::TestEnumExtended2 testEnumExtended2InValue, DerivedTypeCollection::TestMap testMapInValue, DerivedTypeCollection::TestEnumExtended2& testEnumExtended2OutValue, DerivedTypeCollection::TestMap& testMapOutValue) {
+    // No operation in default
+}
+
+void TestInterfaceStubDefault::firePredefinedBroadcast(uint32_t value, std::string& sValue) {
+    stubAdapter_->fireTestPredefinedTypeBroadcastEvent(value, sValue);
+}
+
+
+TestInterfaceStubDefault::RemoteEventHandler::RemoteEventHandler(TestInterfaceStubDefault* defaultStub):
+        defaultStub_(defaultStub) {
+}
+
+bool TestInterfaceStubDefault::RemoteEventHandler::onRemoteSetTestPredefinedTypeAttributeAttribute(uint32_t value) {
+    return defaultStub_->trySetTestPredefinedTypeAttributeAttribute(std::move(value));
+}
+
+void TestInterfaceStubDefault::RemoteEventHandler::onRemoteTestPredefinedTypeAttributeAttributeChanged() {
+    defaultStub_->onRemoteTestPredefinedTypeAttributeAttributeChanged();
+}
+
+bool TestInterfaceStubDefault::RemoteEventHandler::onRemoteSetTestDerivedStructAttributeAttribute(DerivedTypeCollection::TestStructExtended value) {
+    return defaultStub_->trySetTestDerivedStructAttributeAttribute(std::move(value));
+}
+
+void TestInterfaceStubDefault::RemoteEventHandler::onRemoteTestDerivedStructAttributeAttributeChanged() {
+    defaultStub_->onRemoteTestDerivedStructAttributeAttributeChanged();
+}
+
+bool TestInterfaceStubDefault::RemoteEventHandler::onRemoteSetTestDerivedArrayAttributeAttribute(DerivedTypeCollection::TestArrayUInt64 value) {
+    return defaultStub_->trySetTestDerivedArrayAttributeAttribute(std::move(value));
+}
+
+void TestInterfaceStubDefault::RemoteEventHandler::onRemoteTestDerivedArrayAttributeAttributeChanged() {
+    defaultStub_->onRemoteTestDerivedArrayAttributeAttributeChanged();
+}
+
+
+} // namespace tests
+} // namespace commonapi
diff --git a/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceStubDefault.h b/CommonAPI-DBus/src/test/commonapi/tests/TestInterfaceStubDefault.h
new file mode 100644 (file)
index 0000000..de66e00
--- /dev/null
@@ -0,0 +1,82 @@
+/* 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_TESTS_TEST_INTERFACE_STUB_DEFAULT_H_
+#define COMMONAPI_TESTS_TEST_INTERFACE_STUB_DEFAULT_H_
+
+#include "TestInterfaceStub.h"
+
+namespace commonapi {
+namespace tests {
+
+class TestInterfaceStubDefault : public TestInterfaceStub {
+ public:
+    TestInterfaceStubDefault();
+
+    TestInterfaceStubRemoteEvent* initStubAdapter(const std::shared_ptr<TestInterfaceStubAdapter>& stubAdapter);
+
+    virtual const uint32_t& getTestPredefinedTypeAttributeAttribute();
+    void setTestPredefinedTypeAttributeAttribute(uint32_t value);
+
+    virtual const DerivedTypeCollection::TestStructExtended& getTestDerivedStructAttributeAttribute();
+    void setTestDerivedStructAttributeAttribute(DerivedTypeCollection::TestStructExtended value);
+
+    virtual const DerivedTypeCollection::TestArrayUInt64& getTestDerivedArrayAttributeAttribute();
+    void setTestDerivedArrayAttributeAttribute(DerivedTypeCollection::TestArrayUInt64 value);
+
+
+    virtual void testVoidPredefinedTypeMethod(uint32_t uint32Value, std::string stringValue);
+
+    virtual void testPredefinedTypeMethod(uint32_t uint32InValue, std::string stringInValue, uint32_t& uint32OutValue, std::string& stringOutValue);
+
+    virtual void testVoidDerivedTypeMethod(DerivedTypeCollection::TestEnumExtended2 testEnumExtended2Value, DerivedTypeCollection::TestMap testMapValue);
+
+    virtual void testDerivedTypeMethod(DerivedTypeCollection::TestEnumExtended2 testEnumExtended2InValue, DerivedTypeCollection::TestMap testMapInValue, DerivedTypeCollection::TestEnumExtended2& testEnumExtended2OutValue, DerivedTypeCollection::TestMap& testMapOutValue);
+
+    virtual void firePredefinedBroadcast(uint32_t value, std::string& sValue);
+
+ protected:
+    void onRemoteTestPredefinedTypeAttributeAttributeChanged();
+    bool trySetTestPredefinedTypeAttributeAttribute(uint32_t value);
+    bool validateTestPredefinedTypeAttributeAttributeRequestedValue(const uint32_t& value);
+
+    void onRemoteTestDerivedStructAttributeAttributeChanged();
+    bool trySetTestDerivedStructAttributeAttribute(DerivedTypeCollection::TestStructExtended value);
+    bool validateTestDerivedStructAttributeAttributeRequestedValue(const DerivedTypeCollection::TestStructExtended& value);
+
+    void onRemoteTestDerivedArrayAttributeAttributeChanged();
+    bool trySetTestDerivedArrayAttributeAttribute(DerivedTypeCollection::TestArrayUInt64 value);
+    bool validateTestDerivedArrayAttributeAttributeRequestedValue(const DerivedTypeCollection::TestArrayUInt64& value);
+
+
+ private:
+    class RemoteEventHandler: public TestInterfaceStubRemoteEvent {
+     public:
+        RemoteEventHandler(TestInterfaceStubDefault* defaultStub);
+
+        virtual bool onRemoteSetTestPredefinedTypeAttributeAttribute(uint32_t value);
+        virtual void onRemoteTestPredefinedTypeAttributeAttributeChanged();
+
+        virtual bool onRemoteSetTestDerivedStructAttributeAttribute(DerivedTypeCollection::TestStructExtended value);
+        virtual void onRemoteTestDerivedStructAttributeAttributeChanged();
+
+        virtual bool onRemoteSetTestDerivedArrayAttributeAttribute(DerivedTypeCollection::TestArrayUInt64 value);
+        virtual void onRemoteTestDerivedArrayAttributeAttributeChanged();
+
+
+     private:
+        TestInterfaceStubDefault* defaultStub_;
+    };
+
+    RemoteEventHandler remoteEventHandler_;
+    std::shared_ptr<TestInterfaceStubAdapter> stubAdapter_;
+
+    uint32_t testPredefinedTypeAttributeAttributeValue_;
+    DerivedTypeCollection::TestStructExtended testDerivedStructAttributeAttributeValue_;
+    DerivedTypeCollection::TestArrayUInt64 testDerivedArrayAttributeAttributeValue_;
+};
+
+} // namespace tests
+} // namespace commonapi
+
+#endif // COMMONAPI_TESTS_TEST_INTERFACE_STUB_DEFAULT_H_