diff --git a/Makefile.am b/Makefile.am index ca44ee6..c60c412 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,6 @@ -SUBDIRS = src tools data examples tests doc +SUBDIRS = src tools data doc + +EXTRA_DIST = TODO pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = dbus-c++-0.3.pc diff --git a/Makefile.in b/Makefile.in index 7139ae8..3739d1b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -40,7 +40,7 @@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/dbus-c++-0.3.pc.in \ $(top_srcdir)/configure \ $(top_srcdir)/include/dbus-c++/config.h.in AUTHORS COPYING \ - ChangeLog INSTALL NEWS config.guess config.sub depcomp \ + ChangeLog INSTALL NEWS TODO config.guess config.sub depcomp \ install-sh ltmain.sh missing mkinstalldirs subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -189,7 +189,8 @@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -SUBDIRS = src tools data examples tests doc +SUBDIRS = src tools data doc +EXTRA_DIST = TODO pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = dbus-c++-0.3.pc all: all-recursive diff --git a/SConscript b/SConscript index b3330ec..d7b2358 100644 --- a/SConscript +++ b/SConscript @@ -26,6 +26,7 @@ sources = [ 'src/eventloop.cpp', 'src/interface.cpp', 'src/introspection.cpp', + 'src/property.cpp', 'src/message.cpp', 'src/object.cpp', 'src/pendingcall.cpp', diff --git a/TODO b/TODO new file mode 100644 index 0000000..b9b6167 --- /dev/null +++ b/TODO @@ -0,0 +1,4 @@ +* Fix dbusxx-xml2cpp to generate client-side proxies +* Implement continuations in a saner way +* Find time for some hardcore valgrinding +* Correctly parse variants containing compound types diff --git a/autom4te.cache/output.1 b/autom4te.cache/output.1 index de05f62..7d688e8 100644 --- a/autom4te.cache/output.1 +++ b/autom4te.cache/output.1 @@ -19120,7 +19120,7 @@ echo "${ECHO_T}yes" >&6 # Save processed files - ac_config_files="$ac_config_files Makefile src/Makefile tools/Makefile data/Makefile doc/Makefile doc/Doxyfile doc/html/Makefile examples/Makefile tests/Makefile dbus-c++-0.3.pc" + ac_config_files="$ac_config_files Makefile src/Makefile tools/Makefile data/Makefile doc/Makefile doc/Doxyfile doc/html/Makefile dbus-c++-0.3.pc" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -19691,8 +19691,6 @@ do "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/Doxyfile" ) CONFIG_FILES="$CONFIG_FILES doc/Doxyfile" ;; "doc/html/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/html/Makefile" ;; - "examples/Makefile" ) CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; - "tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "dbus-c++-0.3.pc" ) CONFIG_FILES="$CONFIG_FILES dbus-c++-0.3.pc" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "include/dbus-c++/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/dbus-c++/config.h" ;; diff --git a/autom4te.cache/output.2 b/autom4te.cache/output.2 index 0c59623..8c84a62 100644 --- a/autom4te.cache/output.2 +++ b/autom4te.cache/output.2 @@ -19132,7 +19132,7 @@ echo "${ECHO_T}yes" >&6 # Save processed files - ac_config_files="$ac_config_files Makefile src/Makefile tools/Makefile data/Makefile doc/Makefile doc/Doxyfile doc/html/Makefile examples/Makefile tests/Makefile dbus-c++-0.3.pc" + ac_config_files="$ac_config_files Makefile src/Makefile tools/Makefile data/Makefile doc/Makefile doc/Doxyfile doc/html/Makefile dbus-c++-0.3.pc" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -19703,8 +19703,6 @@ do "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/Doxyfile" ) CONFIG_FILES="$CONFIG_FILES doc/Doxyfile" ;; "doc/html/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/html/Makefile" ;; - "examples/Makefile" ) CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; - "tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "dbus-c++-0.3.pc" ) CONFIG_FILES="$CONFIG_FILES dbus-c++-0.3.pc" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "include/dbus-c++/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/dbus-c++/config.h" ;; diff --git a/autom4te.cache/traces.1 b/autom4te.cache/traces.1 index ce5946b..fb8a975 100644 --- a/autom4te.cache/traces.1 +++ b/autom4te.cache/traces.1 @@ -424,18 +424,16 @@ m4trace:configure.ac:68: -1- AC_SUBST([DOXYGEN], [$ac_cv_path_DOXYGEN]) m4trace:configure.ac:88: -1- AM_CONDITIONAL([DBUS_DOXYGEN_DOCS_ENABLED], [test x$enable_doxygen_docs = xyes]) m4trace:configure.ac:88: -1- AC_SUBST([DBUS_DOXYGEN_DOCS_ENABLED_TRUE]) m4trace:configure.ac:88: -1- AC_SUBST([DBUS_DOXYGEN_DOCS_ENABLED_FALSE]) -m4trace:configure.ac:104: -1- AC_CONFIG_FILES([Makefile +m4trace:configure.ac:102: -1- AC_CONFIG_FILES([Makefile src/Makefile tools/Makefile data/Makefile doc/Makefile doc/Doxyfile doc/html/Makefile - examples/Makefile - tests/Makefile dbus-c++-0.3.pc ]) -m4trace:configure.ac:104: -1- _m4_warn([obsolete], [AC_OUTPUT should be used without arguments. +m4trace:configure.ac:102: -1- _m4_warn([obsolete], [AC_OUTPUT should be used without arguments. You should run autoupdate.], []) -m4trace:configure.ac:104: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs]) -m4trace:configure.ac:104: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs]) +m4trace:configure.ac:102: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs]) +m4trace:configure.ac:102: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs]) diff --git a/autom4te.cache/traces.2 b/autom4te.cache/traces.2 index 8dc7b6d..c28eae8 100644 --- a/autom4te.cache/traces.2 +++ b/autom4te.cache/traces.2 @@ -9320,20 +9320,18 @@ m4trace:configure.ac:68: -1- AC_SUBST([DOXYGEN], [$ac_cv_path_DOXYGEN]) m4trace:configure.ac:88: -1- AM_CONDITIONAL([DBUS_DOXYGEN_DOCS_ENABLED], [test x$enable_doxygen_docs = xyes]) m4trace:configure.ac:88: -1- AC_SUBST([DBUS_DOXYGEN_DOCS_ENABLED_TRUE]) m4trace:configure.ac:88: -1- AC_SUBST([DBUS_DOXYGEN_DOCS_ENABLED_FALSE]) -m4trace:configure.ac:104: -1- AC_CONFIG_FILES([Makefile +m4trace:configure.ac:102: -1- AC_CONFIG_FILES([Makefile src/Makefile tools/Makefile data/Makefile doc/Makefile doc/Doxyfile doc/html/Makefile - examples/Makefile - tests/Makefile dbus-c++-0.3.pc ]) -m4trace:configure.ac:104: -1- _m4_warn([obsolete], [AC_OUTPUT should be used without arguments. +m4trace:configure.ac:102: -1- _m4_warn([obsolete], [AC_OUTPUT should be used without arguments. You should run autoupdate.], []) -m4trace:configure.ac:104: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs]) -m4trace:configure.ac:104: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs]) -m4trace:configure.ac:104: -1- _AC_AM_CONFIG_HEADER_HOOK([$ac_file]) -m4trace:configure.ac:104: -1- _AM_OUTPUT_DEPENDENCY_COMMANDS +m4trace:configure.ac:102: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs]) +m4trace:configure.ac:102: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs]) +m4trace:configure.ac:102: -1- _AC_AM_CONFIG_HEADER_HOOK([$ac_file]) +m4trace:configure.ac:102: -1- _AM_OUTPUT_DEPENDENCY_COMMANDS diff --git a/configure b/configure index 335cc19..2a9d301 100755 --- a/configure +++ b/configure @@ -19120,7 +19120,7 @@ echo "${ECHO_T}yes" >&6 # Save processed files - ac_config_files="$ac_config_files Makefile src/Makefile tools/Makefile data/Makefile doc/Makefile doc/Doxyfile doc/html/Makefile examples/Makefile tests/Makefile dbus-c++-0.3.pc" + ac_config_files="$ac_config_files Makefile src/Makefile tools/Makefile data/Makefile doc/Makefile doc/Doxyfile doc/html/Makefile dbus-c++-0.3.pc" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -19691,8 +19691,6 @@ do "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/Doxyfile" ) CONFIG_FILES="$CONFIG_FILES doc/Doxyfile" ;; "doc/html/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/html/Makefile" ;; - "examples/Makefile" ) CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; - "tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "dbus-c++-0.3.pc" ) CONFIG_FILES="$CONFIG_FILES dbus-c++-0.3.pc" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "include/dbus-c++/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/dbus-c++/config.h" ;; diff --git a/configure.ac b/configure.ac index c787ce1..3552b6b 100644 --- a/configure.ac +++ b/configure.ac @@ -98,7 +98,5 @@ AC_OUTPUT( doc/Makefile doc/Doxyfile doc/html/Makefile - examples/Makefile - tests/Makefile dbus-c++-0.3.pc ) diff --git a/examples/Makefile.am b/examples/Makefile.am deleted file mode 100644 index 02323c9..0000000 --- a/examples/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -EXTRA_DIST = README - -INCLUDES = -I$(top_srcdir)/include - -noinst_PROGRAMS = echo_server - -echo_server_SOURCES = server.cpp server.h -echo_server_LDADD = $(top_builddir)/src/libdbus-c++-0.3.la diff --git a/examples/Makefile.in b/examples/Makefile.in deleted file mode 100644 index ab7c60a..0000000 --- a/examples/Makefile.in +++ /dev/null @@ -1,438 +0,0 @@ -# Makefile.in generated by automake 1.9.6 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -noinst_PROGRAMS = echo_server$(EXEEXT) -subdir = examples -DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/include/dbus-c++/config.h -CONFIG_CLEAN_FILES = -PROGRAMS = $(noinst_PROGRAMS) -am_echo_server_OBJECTS = server.$(OBJEXT) -echo_server_OBJECTS = $(am_echo_server_OBJECTS) -echo_server_DEPENDENCIES = $(top_builddir)/src/libdbus-c++-0.3.la -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include/dbus-c++ -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(echo_server_SOURCES) -DIST_SOURCES = $(echo_server_SOURCES) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMDEP_FALSE = @AMDEP_FALSE@ -AMDEP_TRUE = @AMDEP_TRUE@ -AMTAR = @AMTAR@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DBUS_DOXYGEN_DOCS_ENABLED_FALSE = @DBUS_DOXYGEN_DOCS_ENABLED_FALSE@ -DBUS_DOXYGEN_DOCS_ENABLED_TRUE = @DBUS_DOXYGEN_DOCS_ENABLED_TRUE@ -DEBUG_FLAGS = @DEBUG_FLAGS@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DOXYGEN = @DOXYGEN@ -ECHO = @ECHO@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -F77 = @F77@ -FFLAGS = @FFLAGS@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -RANLIB = @RANLIB@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_F77 = @ac_ct_F77@ -ac_ct_RANLIB = @ac_ct_RANLIB@ -ac_ct_STRIP = @ac_ct_STRIP@ -ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@ -am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ -am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ -am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ -am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -datadir = @datadir@ -dbus_CFLAGS = @dbus_CFLAGS@ -dbus_LIBS = @dbus_LIBS@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -xml_CFLAGS = @xml_CFLAGS@ -xml_LIBS = @xml_LIBS@ -EXTRA_DIST = README -INCLUDES = -I$(top_srcdir)/include -echo_server_SOURCES = server.cpp server.h -echo_server_LDADD = $(top_builddir)/src/libdbus-c++-0.3.la -all: all-am - -.SUFFIXES: -.SUFFIXES: .cpp .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu examples/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; for p in $$list; do \ - f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f $$p $$f"; \ - rm -f $$p $$f ; \ - done -echo_server$(EXEEXT): $(echo_server_OBJECTS) $(echo_server_DEPENDENCIES) - @rm -f echo_server$(EXEEXT) - $(CXXLINK) $(echo_server_LDFLAGS) $(echo_server_OBJECTS) $(echo_server_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Po@am__quote@ - -.cpp.o: -@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ -@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< - -.cpp.obj: -@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ -@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.cpp.lo: -@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ -@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkdir_p) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(PROGRAMS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-info-am - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstPROGRAMS ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-exec \ - install-exec-am install-info install-info-am install-man \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am \ - uninstall-info-am - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/examples/README b/examples/README deleted file mode 100644 index 0921454..0000000 --- a/examples/README +++ /dev/null @@ -1,11 +0,0 @@ -This is a very simple use case of the c++ wrappers to write a DBus service, you can test it by running ./echo_server and then issuing the following commands: - -dbus-send --dest=org.test.cbus --type=method_call --print-reply /org/test/cbus/EchoServer org.test.cbus.EchoServer.Echo string:"hello world" - -method return sender=:1.34 -> dest=:1.36 - string "hello world" - -dbus-send --dest=org.test.cbus --type=method_call --print-reply /org/test/cbus/EchoServer org.test.cbus.EchoServer.Echo int32:10 - -Error org.freedesktop.DBus.Error.InvalidArgs: String value expected - diff --git a/examples/server.cpp b/examples/server.cpp deleted file mode 100644 index dda9dc7..0000000 --- a/examples/server.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "server.h" -#include - - -class EchoServer : - public EchoInterface, - public DBus::IntrospectableAdaptor, - public DBus::ObjectAdaptor -{ -public: - EchoServer( DBus::Connection& conn ) : DBus::ObjectAdaptor(conn, "/org/test/cbus/EchoServer") - {} - - DBus::Message Echo( const DBus::CallMessage& msg ) - { - DBus::MessageIter r = msg.r_iter(); - - DBus::ReturnMessage ret(msg); - DBus::MessageIter w = ret.w_iter(); - - const char* string = r.get_string(); - - w.append_string(string); - - return ret; - } -}; - - -DBus::BusDispatcher dispatcher; - -void niam( int sig ) -{ - dispatcher.leave(); -} - -int main() -{ - signal(SIGTERM, niam); - signal(SIGINT, niam); - - DBus::default_dispatcher = &dispatcher; - - DBus::Connection conn = DBus::Connection::SessionBus(); - conn.request_name("org.test.cbus"); - - EchoServer server(conn); - - dispatcher.enter(); - - return 0; -} diff --git a/examples/server.h b/examples/server.h deleted file mode 100644 index 8e6a595..0000000 --- a/examples/server.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __ECHO_SERVER_H -#define __ECHO_SERVER_H - -#include - -class EchoInterface : - public DBus::InterfaceAdaptor -{ -public: - - EchoInterface() : DBus::InterfaceAdaptor("org.test.cbus.EchoServer") - { - register_method(EchoInterface, Echo, Echo); - } - - virtual DBus::Message Echo( const DBus::CallMessage& ) = 0; -}; - -#endif//__ECHO_SERVER_H diff --git a/include/dbus-c++/dbus-c++.h b/include/dbus-c++/dbus.h similarity index 92% rename from include/dbus-c++/dbus-c++.h rename to include/dbus-c++/dbus.h index eb26574..786192c 100644 --- a/include/dbus-c++/dbus-c++.h +++ b/include/dbus-c++/dbus.h @@ -22,12 +22,13 @@ */ -#ifndef __DBUSXX_DBUSXX_H -#define __DBUSXX_DBUSXX_H +#ifndef __DBUSXX_DBUS_H +#define __DBUSXX_DBUS_H #include "types.h" #include "interface.h" #include "object.h" +#include "property.h" #include "connection.h" #include "server.h" #include "error.h" @@ -41,4 +42,4 @@ #include "xml.h" #include "introspection.h" -#endif//__DBUSXX_DBUSXX_H +#endif//__DBUSXX_DBUS_H diff --git a/include/dbus-c++/error.h b/include/dbus-c++/error.h index 6e087c1..54f8430 100644 --- a/include/dbus-c++/error.h +++ b/include/dbus-c++/error.h @@ -51,16 +51,16 @@ public: const char* what() const throw(); - const char* name(); + const char* name() const; - const char* message(); + const char* message() const; void set( const char* name, const char* message ); // parameters MUST be static strings - bool is_set(); + bool is_set() const; - operator bool() + operator bool() const { return is_set(); } @@ -224,7 +224,61 @@ struct ErrorMatchRuleInvalid : public Error {} }; -/* TODO: add the remaining error codes from dbus-protocol.h */ +struct ErrorSpawnExecFailed : public Error +{ + ErrorSpawnExecFailed( const char* message ) + : Error("org.freedesktop.DBus.Error.Spawn.ExecFailed", message) + {} +}; + +struct ErrorSpawnForkFailed : public Error +{ + ErrorSpawnForkFailed( const char* message ) + : Error("org.freedesktop.DBus.Error.Spawn.ForkFailed", message) + {} +}; + +struct ErrorSpawnChildExited : public Error +{ + ErrorSpawnChildExited( const char* message ) + : Error("org.freedesktop.DBus.Error.Spawn.ChildExited", message) + {} +}; + +struct ErrorSpawnChildSignaled : public Error +{ + ErrorSpawnChildSignaled( const char* message ) + : Error("org.freedesktop.DBus.Error.Spawn.ChildSignaled", message) + {} +}; + +struct ErrorSpawnFailed : public Error +{ + ErrorSpawnFailed( const char* message ) + : Error("org.freedesktop.DBus.Error.Spawn.Failed", message) + {} +}; + +struct ErrorInvalidSignature : public Error +{ + ErrorInvalidSignature( const char* message ) + : Error("org.freedesktop.DBus.Error.InvalidSignature", message) + {} +}; + +struct ErrorUnixProcessIdUnknown : public Error +{ + ErrorUnixProcessIdUnknown( const char* message ) + : Error("org.freedesktop.DBus.Error.UnixProcessIdUnknown", message) + {} +}; + +struct ErrorSELinuxSecurityContextUnknown : public Error +{ + ErrorSELinuxSecurityContextUnknown( const char* message ) + : Error("org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown", message) + {} +}; } /* namespace DBus */ diff --git a/include/dbus-c++/interface.h b/include/dbus-c++/interface.h index eba1bcd..7f9dece 100644 --- a/include/dbus-c++/interface.h +++ b/include/dbus-c++/interface.h @@ -28,77 +28,94 @@ #include #include #include "util.h" +#include "types.h" #include "message.h" namespace DBus { -class Interface; -class IfaceTracker; +//todo: this should belong to to properties.h +struct PropertyData +{ + bool read; + bool write; + Variant value; +}; -typedef std::map InterfaceTable; - -class Object; - -class CallMessage; -class SignalMessage; +typedef std::map PropertyTable; class IntrospectedInterface; -class IfaceTracker +class ObjectAdaptor; +class InterfaceAdaptor; +class SignalMessage; + +typedef std::map InterfaceAdaptorTable; + +class AdaptorBase { public: - virtual const Object* object() const = 0 ; + virtual const ObjectAdaptor* object() const = 0 ; protected: - InterfaceTable _interfaces; + InterfaceAdaptor* find_interface( const std::string& name ); - virtual ~IfaceTracker() + virtual ~AdaptorBase() {} - virtual void remit_signal( SignalMessage& ) - {} + virtual void _emit_signal( SignalMessage& ) = 0; - virtual Message rinvoke_method( CallMessage& ); -}; - -typedef std::map< std::string, Slot > MethodTable; -typedef std::map< std::string, Slot > SignalTable; - -class Interface : public virtual IfaceTracker -{ -public: - - Interface( const char* name ); - - virtual ~Interface(); - - inline const std::string& iname() const; - - virtual Message invoke_method( const CallMessage& ); - - virtual bool dispatch_signal( const SignalMessage& ); - - virtual IntrospectedInterface* const introspect() const - { - return NULL; - } - -private: - - void register_interface( const char* name ); - -private: - - std::string _name; + InterfaceAdaptorTable _interfaces; }; /* */ -const std::string& Interface::iname() const +class ObjectProxy; +class InterfaceProxy; +class CallMessage; + +typedef std::map InterfaceProxyTable; + +class ProxyBase +{ +public: + + virtual const ObjectProxy* object() const = 0 ; + +protected: + + InterfaceProxy* find_interface( const std::string& name ); + + virtual ~ProxyBase() + {} + + virtual Message _invoke_method( CallMessage& ) = 0; + + InterfaceProxyTable _interfaces; +}; + +class Interface +{ +public: + + Interface( const std::string& name ); + + virtual ~Interface(); + + inline const std::string& name() const; + +private: + + std::string _name; +}; + +/* +*/ + +const std::string& Interface::name() const { return _name; } @@ -106,29 +123,43 @@ const std::string& Interface::iname() const /* */ -class InterfaceAdaptor : public Interface +typedef std::map< std::string, Slot > MethodTable; + +class InterfaceAdaptor : public Interface, public virtual AdaptorBase { public: - InterfaceAdaptor( const char* name ); + InterfaceAdaptor( const std::string& name ); - Message invoke_method( const CallMessage& ); + Message dispatch_method( const CallMessage& ); void emit_signal( const SignalMessage& ); + Variant* get_property( const std::string& name ); + + bool set_property( const std::string& name, Variant& value ); + + virtual IntrospectedInterface* const introspect() const + { + return NULL; + } + protected: MethodTable _methods; + PropertyTable _properties; }; /* */ -class InterfaceProxy : public Interface +typedef std::map< std::string, Slot > SignalTable; + +class InterfaceProxy : public Interface, public virtual ProxyBase { public: - InterfaceProxy( const char* name ); + InterfaceProxy( const std::string& name ); Message invoke_method( const CallMessage& ); @@ -141,11 +172,16 @@ protected: # define register_method(interface, method, callback) \ InterfaceAdaptor::_methods[ #method ] = \ - new DBus::Callback< interface, DBus::Message, const DBus::CallMessage& >(this, & interface :: callback ); + new ::DBus::Callback< interface, ::DBus::Message, const ::DBus::CallMessage& >(this, & interface :: callback ); + +# define bind_property(variable, can_read, can_write) \ + InterfaceAdaptor::_properties[ #variable ].read = can_read; \ + InterfaceAdaptor::_properties[ #variable ].write = can_write; \ + variable.bind( InterfaceAdaptor::_properties[ #variable ] ); -# define connect_signal(interface, signal) \ +# define connect_signal(interface, signal, callback) \ InterfaceProxy::_signals[ #signal ] = \ - new DBus::Callback< interface, void, const DBus::SignalMessage& >(this, & interface :: method ); + new ::DBus::Callback< interface, void, const ::DBus::SignalMessage& >(this, & interface :: callback ); } /* namespace DBus */ diff --git a/include/dbus-c++/introspection.h b/include/dbus-c++/introspection.h index 0d5af66..ab474c3 100644 --- a/include/dbus-c++/introspection.h +++ b/include/dbus-c++/introspection.h @@ -42,11 +42,20 @@ struct IntrospectedMethod const IntrospectedArgument* args; }; +struct IntrospectedProperty +{ + const char* name; + const char* type; + const bool read; + const bool write; +}; + struct IntrospectedInterface { const char* name; const IntrospectedMethod* methods; const IntrospectedMethod* signals; + const IntrospectedProperty* properties; }; class IntrospectableAdaptor : public InterfaceAdaptor diff --git a/include/dbus-c++/message.h b/include/dbus-c++/message.h index 1c22ed1..5ebccfd 100644 --- a/include/dbus-c++/message.h +++ b/include/dbus-c++/message.h @@ -125,10 +125,12 @@ public: MessageIter new_variant( const char* sig ); - MessageIter new_struct( const char* sig ); + MessageIter new_struct(); void close_container( MessageIter& container ); + void copy_data( MessageIter& to ); + Message& msg() const { return *_msg; @@ -187,9 +189,9 @@ public: bool is_signal( const char* interface, const char* member ) const; - MessageIter r_iter() const; + MessageIter reader() const; - MessageIter w_iter(); + MessageIter writer(); bool append( int first_type, ... ); diff --git a/include/dbus-c++/object.h b/include/dbus-c++/object.h index 46064d0..79ad167 100644 --- a/include/dbus-c++/object.h +++ b/include/dbus-c++/object.h @@ -27,7 +27,6 @@ #include #include -#include #include "interface.h" #include "connection.h" @@ -36,19 +35,11 @@ namespace DBus { -class Object; - -typedef std::list ObjectPList; - -class ObjectAdaptor; - -class ObjectProxy; - -class Object : protected virtual IfaceTracker +class Object { protected: - Object( Connection& conn, const char* path, const char* service ); + Object( Connection& conn, const Path& path, const char* service ); public: @@ -57,15 +48,11 @@ public: inline const DBus::Path& path() const; inline const std::string& service() const; - - inline const Object* object() const; inline Connection& conn(); private: - //Object( const Object& ); - virtual bool handle_message( const Message& ) = 0; virtual void register_obj() = 0; virtual void unregister_obj() = 0; @@ -80,11 +67,6 @@ private: /* */ -const Object* Object::object() const -{ - return this; -} - Connection& Object::conn() { return _conn; @@ -103,21 +85,29 @@ const std::string& Object::service() const /* */ -class ObjectAdaptor : public Object +class ObjectAdaptor; + +typedef std::list ObjectAdaptorPList; + +class ObjectAdaptor : public Object, public virtual AdaptorBase { public: + static ObjectAdaptor* from_path( const Path& path ); + + static ObjectAdaptorPList from_path_prefix( const std::string& prefix ); + struct Private; - ObjectAdaptor( Connection& conn, const char* path ); + ObjectAdaptor( Connection& conn, const Path& path ); ~ObjectAdaptor(); - void remit_signal( SignalMessage& ); + inline const ObjectAdaptor* object() const; protected: - class DeferredReturn + class Continuation { public: @@ -127,7 +117,7 @@ protected: private: - DeferredReturn( Connection& conn, const CallMessage& call, const void* tag ); + Continuation( Connection& conn, const CallMessage& call, const void* tag ); Connection _conn; CallMessage _call; @@ -140,31 +130,38 @@ protected: void return_later( const void* tag ); - void return_now( DeferredReturn* ret ); + void return_now( Continuation* ret ); - void return_error( DeferredReturn* ret, Error& error ); + void return_error( Continuation* ret, const Error error ); - DeferredReturn* find_return( const void* tag ); + Continuation* find_continuation( const void* tag ); private: + void _emit_signal( SignalMessage& ); + bool handle_message( const Message& ); void register_obj(); void unregister_obj(); - typedef std::map DeferredReturnMap; - DeferredReturnMap _deferred_returns; + typedef std::map ContinuationMap; + ContinuationMap _continuations; friend struct Private; }; -void* ObjectAdaptor::DeferredReturn::tag() +const ObjectAdaptor* ObjectAdaptor::object() const +{ + return this; +} + +void* ObjectAdaptor::Continuation::tag() { return const_cast(_tag); } -MessageIter& ObjectAdaptor::DeferredReturn::writer() +MessageIter& ObjectAdaptor::Continuation::writer() { return _writer; } @@ -172,18 +169,24 @@ MessageIter& ObjectAdaptor::DeferredReturn::writer() /* */ -class ObjectProxy : public Object +class ObjectProxy; + +typedef std::list ObjectProxyPList; + +class ObjectProxy : public Object, public virtual ProxyBase { public: - ObjectProxy( Connection& conn, const char* path, const char* service = "" ); + ObjectProxy( Connection& conn, const Path& path, const char* service = "" ); ~ObjectProxy(); - Message rinvoke_method( CallMessage& ); + inline const ObjectProxy* object() const; private: + Message _invoke_method( CallMessage& ); + bool handle_message( const Message& ); void register_obj(); @@ -194,6 +197,11 @@ private: MessageSlot _filtered; }; +const ObjectProxy* ObjectProxy::object() const +{ + return this; +} + } /* namespace DBus */ #endif//__DBUSXX_OBJECT_H diff --git a/include/dbus-c++/property.h b/include/dbus-c++/property.h new file mode 100644 index 0000000..ac1f0c2 --- /dev/null +++ b/include/dbus-c++/property.h @@ -0,0 +1,104 @@ +/* + * + * D-Bus++ - C++ bindings for DBus + * + * Copyright (C) 2005-2006 Paolo Durante + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __DBUSXX_PROPERTY_H +#define __DBUSXX_PROPERTY_H + +#include "types.h" +#include "interface.h" + +namespace DBus { + +template +class PropertyAdaptor +{ +public: + + PropertyAdaptor() : _data(0) + {} + + void bind( PropertyData& data ) + { + _data = &data; + } + + T operator() (void) const + { + T t; + MessageIter ri = _data->value.reader(); + ri >> t; + return t; + } + + PropertyAdaptor& operator = ( const T& t ) + { + _data->value.clear(); + MessageIter wi = _data->value.writer(); + wi << t; + return *this; + } + +private: + + PropertyData* _data; +}; + +struct IntrospectedInterface; + +class PropertiesAdaptor : public InterfaceAdaptor +{ +public: + + PropertiesAdaptor(); + + Message Get( const CallMessage& ); + + Message Set( const CallMessage& ); + +protected: + + virtual void on_get_property( InterfaceAdaptor& interface, const String& property, Variant& value ) + {} + + virtual void on_set_property( InterfaceAdaptor& interface, const String& property, const Variant& value ) + {} + + IntrospectedInterface* const introspect() const; +}; + +class PropertiesProxy : public InterfaceProxy +{ +public: + + PropertiesProxy(); + + Variant Get( const String& interface, const String& property ); + + void Set( const String& interface, const String& property, const Variant& value ); +}; + +} /* namespace DBus */ + +#endif//__DBUSXX_PROPERTY_H + diff --git a/include/dbus-c++/types.h b/include/dbus-c++/types.h index d1d0a43..19b3ab2 100644 --- a/include/dbus-c++/types.h +++ b/include/dbus-c++/types.h @@ -49,6 +49,7 @@ typedef std::string String; struct Path : public std::string { Path() {} + Path( const std::string& s ) : std::string(s) {} Path( const char* c ) : std::string(c) {} Path& operator = ( std::string& s ) { @@ -60,6 +61,7 @@ struct Path : public std::string struct Signature : public std::string { Signature() {} + Signature( const std::string& s ) : std::string(s) {} Signature( const char* c ) : std::string(c) {} Signature& operator = ( std::string& s ) { @@ -80,30 +82,23 @@ public: Variant& operator = ( const Variant& v ); - const char* signature() const; + const Signature signature() const; - MessageIter iter() const + void clear(); + + MessageIter reader() const { - return _it; + return _msg.reader(); + } + + MessageIter writer() + { + return _msg.writer(); } private: Message _msg; - MessageIter _it; - mutable Signature _signature; -}; - -template -struct Array : public std::vector {}; - -template -struct Dict : public std::map -{ - bool has_key( const K& key ) const - { - return this->find(key) != this->end(); - } }; template < @@ -131,19 +126,19 @@ struct type } }; -template <> struct type { static std::string sig(){ return "y"; } }; -template <> struct type { static std::string sig(){ return "b"; } }; -template <> struct type { static std::string sig(){ return "n"; } }; -template <> struct type { static std::string sig(){ return "q"; } }; -template <> struct type { static std::string sig(){ return "i"; } }; -template <> struct type { static std::string sig(){ return "u"; } }; -template <> struct type { static std::string sig(){ return "x"; } }; -template <> struct type { static std::string sig(){ return "t"; } }; -template <> struct type { static std::string sig(){ return "d"; } }; -template <> struct type { static std::string sig(){ return "s"; } }; -template <> struct type { static std::string sig(){ return "o"; } }; -template <> struct type { static std::string sig(){ return "g"; } }; -template <> struct type { static std::string sig(){ return ""; } }; +template <> struct type { static std::string sig(){ return "y"; } }; +template <> struct type { static std::string sig(){ return "b"; } }; +template <> struct type { static std::string sig(){ return "n"; } }; +template <> struct type { static std::string sig(){ return "q"; } }; +template <> struct type { static std::string sig(){ return "i"; } }; +template <> struct type { static std::string sig(){ return "u"; } }; +template <> struct type { static std::string sig(){ return "x"; } }; +template <> struct type { static std::string sig(){ return "t"; } }; +template <> struct type { static std::string sig(){ return "d"; } }; +template <> struct type { static std::string sig(){ return "s"; } }; +template <> struct type { static std::string sig(){ return "o"; } }; +template <> struct type { static std::string sig(){ return "g"; } }; +template <> struct type { static std::string sig(){ return ""; } }; template struct type< std::vector > @@ -315,11 +310,11 @@ template < > inline DBus::MessageIter& operator << ( DBus::MessageIter& iter, const DBus::Struct& val ) { - const std::string sig = +/* const std::string sig = DBus::type::sig() + DBus::type::sig() + DBus::type::sig() + DBus::type::sig() + DBus::type::sig() + DBus::type::sig() + DBus::type::sig() + DBus::type::sig(); - - DBus::MessageIter sit = iter.new_struct(sig.c_str()); +*/ + DBus::MessageIter sit = iter.new_struct(/*sig.c_str()*/); sit << val._1 << val._2 << val._3 << val._4 << val._5 << val._6 << val._7 << val._8; diff --git a/src/Makefile.am b/src/Makefile.am index 91223d6..de13f54 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,9 +4,10 @@ AM_CPPFLAGS = -DDBUS_API_SUBJECT_TO_CHANGE HEADER_DIR = $(top_srcdir)/include/dbus-c++ HEADER_FILES = \ $(HEADER_DIR)/config.h \ - $(HEADER_DIR)/dbus-c++.h \ + $(HEADER_DIR)/dbus.h \ $(HEADER_DIR)/types.h \ $(HEADER_DIR)/connection.h \ + $(HEADER_DIR)/property.h \ $(HEADER_DIR)/debug.h \ $(HEADER_DIR)/error.h \ $(HEADER_DIR)/interface.h \ @@ -26,5 +27,5 @@ lib_includedir=$(includedir)/dbus-c++-0.3/dbus-c++ lib_include_HEADERS = $(HEADER_FILES) lib_LTLIBRARIES = libdbus-c++-0.3.la -libdbus_c___0_3_la_SOURCES = $(HEADER_FILES) interface.cpp object.cpp introspection.cpp debug.cpp eventloop.cpp xml.cpp types.cpp connection.cpp connection_p.h dispatcher.cpp dispatcher_p.h pendingcall.cpp pendingcall_p.h error.cpp internalerror.h message.cpp message_p.h server.cpp server_p.h +libdbus_c___0_3_la_SOURCES = $(HEADER_FILES) interface.cpp object.cpp introspection.cpp debug.cpp eventloop.cpp xml.cpp types.cpp connection.cpp connection_p.h property.cpp dispatcher.cpp dispatcher_p.h pendingcall.cpp pendingcall_p.h error.cpp internalerror.h message.cpp message_p.h server.cpp server_p.h libdbus_c___0_3_la_LIBADD = $(dbus_LIBS) $(xml_LIBS) diff --git a/src/Makefile.in b/src/Makefile.in index d16d2ed..adc8e6e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -62,8 +62,8 @@ libdbus_c___0_3_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ am__objects_1 = am_libdbus_c___0_3_la_OBJECTS = $(am__objects_1) interface.lo \ object.lo introspection.lo debug.lo eventloop.lo xml.lo \ - types.lo connection.lo dispatcher.lo pendingcall.lo error.lo \ - message.lo server.lo + types.lo connection.lo property.lo dispatcher.lo \ + pendingcall.lo error.lo message.lo server.lo libdbus_c___0_3_la_OBJECTS = $(am_libdbus_c___0_3_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include/dbus-c++ depcomp = $(SHELL) $(top_srcdir)/depcomp @@ -202,9 +202,10 @@ AM_CPPFLAGS = -DDBUS_API_SUBJECT_TO_CHANGE HEADER_DIR = $(top_srcdir)/include/dbus-c++ HEADER_FILES = \ $(HEADER_DIR)/config.h \ - $(HEADER_DIR)/dbus-c++.h \ + $(HEADER_DIR)/dbus.h \ $(HEADER_DIR)/types.h \ $(HEADER_DIR)/connection.h \ + $(HEADER_DIR)/property.h \ $(HEADER_DIR)/debug.h \ $(HEADER_DIR)/error.h \ $(HEADER_DIR)/interface.h \ @@ -223,7 +224,7 @@ HEADER_FILES = \ lib_includedir = $(includedir)/dbus-c++-0.3/dbus-c++ lib_include_HEADERS = $(HEADER_FILES) lib_LTLIBRARIES = libdbus-c++-0.3.la -libdbus_c___0_3_la_SOURCES = $(HEADER_FILES) interface.cpp object.cpp introspection.cpp debug.cpp eventloop.cpp xml.cpp types.cpp connection.cpp connection_p.h dispatcher.cpp dispatcher_p.h pendingcall.cpp pendingcall_p.h error.cpp internalerror.h message.cpp message_p.h server.cpp server_p.h +libdbus_c___0_3_la_SOURCES = $(HEADER_FILES) interface.cpp object.cpp introspection.cpp debug.cpp eventloop.cpp xml.cpp types.cpp connection.cpp connection_p.h property.cpp dispatcher.cpp dispatcher_p.h pendingcall.cpp pendingcall_p.h error.cpp internalerror.h message.cpp message_p.h server.cpp server_p.h libdbus_c___0_3_la_LIBADD = $(dbus_LIBS) $(xml_LIBS) all: all-am @@ -304,6 +305,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pendingcall.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/property.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/types.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml.Plo@am__quote@ diff --git a/src/connection.cpp b/src/connection.cpp index fdaabfc..2a06d26 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -307,7 +307,7 @@ PendingCall Connection::send_async( Message& msg, int timeout ) if(!dbus_connection_send_with_reply(_pvt->conn, msg._pvt->msg, &pending, timeout)) { - throw Error(DBUS_ERROR_NO_MEMORY, "Unable to start asynchronous call"); + throw ErrorNoMemory("Unable to start asynchronous call"); } return PendingCall(new PendingCall::Private(pending)); } diff --git a/src/error.cpp b/src/error.cpp index c4c6c1a..b6e1b62 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -55,17 +55,17 @@ Error::Error( Message& m ) dbus_set_error_from_message(&(_int->error), m._pvt->msg); } -const char* Error::name() +const char* Error::name() const { return _int->error.name; } -const char* Error::message() +const char* Error::message() const { return _int->error.message; } -bool Error::is_set() +bool Error::is_set() const { return *(_int); } diff --git a/src/eventloop.cpp b/src/eventloop.cpp index 2c9abe1..270311b 100644 --- a/src/eventloop.cpp +++ b/src/eventloop.cpp @@ -111,8 +111,9 @@ void EepleMainLoop::dispatch() int wait_min = 10000; - Timeouts::iterator ti = _timeouts.begin(); - for(;ti != _timeouts.end(); ++ti) + Timeouts::iterator ti; + + for(ti = _timeouts.begin(); ti != _timeouts.end(); ++ti) { if((*ti)->enabled() && (*ti)->interval() < wait_min) wait_min = (*ti)->interval(); @@ -151,7 +152,9 @@ void EepleMainLoop::dispatch() for(int j = 0; j < nfd; ++j) { - for(Watches::iterator wi = _watches.begin(); wi != _watches.end();) + Watches::iterator wi; + + for(wi = _watches.begin(); wi != _watches.end();) { Watches::iterator tmp = wi; ++tmp; diff --git a/src/interface.cpp b/src/interface.cpp index b723a54..f982641 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -29,44 +29,29 @@ using namespace DBus; -Message IfaceTracker::rinvoke_method( CallMessage& msg ) -{ - return ErrorMessage(msg, DBUS_ERROR_NOT_SUPPORTED, "there are no proxies in a InterfaceAdaptor"); -} - -Interface::Interface( const char* name ) -: _name(name) -{ - register_interface(name); -} +Interface::Interface( const std::string& name ) +: _name(name) +{} Interface::~Interface() +{} + +InterfaceAdaptor* AdaptorBase::find_interface( const std::string& name ) { - //unregister_interface(name); //not needed + InterfaceAdaptorTable::const_iterator ii = _interfaces.find(name); + + return ii != _interfaces.end() ? ii->second : NULL; } -Message Interface::invoke_method( const CallMessage& ) +InterfaceAdaptor::InterfaceAdaptor( const std::string& name ) +: Interface(name) { - throw Error(DBUS_ERROR_NOT_SUPPORTED, ""); -} - -bool Interface::dispatch_signal( const SignalMessage& ) -{ - throw Error(DBUS_ERROR_NOT_SUPPORTED, ""); -} - -void Interface::register_interface( const char* name ) -{ - debug_log("registering interface %s",name); + debug_log("adding interface %s", name.c_str()); _interfaces[name] = this; } -InterfaceAdaptor::InterfaceAdaptor( const char* name ) -: Interface(name) -{} - -Message InterfaceAdaptor::invoke_method( const CallMessage& msg ) +Message InterfaceAdaptor::dispatch_method( const CallMessage& msg ) { const char* name = msg.member(); @@ -85,13 +70,53 @@ void InterfaceAdaptor::emit_signal( const SignalMessage& sig ) { SignalMessage& sig2 = const_cast(sig); - sig2.interface( iname().c_str() ); - remit_signal(sig2); + sig2.interface( name().c_str() ); + _emit_signal(sig2); } -InterfaceProxy::InterfaceProxy( const char* name ) -: Interface(name) -{} +Variant* InterfaceAdaptor::get_property( const std::string& name ) +{ + PropertyTable::iterator pti = _properties.find(name); + + if( pti != _properties.end() ) + { + if( !pti->second.read ) + throw ErrorAccessDenied("property is not readable"); + + return &(pti->second.value); + } + return NULL; +} + +bool InterfaceAdaptor::set_property( const std::string& name, Variant& value ) +{ + PropertyTable::iterator pti = _properties.find(name); + + if( pti != _properties.end() ) + { + if( !pti->second.write ) + throw ErrorAccessDenied("property is not writeable"); + + pti->second.value = value; + return true; + } + return false; +} + +InterfaceProxy* ProxyBase::find_interface( const std::string& name ) +{ + InterfaceProxyTable::const_iterator ii = _interfaces.find(name); + + return ii != _interfaces.end() ? ii->second : NULL; +} + +InterfaceProxy::InterfaceProxy( const std::string& name ) +: Interface(name) +{ + debug_log("adding interface %s", name.c_str()); + + _interfaces[name] = this; +} bool InterfaceProxy::dispatch_signal( const SignalMessage& msg ) { @@ -113,6 +138,6 @@ Message InterfaceProxy::invoke_method( const CallMessage& call ) { CallMessage& call2 = const_cast(call); - call2.interface( iname().c_str() ); - return rinvoke_method(call2); + call2.interface( name().c_str() ); + return _invoke_method(call2); } diff --git a/src/introspection.cpp b/src/introspection.cpp index cc98cc9..1af868a 100644 --- a/src/introspection.cpp +++ b/src/introspection.cpp @@ -23,6 +23,7 @@ #include +#include #include #include @@ -44,7 +45,7 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call ) Xml::Node iroot("node"); - InterfaceTable::const_iterator iti; + InterfaceAdaptorTable::const_iterator iti; for(iti = _interfaces.begin(); iti != _interfaces.end(); ++iti) { @@ -56,6 +57,20 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call ) Xml::Node& iface = iroot.add(Xml::Node("interface")); iface.set("name", intro->name); + for(const IntrospectedProperty* p = intro->properties; p->name; ++p) + { + Xml::Node& property = iface.add(Xml::Node("property")); + property.set("name", p->name); + property.set("type", p->type); + + std::string access; + + if(p->read) access += "read"; + if(p->write) access += "write"; + + property.set("access", access); + } + for(const IntrospectedMethod* m = intro->methods; m->args; ++m) { Xml::Node& method = iface.add(Xml::Node("method")); @@ -84,10 +99,25 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call ) } } } + const std::string parent = object()->path(); + const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(parent + '/'); + + ObjectAdaptorPList::const_iterator oci; + + for(oci = children.begin(); oci != children.end(); ++oci) + { + Xml::Node& subnode = iroot.add(Xml::Node("node")); + + std::string name = (*oci)->path().substr(parent.length()+1); + name.substr(name.find('/')); + + subnode.set("name", name); + } + std::string xml = DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + iroot.to_xml(); ReturnMessage reply(call); - MessageIter wi = reply.w_iter(); + MessageIter wi = reply.writer(); wi.append_string(xml.c_str()); return reply; } @@ -108,9 +138,16 @@ IntrospectedInterface* const IntrospectableAdaptor::introspect() const { { 0, 0 } }; + static IntrospectedProperty Introspectable_properties[] = + { + { 0, 0, 0, 0 } + }; static IntrospectedInterface Introspectable_interface = { - introspectable_name, Introspectable_methods, Introspectable_signals + introspectable_name, + Introspectable_methods, + Introspectable_signals, + Introspectable_properties }; return &Introspectable_interface; } @@ -127,7 +164,7 @@ std::string IntrospectableProxy::Introspect() DBus::Message ret = invoke_method(call); - DBus::MessageIter ri = ret.r_iter(); + DBus::MessageIter ri = ret.reader(); const char* str = ri.get_string(); return str; diff --git a/src/message.cpp b/src/message.cpp index 34223c3..36ddeb6 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -67,7 +67,7 @@ bool MessageIter::append_basic( int type_id, void* value ) void MessageIter::get_basic( int type_id, void* ptr ) { if(type() != type_id) - throw Error(DBUS_ERROR_INVALID_ARGS, "type mismatch"); + throw ErrorInvalidArgs("type mismatch"); dbus_message_iter_get_basic((DBusMessageIter*)_iter, ptr); } @@ -287,11 +287,11 @@ MessageIter MessageIter::new_variant( const char* sig ) return var; } -MessageIter MessageIter::new_struct( const char* sig ) +MessageIter MessageIter::new_struct() { MessageIter stu(msg()); dbus_message_iter_open_container( - (DBusMessageIter*)_iter, DBUS_TYPE_STRUCT, sig, (DBusMessageIter*)&(stu._iter) + (DBusMessageIter*)_iter, DBUS_TYPE_STRUCT, 0, (DBusMessageIter*)&(stu._iter) ); return stu; } @@ -301,6 +301,56 @@ void MessageIter::close_container( MessageIter& container ) dbus_message_iter_close_container((DBusMessageIter*)&_iter, (DBusMessageIter*)&(container._iter)); } +void MessageIter::copy_data( MessageIter& to ) +{ + for(MessageIter from = *this; from.at_end(); ++from) + { + switch(from.type()) + { + case DBUS_TYPE_BYTE: + case DBUS_TYPE_BOOLEAN: + case DBUS_TYPE_INT16: + case DBUS_TYPE_UINT16: + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: + case DBUS_TYPE_INT64: + case DBUS_TYPE_UINT64: + case DBUS_TYPE_DOUBLE: + case DBUS_TYPE_STRING: + case DBUS_TYPE_OBJECT_PATH: + case DBUS_TYPE_SIGNATURE: + { + unsigned char value[8]; + from.get_basic(from.type(), &value); + to.append_basic(from.type(), &value); + break; + } + case DBUS_TYPE_ARRAY: + case DBUS_TYPE_VARIANT: + case DBUS_TYPE_STRUCT: + case DBUS_TYPE_DICT_ENTRY: + { + MessageIter from_container = from.recurse(); + char* sig = from_container.signature(); + + MessageIter to_container(to.msg()); + dbus_message_iter_open_container + ( + (DBusMessageIter*)&(to._iter), + from.type(), + sig, + (DBusMessageIter*)&(to_container._iter) + ); + + from_container.copy_data(to_container); + to.close_container(to_container); + free(sig); + break; + } + } + } +} + /* */ @@ -398,14 +448,14 @@ bool Message::is_signal( const char* interface, const char* member ) const return dbus_message_is_signal(_pvt->msg, interface, member); } -MessageIter Message::w_iter() +MessageIter Message::writer() { MessageIter iter(*this); dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter*)&(iter._iter)); return iter; } -MessageIter Message::r_iter() const +MessageIter Message::reader() const { MessageIter iter(const_cast(*this)); dbus_message_iter_init(_pvt->msg, (DBusMessageIter*)&(iter._iter)); diff --git a/src/object.cpp b/src/object.cpp index d671d0a..0cf3381 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -26,6 +26,7 @@ #include #include "internalerror.h" +#include #include #include "message_p.h" @@ -33,7 +34,7 @@ using namespace DBus; -Object::Object( Connection& conn, const char* path, const char* service ) +Object::Object( Connection& conn, const Path& path, const char* service ) : _conn(conn), _path(path), _service(service ? service : "") { } @@ -57,7 +58,7 @@ static DBusObjectPathVTable _vtable = void ObjectAdaptor::Private::unregister_function_stub( DBusConnection* conn, void* data ) { - // XXX: what do we have to do here ? + //TODO: what do we have to do here ? } DBusHandlerResult ObjectAdaptor::Private::message_function_stub( DBusConnection*, DBusMessage* dmsg, void* data ) @@ -85,7 +86,39 @@ DBusHandlerResult ObjectAdaptor::Private::message_function_stub( DBusConnection* } } -ObjectAdaptor::ObjectAdaptor( Connection& conn, const char* path ) +typedef std::map ObjectAdaptorTable; +static ObjectAdaptorTable _adaptor_table; + +ObjectAdaptor* ObjectAdaptor::from_path( const Path& path ) +{ + ObjectAdaptorTable::iterator ati = _adaptor_table.find(path); + + if(ati != _adaptor_table.end()) + return ati->second; + + return NULL; +} + +ObjectAdaptorPList ObjectAdaptor::from_path_prefix( const std::string& prefix ) +{ + ObjectAdaptorPList ali; + + ObjectAdaptorTable::iterator ati = _adaptor_table.begin(); + + size_t plen = prefix.length(); + + while(ati != _adaptor_table.end()) + { + if(!strncmp(ati->second->path().c_str(), prefix.c_str(), plen)) + ali.push_back(ati->second); + + ++ati; + } + + return ali; +} + +ObjectAdaptor::ObjectAdaptor( Connection& conn, const Path& path ) : Object(conn, path, conn.unique_name()) { register_obj(); @@ -102,11 +135,11 @@ void ObjectAdaptor::register_obj() if(!dbus_connection_register_object_path(conn()._pvt->conn, path().c_str(), &_vtable, this)) { - throw Error(DBUS_ERROR_NO_MEMORY,"unable to register object path"); + throw ErrorNoMemory("unable to register object path"); } else { - InterfaceTable::const_iterator ii = _interfaces.begin(); + InterfaceAdaptorTable::const_iterator ii = _interfaces.begin(); while( ii != _interfaces.end() ) { std::string im = "type='method_call',interface='"+ii->first+"'"; @@ -114,15 +147,19 @@ void ObjectAdaptor::register_obj() ++ii; } } + + _adaptor_table[path()] = this; } void ObjectAdaptor::unregister_obj() { + _adaptor_table.erase(path()); + debug_log("unregistering local object %s", path().c_str()); dbus_connection_unregister_object_path(conn()._pvt->conn, path().c_str()); - InterfaceTable::const_iterator ii = _interfaces.begin(); + InterfaceAdaptorTable::const_iterator ii = _interfaces.begin(); while( ii != _interfaces.end() ) { std::string im = "type='method_call',interface='"+ii->first+"'"; @@ -131,7 +168,7 @@ void ObjectAdaptor::unregister_obj() } } -void ObjectAdaptor::remit_signal( SignalMessage& sig ) +void ObjectAdaptor::_emit_signal( SignalMessage& sig ) { sig.path(path().c_str()); @@ -150,17 +187,17 @@ bool ObjectAdaptor::handle_message( const Message& msg ) case DBUS_MESSAGE_TYPE_METHOD_CALL: { const CallMessage& cmsg = reinterpret_cast(msg); - const char* member = cmsg.member(); - const char* interface = cmsg.interface(); + const char* member = cmsg.member(); + const char* interface = cmsg.interface(); debug_log(" invoking method %s.%s", interface, member); - InterfaceTable::const_iterator ii = _interfaces.find(interface); - if( ii != _interfaces.end() ) + InterfaceAdaptor* ii = find_interface(interface); + if( ii ) { try { - Message ret = ii->second->invoke_method(cmsg); + Message ret = ii->dispatch_method(cmsg); conn().send(ret); } catch(Error& e) @@ -170,7 +207,7 @@ bool ObjectAdaptor::handle_message( const Message& msg ) } catch(WontReturnException& wre) { - _deferred_returns[wre.tag] = new DeferredReturn(conn(), cmsg, wre.tag); + _continuations[wre.tag] = new Continuation(conn(), cmsg, wre.tag); } return true; } @@ -193,45 +230,45 @@ void ObjectAdaptor::return_later( const void* tag ) throw wre; } -void ObjectAdaptor::return_now( DeferredReturn* ret ) +void ObjectAdaptor::return_now( Continuation* ret ) { ret->_conn.send(ret->_return); - DeferredReturnMap::iterator di = _deferred_returns.find(ret->_tag); + ContinuationMap::iterator di = _continuations.find(ret->_tag); delete di->second; - _deferred_returns.erase(di); + _continuations.erase(di); } -void ObjectAdaptor::return_error( DeferredReturn* ret, Error& error ) +void ObjectAdaptor::return_error( Continuation* ret, const Error error ) { ret->_conn.send(ErrorMessage(ret->_call, error.name(), error.message())); - DeferredReturnMap::iterator di = _deferred_returns.find(ret->_tag); + ContinuationMap::iterator di = _continuations.find(ret->_tag); delete di->second; - _deferred_returns.erase(di); + _continuations.erase(di); } -ObjectAdaptor::DeferredReturn* ObjectAdaptor::find_return( const void* tag ) +ObjectAdaptor::Continuation* ObjectAdaptor::find_continuation( const void* tag ) { - DeferredReturnMap::iterator di = _deferred_returns.find(tag); + ContinuationMap::iterator di = _continuations.find(tag); - return di != _deferred_returns.end() ? di->second : NULL; + return di != _continuations.end() ? di->second : NULL; } -ObjectAdaptor::DeferredReturn::DeferredReturn( Connection& conn, const CallMessage& call, const void* tag ) +ObjectAdaptor::Continuation::Continuation( Connection& conn, const CallMessage& call, const void* tag ) : _conn(conn), _call(call), _return(_call), _tag(tag) { - _writer = _return.w_iter(); //todo: verify + _writer = _return.writer(); //todo: verify } /* */ -ObjectProxy::ObjectProxy( Connection& conn, const char* path, const char* service ) +ObjectProxy::ObjectProxy( Connection& conn, const Path& path, const char* service ) : Object(conn, path, service) { register_obj(); @@ -250,7 +287,7 @@ void ObjectProxy::register_obj() conn().add_filter(_filtered); - InterfaceTable::const_iterator ii = _interfaces.begin(); + InterfaceProxyTable::const_iterator ii = _interfaces.begin(); while( ii != _interfaces.end() ) { std::string im = "type='signal',interface='"+ii->first+"'"; @@ -266,7 +303,7 @@ void ObjectProxy::unregister_obj() { debug_log("unregistering remote object %s", path().c_str()); - InterfaceTable::const_iterator ii = _interfaces.begin(); + InterfaceProxyTable::const_iterator ii = _interfaces.begin(); while( ii != _interfaces.end() ) { std::string im = "type='signal',interface='"+ii->first+"'"; @@ -279,7 +316,7 @@ void ObjectProxy::unregister_obj() conn().remove_filter(_filtered); } -Message ObjectProxy::rinvoke_method( CallMessage& call ) +Message ObjectProxy::_invoke_method( CallMessage& call ) { call.path(path().c_str()); call.destination(service().c_str()); @@ -299,10 +336,10 @@ bool ObjectProxy::handle_message( const Message& msg ) debug_log("filtered signal %s(in %s) from remote object %s", member, interface, msg.sender()); - InterfaceTable::const_iterator ii = _interfaces.find(interface); - if( ii != _interfaces.end() ) + InterfaceProxy* ii = find_interface(interface); + if( ii ) { - return ii->second->dispatch_signal(smsg); + return ii->dispatch_signal(smsg); } else { @@ -313,14 +350,14 @@ bool ObjectProxy::handle_message( const Message& msg ) { debug_log("filtered method return from remote object %s", msg.sender()); - //TODO: + //TODO? return false; } case DBUS_MESSAGE_TYPE_ERROR: { debug_log("filtered error from remote object %s", msg.sender()); - //TODO: + //TODO? return false; } default: diff --git a/src/pendingcall.cpp b/src/pendingcall.cpp index 799c7c7..2221619 100644 --- a/src/pendingcall.cpp +++ b/src/pendingcall.cpp @@ -31,12 +31,12 @@ using namespace DBus; -PendingCall::Private::Private( DBusPendingCall* pc ) -: call(pc), dataslot(-1) +PendingCall::Private::Private( DBusPendingCall* dpc ) +: call(dpc), dataslot(-1) { if(!dbus_pending_call_allocate_data_slot(&dataslot)) { - throw Error(DBUS_ERROR_NO_MEMORY, "Unable to allocate data slot"); + throw ErrorNoMemory("Unable to allocate data slot"); } } @@ -60,7 +60,7 @@ PendingCall::PendingCall( PendingCall::Private* p ) { if(!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, this, NULL)) { - throw Error(DBUS_ERROR_NO_MEMORY, "Unable to initialize pending call"); + throw ErrorNoMemory("Unable to initialize pending call"); } } @@ -94,7 +94,7 @@ void PendingCall::data( void* p ) { if(!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL)) { - throw Error(DBUS_ERROR_NO_MEMORY, "Unable to initialize data slot"); + throw ErrorNoMemory("Unable to initialize data slot"); } } diff --git a/src/property.cpp b/src/property.cpp new file mode 100644 index 0000000..5e70a82 --- /dev/null +++ b/src/property.cpp @@ -0,0 +1,151 @@ +/* + * + * D-Bus++ - C++ bindings for DBus + * + * Copyright (C) 2005-2006 Paolo Durante + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include + +#include + +using namespace DBus; + +static const char* properties_name = "org.freedesktop.DBus.Properties"; + +PropertiesAdaptor::PropertiesAdaptor() +: InterfaceAdaptor(properties_name) +{ + register_method(PropertiesAdaptor, Get, Get); + register_method(PropertiesAdaptor, Set, Set); +} + +Message PropertiesAdaptor::Get( const CallMessage& call ) +{ + MessageIter ri = call.reader(); + + String iface_name; + String property_name; + + ri >> iface_name >> property_name; + + InterfaceAdaptor* interface = (InterfaceAdaptor*) find_interface(iface_name); + + if(!interface) + throw ErrorFailed("requested interface not found"); + + Variant* value = interface->get_property(property_name); + + if(!value) + throw ErrorFailed("requested property not found"); + + on_get_property(*interface, property_name, *value); + + ReturnMessage reply(call); + + MessageIter wi = reply.writer(); + + wi << *value; + + return reply; +} + +Message PropertiesAdaptor::Set( const CallMessage& call ) +{ + MessageIter ri = call.reader(); + + String iface_name; + String property_name; + Variant value; + + ri >> iface_name >> property_name >> value; + + InterfaceAdaptor* interface = (InterfaceAdaptor*) find_interface(iface_name); + + if(!interface) + throw ErrorFailed("requested interface not found"); + + on_set_property(*interface, property_name, value); + + if(!interface->set_property(property_name, value)) + throw ErrorFailed("requested property not found"); + + ReturnMessage reply(call); + + return reply; +} + +IntrospectedInterface* const PropertiesAdaptor::introspect() const +{ + static IntrospectedArgument Get_args[] = + { + { "interface_name", "s", true }, + { "property_name", "s", true }, + { "value", "v", false }, + { 0, 0, 0 } + }; + static IntrospectedArgument Set_args[] = + { + { "interface_name", "s", true }, + { "property_name", "s", true }, + { "value", "v", true }, + { 0, 0, 0 } + }; + static IntrospectedMethod Properties_methods[] = + { + { "Get", Get_args }, + { "Set", Set_args }, + { 0, 0 } + }; + static IntrospectedMethod Properties_signals[] = + { + { 0, 0 } + }; + static IntrospectedProperty Properties_properties[] = + { + { 0, 0, 0, 0 } + }; + static IntrospectedInterface Properties_interface = + { + properties_name, + Properties_methods, + Properties_signals, + Properties_properties + }; + return &Properties_interface; +} + +PropertiesProxy::PropertiesProxy() +: InterfaceProxy(properties_name) +{ +} + +Variant PropertiesProxy::Get( const String& iface, const String& property ) +{ +//todo + Variant v; + return v; +} + +void PropertiesProxy::Set( const String& iface, const String& property, const Variant& value ) +{ +//todo +} + diff --git a/src/types.cpp b/src/types.cpp index 3b69832..3a8a742 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -33,15 +33,16 @@ using namespace DBus; Variant::Variant() -: _msg(CallMessage()), // dummy message used as temporary storage for variant data - _it(_msg.w_iter()) +: _msg(CallMessage()) // dummy message used as temporary storage for variant data { } Variant::Variant( MessageIter& it ) -: _msg(it.msg()), - _it(it.recurse()) +: _msg(CallMessage()) { + MessageIter vi = it.recurse(); + MessageIter mi = _msg.writer(); + vi.copy_data(mi); } Variant& Variant::operator = ( const Variant& v ) @@ -49,118 +50,35 @@ Variant& Variant::operator = ( const Variant& v ) if(&v != this) { _msg = v._msg; - _it = v._it; - _signature = v._signature; } return *this; } -const char* Variant::signature() const +void Variant::clear() { - char* sigbuf = _it.signature(); + CallMessage empty; + _msg = empty; +} - _signature = sigbuf; +const Signature Variant::signature() const +{ + char* sigbuf = reader().signature(); + + Signature signature = sigbuf; free(sigbuf); - return _signature.c_str(); + return signature; } MessageIter& operator << ( MessageIter& iter, const Variant& val ) { - const char* sig = val.signature(); + const Signature sig = val.signature(); - MessageIter rit = val.iter(); - MessageIter wit = iter.new_variant(sig); + MessageIter rit = val.reader(); + MessageIter wit = iter.new_variant(sig.c_str()); - for(size_t i = 0; i < strlen(sig); ++i) - { - switch(sig[i]) - { - case 'b': - { - Bool b; rit >> b; wit << b; - break; - } - case 'y': - { - Byte y; rit >> y; wit << y; - break; - } - case 'n': - { - Int16 n; rit >> n; wit << n; - break; - } - case 'q': - { - UInt16 q; rit >> q; wit << q; - break; - } - case 'i': - { - Int32 i; rit >> i; wit << i; - break; - } - case 'u': - { - UInt32 u; rit >> u; wit << u; - break; - } - case 'x': - { - Int64 x; rit >> x; wit << x; - break; - } - case 't': - { - UInt64 t; rit >> t; wit << t; - break; - } - case 'd': - { - Double d; rit >> d; wit << d; - break; - } - case 's': - { - String s; rit >> s; wit << s; - break; - } - case 'o': - { - Path o; rit >> o; wit << o; - break; - } - case 'g': - { - Signature g; rit >> g; wit << g; - break; - } - case 'a': - { - break; - } - case '(': - { - break; - } - case ')': - { - break; - } - case '{': - { - break; - } - case '}': - { - break; - } - } - } - - //TODO: implement marshaling of compound types + rit.copy_data(wit); iter.close_container(wit); diff --git a/tests/Makefile.am b/tests/Makefile.am deleted file mode 100644 index 320a8d7..0000000 --- a/tests/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -EXTRA_DIST = test-introspect.xml diff --git a/tests/Makefile.in b/tests/Makefile.in deleted file mode 100644 index 5b70539..0000000 --- a/tests/Makefile.in +++ /dev/null @@ -1,319 +0,0 @@ -# Makefile.in generated by automake 1.9.6 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = tests -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/include/dbus-c++/config.h -CONFIG_CLEAN_FILES = -SOURCES = -DIST_SOURCES = -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMDEP_FALSE = @AMDEP_FALSE@ -AMDEP_TRUE = @AMDEP_TRUE@ -AMTAR = @AMTAR@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DBUS_DOXYGEN_DOCS_ENABLED_FALSE = @DBUS_DOXYGEN_DOCS_ENABLED_FALSE@ -DBUS_DOXYGEN_DOCS_ENABLED_TRUE = @DBUS_DOXYGEN_DOCS_ENABLED_TRUE@ -DEBUG_FLAGS = @DEBUG_FLAGS@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DOXYGEN = @DOXYGEN@ -ECHO = @ECHO@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -F77 = @F77@ -FFLAGS = @FFLAGS@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -RANLIB = @RANLIB@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_F77 = @ac_ct_F77@ -ac_ct_RANLIB = @ac_ct_RANLIB@ -ac_ct_STRIP = @ac_ct_STRIP@ -ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@ -am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ -am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ -am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ -am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -datadir = @datadir@ -dbus_CFLAGS = @dbus_CFLAGS@ -dbus_LIBS = @dbus_LIBS@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -xml_CFLAGS = @xml_CFLAGS@ -xml_LIBS = @xml_LIBS@ -EXTRA_DIST = test-introspect.xml -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu tests/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: -tags: TAGS -TAGS: - -ctags: CTAGS -CTAGS: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkdir_p) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-libtool - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-info-am - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - distclean distclean-generic distclean-libtool distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-exec install-exec-am \ - install-info install-info-am install-man install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ - uninstall-info-am - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/tests/test-introspect.xml b/tests/test-introspect.xml deleted file mode 100644 index e4fd9d0..0000000 --- a/tests/test-introspect.xml +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tools/introspect.h b/tools/introspect.h index 7f843e5..956c373 100644 --- a/tools/introspect.h +++ b/tools/introspect.h @@ -25,7 +25,7 @@ #ifndef __DBUSXX_TOOLS_INTROSPECT_H #define __DBUSXX_TOOLS_INTROSPECT_H -#include +#include #include class IntrospectedObject : public DBus::IntrospectableProxy, public DBus::ObjectProxy diff --git a/tools/xml2cpp.cpp b/tools/xml2cpp.cpp index 36a2838..16e444f 100644 --- a/tools/xml2cpp.cpp +++ b/tools/xml2cpp.cpp @@ -38,12 +38,14 @@ using namespace DBus; static const char* tab = " "; static const char* header = "\n\ -/* This file was automatically generated by dbusxx-xml2cpp; DO NOT EDIT! */\n\ +/*\n\ + * This file was automatically generated by dbusxx-xml2cpp; DO NOT EDIT!\n\ + */\n\ \n\ "; static const char* dbus_includes = "\n\ -#include \n\ +#include \n\ \n\ "; @@ -51,8 +53,8 @@ typedef map TypeCache; void usage( const char* argv0 ) { - cerr << endl << "Usage: " << argv0 << " [ --client= ] [ --adaptor= ]" - << endl << endl; + cerr << endl << "Usage: " << argv0 << " [ --proxy= ] [ --adaptor= ]" + << endl << endl; exit(-1); } @@ -60,7 +62,7 @@ void underscorize( std::string& str ) { for(unsigned int i = 0; i < str.length(); ++i) { - if(!isalpha(str[i])) str[i] = '_'; + if(!isalpha(str[i]) && !isdigit(str[i])) str[i] = '_'; } } @@ -83,19 +85,19 @@ const char* atomic_type_to_string( char t ) { static struct { char type; char* name; } atos[] = { - { 'y', "DBus::Byte" }, - { 'b', "DBus::Bool" }, - { 'n', "DBus::Int16" }, - { 'q', "DBus::UInt16" }, - { 'i', "DBus::Int32" }, - { 'u', "DBus::UInt32" }, - { 'x', "DBus::Int64" }, - { 't', "DBus::UInt64" }, - { 'd', "DBus::Double" }, - { 's', "DBus::String" }, - { 'o', "DBus::Path" }, - { 'g', "DBus::Signature" }, - { 'v', "DBus::Variant" }, + { 'y', "::DBus::Byte" }, + { 'b', "::DBus::Bool" }, + { 'n', "::DBus::Int16" }, + { 'q', "::DBus::UInt16" }, + { 'i', "::DBus::Int32" }, + { 'u', "::DBus::UInt32" }, + { 'x', "::DBus::Int64" }, + { 't', "::DBus::UInt64" }, + { 'd', "::DBus::Double" }, + { 's', "::DBus::String" }, + { 'o', "::DBus::Path" }, + { 'g', "::DBus::Signature" }, + { 'v', "::DBus::Variant" }, { '\0', "" } }; int i; @@ -124,7 +126,7 @@ void _parse_signature( const std::string& signature, std::string& type, size_t& { case '{': { - type += "DBus::Dict< "; + type += "std::map< "; const char* atom = atomic_type_to_string(signature[++i]); if(!atom) @@ -139,7 +141,7 @@ void _parse_signature( const std::string& signature, std::string& type, size_t& } default: { - type += "DBus::Array< "; + type += "std::vector< "; break; } } @@ -149,7 +151,7 @@ void _parse_signature( const std::string& signature, std::string& type, size_t& } case '(': { - type += "DBus::Struct< "; + type += "::DBus::Struct< "; ++i; _parse_signature(signature, type, i); type += " >"; @@ -188,7 +190,7 @@ std::string signature_to_type( const std::string& signature ) return type; } -void generate_client( Xml::Document& doc, const char* filename ) +void generate_proxy( Xml::Document& doc, const char* filename ) { cerr << "writing " << filename << endl; @@ -225,13 +227,13 @@ void generate_client( Xml::Document& doc, const char* filename ) cerr << "generating code for interface " << ifacename << "..." << endl; - file << "class " << ifaceclass << " : public DBus::InterfaceProxy" << endl - << "{" << endl - << "public:" << endl - << endl - << tab << ifaceclass << "()" << endl - << tab << ": DBus::InterfaceProxy(\"" << ifacename << "\")" << endl - << tab << "{" << endl; + file << "class " << ifaceclass << " : public ::DBus::InterfaceProxy" << endl + << "{" << endl + << "public:" << endl + << endl + << tab << ifaceclass << "()" << endl + << tab << ": ::DBus::InterfaceProxy(\"" << ifacename << "\")" << endl + << tab << "{" << endl; for(Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) { @@ -243,7 +245,7 @@ void generate_client( Xml::Document& doc, const char* filename ) } file << tab << "}" << endl - << endl; + << endl; for(Xml::Nodes::iterator j = methods.begin(); j != methods.end(); ++j) { @@ -297,9 +299,9 @@ void generate_client( Xml::Document& doc, const char* filename ) } file << tab << "{" << endl - << tab << tab << "DBus::CallMessage call;" << endl - << tab << tab << "DBus::MessageIter wi = call.w_iter();" << endl - << endl; + << tab << tab << "::DBus::CallMessage call;" << endl + << tab << tab << "::DBus::MessageIter wi = call.writer();" << endl + << endl; for(Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai) { @@ -307,17 +309,17 @@ void generate_client( Xml::Document& doc, const char* filename ) } file << tab << tab << "call.member(\"" << methodname << "\");" << endl - << tab << tab << "DBus::Message ret = invoke_method(call);" << endl - << tab << tab << "DBus::MessageIter ri = ret.r_iter();" << endl - << endl; + << tab << tab << "::DBus::Message ret = invoke_method(call);" << endl + << tab << tab << "::DBus::MessageIter ri = ret.reader();" << endl + << endl; file << tab << "}" << endl - << endl; + << endl; } file << "};" << endl - << endl; + << endl; } #endif file << "#endif//" << cond_comp << endl; @@ -343,7 +345,7 @@ void generate_adaptor( Xml::Document& doc, const char* filename ) std::string cond_comp = "__dbusxx__" + filestring + "__ADAPTOR_MARSHAL_H"; file << "#ifndef " << cond_comp << endl - << "#define " << cond_comp << endl; + << "#define " << cond_comp << endl; file << dbus_includes; @@ -355,12 +357,14 @@ void generate_adaptor( Xml::Document& doc, const char* filename ) Xml::Node& iface = **i; Xml::Nodes methods = iface["method"]; Xml::Nodes signals = iface["signal"]; + Xml::Nodes properties = iface["property"]; Xml::Nodes ms; ms.insert(ms.end(), methods.begin(), methods.end()); ms.insert(ms.end(), signals.begin(), signals.end()); std::string ifacename = iface.get("name"); - if(ifacename.find("org.freedesktop.DBus") == 0) + if(ifacename == "org.freedesktop.DBus.Introspectable" + ||ifacename == "org.freedesktop.DBus.Properties") { cerr << "skipping interface " << ifacename << endl; continue; @@ -386,36 +390,53 @@ void generate_adaptor( Xml::Document& doc, const char* filename ) cerr << "generating code for interface " << ifacename << "..." << endl; - file << "class " << ifaceclass << " : public DBus::InterfaceAdaptor" << endl - << "{" << endl - << "public:" << endl - << endl - << tab << ifaceclass << "()" << endl - << tab << ": DBus::InterfaceAdaptor(\"" << ifacename << "\")" << endl - << tab << "{" << endl; + file << "class " << ifaceclass << endl + << ": public ::DBus::InterfaceAdaptor" << endl + << "{" << endl + << "public:" << endl + << endl + << tab << ifaceclass << "()" << endl + << tab << ": ::DBus::InterfaceAdaptor(\"" << ifacename << "\")" << endl + << tab << "{" << endl; + + for(Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi) + { + Xml::Node& property = **pi; + + file << tab << tab << "bind_property(" + << property.get("name") << ", " + << ( property.get("access").find("read") != string::npos + ? "true" + : "false" ) + << ", " + << ( property.get("access").find("write") != string::npos + ? "true" + : "false" ) + << ");" << endl; + } for(Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi) { Xml::Node& method = **mi; file << tab << tab << "register_method(" - << ifaceclass << ", " << method.get("name") << ", "<< stub_name(method.get("name")) - << ");" << endl; + << ifaceclass << ", " << method.get("name") << ", "<< stub_name(method.get("name")) + << ");" << endl; } file << tab << "}" << endl - << endl; + << endl; - file << tab << "DBus::IntrospectedInterface* const introspect() const " << endl - << tab << "{" << endl; + file << tab << "::DBus::IntrospectedInterface* const introspect() const " << endl + << tab << "{" << endl; for(Xml::Nodes::iterator mi = ms.begin(); mi != ms.end(); ++mi) { Xml::Node& method = **mi; Xml::Nodes args = method["arg"]; - file << tab << tab << "static DBus::IntrospectedArgument " << method.get("name") << "_args[] = " << endl - << tab << tab << "{" << endl; + file << tab << tab << "static ::DBus::IntrospectedArgument " << method.get("name") << "_args[] = " << endl + << tab << tab << "{" << endl; for(Xml::Nodes::iterator ai = args.begin(); ai != args.end(); ++ai) { @@ -432,15 +453,15 @@ void generate_adaptor( Xml::Document& doc, const char* filename ) file << "0, "; } file << "\"" << arg.get("type") << "\", " - << ( arg.get("direction") == "in" ? "true" : "false" ) - << " }," << endl; + << ( arg.get("direction") == "in" ? "true" : "false" ) + << " }," << endl; } file << tab << tab << tab << "{ 0, 0, 0 }" << endl - << tab << tab << "};" << endl; + << tab << tab << "};" << endl; } - file << tab << tab << "static DBus::IntrospectedMethod " << ifaceclass << "_methods[] = " << endl - << tab << tab << "{" << endl; + file << tab << tab << "static ::DBus::IntrospectedMethod " << ifaceclass << "_methods[] = " << endl + << tab << tab << "{" << endl; for(Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi) { @@ -450,10 +471,10 @@ void generate_adaptor( Xml::Document& doc, const char* filename ) } file << tab << tab << tab << "{ 0, 0 }" << endl - << tab << tab << "};" << endl; + << tab << tab << "};" << endl; - file << tab << tab << "static DBus::IntrospectedMethod " << ifaceclass << "_signals[] = " << endl - << tab << tab << "{" << endl; + file << tab << tab << "static ::DBus::IntrospectedMethod " << ifaceclass << "_signals[] = " << endl + << tab << tab << "{" << endl; for(Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) { @@ -463,23 +484,66 @@ void generate_adaptor( Xml::Document& doc, const char* filename ) } file << tab << tab << tab << "{ 0, 0 }" << endl - << tab << tab << "};" << endl; + << tab << tab << "};" << endl; - file << tab << tab << "static DBus::IntrospectedInterface " << ifaceclass << "_interface = " << endl - << tab << tab << "{" << endl - << tab << tab << tab << "\"" << ifacename << "\"," << endl - << tab << tab << tab << ifaceclass << "_methods," << endl - << tab << tab << tab << ifaceclass << "_signals," << endl - << tab << tab << "};" << endl - << tab << tab << "return &" << ifaceclass << "_interface;" << endl - << tab << "}" << endl - << endl; + file << tab << tab << "static ::DBus::IntrospectedProperty " << ifaceclass << "_properties[] = " << endl + << tab << tab << "{" << endl; + + for(Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi) + { + Xml::Node& property = **pi; + + file << tab << tab << tab << "{ " + << "\"" << property.get("name") << "\", " + << "\"" << property.get("type") << "\", " + << ( property.get("access").find("read") != string::npos + ? "true" + : "false" ) + << ", " + << ( property.get("access").find("write") != string::npos + ? "true" + : "false" ) + << " }," << endl; + } + + + file << tab << tab << tab << "{ 0, 0, 0, 0 }" << endl + << tab << tab << "};" << endl; + + file << tab << tab << "static ::DBus::IntrospectedInterface " << ifaceclass << "_interface = " << endl + << tab << tab << "{" << endl + << tab << tab << tab << "\"" << ifacename << "\"," << endl + << tab << tab << tab << ifaceclass << "_methods," << endl + << tab << tab << tab << ifaceclass << "_signals," << endl + << tab << tab << tab << ifaceclass << "_properties" << endl + << tab << tab << "};" << endl + << tab << tab << "return &" << ifaceclass << "_interface;" << endl + << tab << "}" << endl + << endl; file << "public:" << endl - << endl - << tab << "/* methods exported by this interface," << endl - << tab << " * you will have to implement them in your ObjectAdaptor" << endl - << tab << " */" << endl; + << endl + << tab << "/* properties exposed by this interface, use" << endl + << tab << " * property() and property(value) to get and set a particular property" << endl + << tab << " */" << endl; + + for(Xml::Nodes::iterator pi = properties.begin(); pi != properties.end(); ++pi) + { + Xml::Node& property = **pi; + std::string name = property.get("name"); + std::string type = property.get("type"); + std::string type_name = signature_to_type(type); + + file << tab << "::DBus::PropertyAdaptor< " << type_name << " > " << name << ";" << endl; + } + + file << endl; + + file << "public:" << endl + << endl + << tab << "/* methods exported by this interface," << endl + << tab << " * you will have to implement them in your ObjectAdaptor" << endl + << tab << " */" << endl; for(Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi) { @@ -535,10 +599,10 @@ void generate_adaptor( Xml::Document& doc, const char* filename ) } file << endl - << "protected:" << endl - << endl - << tab << "/* signals emitted by this interface" << endl - << tab << " */" << endl; + << "protected:" << endl + << endl + << tab << "/* signals emitted by this interface" << endl + << tab << " */" << endl; for(Xml::Nodes::iterator si = signals.begin(); si != signals.end(); ++si) { @@ -559,13 +623,13 @@ void generate_adaptor( Xml::Document& doc, const char* filename ) } file << " )" << endl - << tab << "{" << endl - << tab << tab << "DBus::SignalMessage sig(\"" << signal.get("name") <<"\");" << endl;; + << tab << "{" << endl + << tab << tab << "::DBus::SignalMessage sig(\"" << signal.get("name") <<"\");" << endl;; if(args.size() > 0) { - file << tab << tab << "DBus::MessageIter wi = sig.w_iter();" << endl; + file << tab << tab << "::DBus::MessageIter wi = sig.writer();" << endl; for(unsigned int i = 0; i < args.size(); ++i) { @@ -574,14 +638,14 @@ void generate_adaptor( Xml::Document& doc, const char* filename ) } file << tab << tab << "emit_signal(sig);" << endl - << tab << "}" << endl; + << tab << "}" << endl; } file << endl - << "private:" << endl - << endl - << tab << "/* marshalers (to unpack the DBus message before calling the actual interface method)" << endl - << tab << " */" << endl; + << "private:" << endl + << endl + << tab << "/* marshalers (to unpack the DBus message before calling the actual interface method)" << endl + << tab << " */" << endl; for(Xml::Nodes::iterator mi = methods.begin(); mi != methods.end(); ++mi) { @@ -590,17 +654,17 @@ void generate_adaptor( Xml::Document& doc, const char* filename ) Xml::Nodes args_in = args.select("direction","in"); Xml::Nodes args_out = args.select("direction","out"); - file << tab << "DBus::Message " << stub_name(method.get("name")) << "( const DBus::CallMessage& call )" << endl - << tab << "{" << endl - << tab << tab << "DBus::MessageIter ri = call.r_iter();" << endl - << endl; + file << tab << "::DBus::Message " << stub_name(method.get("name")) << "( const ::DBus::CallMessage& call )" << endl + << tab << "{" << endl + << tab << tab << "::DBus::MessageIter ri = call.reader();" << endl + << endl; unsigned int i = 1; for(Xml::Nodes::iterator ai = args_in.begin(); ai != args_in.end(); ++ai, ++i) { Xml::Node& arg = **ai; file << tab << tab << signature_to_type(arg.get("type")) << " argin" << i << ";" - << " ri >> argin" << i << ";" << endl; + << " ri >> argin" << i << ";" << endl; } if(args_out.size() == 0) @@ -643,11 +707,11 @@ void generate_adaptor( Xml::Document& doc, const char* filename ) file << ");" << endl; - file << tab << tab << "DBus::ReturnMessage reply(call);" << endl; + file << tab << tab << "::DBus::ReturnMessage reply(call);" << endl; if(args_out.size() > 0) { - file << tab << tab << "DBus::MessageIter wi = reply.w_iter();" << endl; + file << tab << tab << "::DBus::MessageIter wi = reply.writer();" << endl; for(unsigned int i = 0; i < args_out.size(); ++i) { @@ -661,7 +725,7 @@ void generate_adaptor( Xml::Document& doc, const char* filename ) } file << "};" << endl - << endl; + << endl; for(size_t i = 0; i < nspaces; ++i) { @@ -682,21 +746,21 @@ int main( int argc, char** argv ) usage(argv[0]); } - bool client_mode, adaptor_mode; - char *client, *adaptor; + bool proxy_mode, adaptor_mode; + char *proxy, *adaptor; - client_mode = false; - client = 0; + proxy_mode = false; + proxy = 0; adaptor_mode = false; adaptor = 0; for(int a = 1; a < argc; ++a) { - if(!strncmp(argv[a], "--client=", 9)) + if(!strncmp(argv[a], "--proxy=", 8)) { - client_mode = true; - client = argv[a] +9; + proxy_mode = true; + proxy = argv[a] +8; } else if(!strncmp(argv[a], "--adaptor=", 10)) @@ -706,7 +770,7 @@ int main( int argc, char** argv ) } } - if(!client_mode && !adaptor_mode) usage(argv[0]); + if(!proxy_mode && !adaptor_mode) usage(argv[0]); ifstream xmlfile(argv[1]); @@ -735,7 +799,7 @@ int main( int argc, char** argv ) return -1; } - if(client_mode) generate_client(doc, client); + if(proxy_mode) generate_proxy(doc, proxy); if(adaptor_mode) generate_adaptor(doc, adaptor); return 0; diff --git a/tools/xml2cpp.h b/tools/xml2cpp.h index 56bf95e..cb0ae53 100644 --- a/tools/xml2cpp.h +++ b/tools/xml2cpp.h @@ -25,7 +25,7 @@ #ifndef __DBUSXX_TOOLS_XML2CPP_H #define __DBUSXX_TOOLS_XML2CPP_H -#include +#include #include #endif//__DBUSXX_TOOLS_XML2CPP_H