From: <or...@us...> - 2011-08-14 13:38:59
|
Revision: 29 http://bsf4oorexx.svn.sourceforge.net/bsf4oorexx/?rev=29&view=rev Author: orexx Date: 2011-08-14 13:38:52 +0000 (Sun, 14 Aug 2011) Log Message: ----------- 20110814 Fix 'dbusdoc.rex', add two samples to demonstrate the direct dbus ooRexx binding (Sebastian Margiol created ooRexx dbus examples using BSF4ooRexx, i.e. using the rather inflexible Java dbus binding). Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbusdoc.rex Added Paths: ----------- sandbox/rgf/misc/dbusoorexx/examples/margiolKate.rex sandbox/rgf/misc/dbusoorexx/examples/margiolVLC.rex sandbox/rgf/misc/dbusoorexx/listObjectPaths.rex Modified: sandbox/rgf/misc/dbusoorexx/dbusdoc.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbusdoc.rex 2011-08-13 19:38:13 UTC (rev 28) +++ sandbox/rgf/misc/dbusoorexx/dbusdoc.rex 2011-08-14 13:38:52 UTC (rev 29) @@ -1,7 +1,7 @@ #!/usr/bin/rexx /* author: Rony G. Flatscher (c) - date: 2011-07-29/31, 2011-08-01/05 + date: 2011-07-29/31, 2011-08-01/05, 2011-08-14 version: 1.0 name: dbusdoc.rex purpose: documents given bus name in HTML form to allow the creation of API listings @@ -583,8 +583,9 @@ if a~name<>"" then mm~~append(' <span class="argname">')~~append(a~name)~~append('</span>') + + bFirstRun=.false end - bFirstRun=.false end tmpStr=mm~string Added: sandbox/rgf/misc/dbusoorexx/examples/margiolKate.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/examples/margiolKate.rex (rev 0) +++ sandbox/rgf/misc/dbusoorexx/examples/margiolKate.rex 2011-08-14 13:38:52 UTC (rev 29) @@ -0,0 +1,116 @@ +#!/usr/bin/rexx +/* + author: Rony G. Flatscher (c) 2011 + name: margiolKate.rex + date: 2011-08-14 + purpose: demonstrate how to code the Sebastian Margiol examples for controlling "kate" and "klipper" with + the direct DBUS language binding for ooRexx + + needs: "kate" (editor) and "klipper" (clipboard) installed + + version: 1.0 + + license: AL 2.0 + + ------------------------ Apache Version 2.0 license ------------------------- + Copyright 2011 Rony G. Flatscher + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ----------------------------------------------------------------------------- + + dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> +*/ + signal on syntax -- syntax condition handler + signal on halt name syntax -- CTL-C handler + + kateProcId=getKateProcId() -- get the procid of the newest Kate, create an instance if necessary + if kateProcId="" then -- no kate instance found (and could not be created) + do + say "no kate instance available, could not create one either, aborting ..." + exit -1 + end + + busname="org.kde.kate-"kateProcID -- create the bus name kate listens to + objPath="/Kate/Document/1" -- define object path + + conn=.dbus~session -- get the session connection + document=conn~getObject(busname,objPath) -- get the kate document object + + klipper=conn~getObject("org.kde.klipper","/klipper") -- get the klipper object + + if document~isEmpty then -- a new, empty document + do + struct=document~endOfLine(1) -- structs are represented as Rexx array objects + say "line" struct[1] "ends at position" struct[2] + + say "Empty document, filling with computed text..." + text=.array~of(" ____ ", - + " ___ ___ | _ \ ___ __ ____ __", - + " / _ \ / _ \| |_) | / _ \\ \/ /\ \/ /", - + "| ( ) || ( ) || _ < | <_>/ > < > < ", - + " \___/ \___/ |_| \_\ \__\ /_/\_\/_/\_\" ) + + document~insertTextLines(.array~of(0,0), text, .false) -- insert the text + end + else -- an existing document + do + say "Document not empty! (Found "document~totalCharacters "characters in" document~lines "line(s).)" + say "- text gets copied to the clipboard and document will be cleared. Press enter to continue ..." + parse pull input + + klipper~setClipboardContents(document~text) + document~clear + say "- Text got copied to the clipboard and the document cleared." + say " next step: paste text from clipboard into the document. Press enter to continue ..." + parse pull input + + document~setText(klipper~getClipboardContents) + say "- Text got pasted from the clipboard into the document." + say " (There are "document~totalCharacters "characters in" document~lines "line(s).)" + end + say "done." + conn~close -- closing the connections, stops the message loop thread + exit + +syntax: + co=condition('object') -- get condition object + call dump2 co + conn~close -- closing the connections, stops the message loop thread + exit + + +::requires "dbus.cls" -- get access to DBus +-- ::requires "rgf_util2.rex" -- package installed with BSF4ooRexx, eases debugging due to 'pp'-formatting and dump2() routines + + +::routine getKateProcId -- return process id of newest Kate instance of current user; if there is none, start an instance of Kate + cmd='pgrep -n -x -u "$USER" kate | rxqueue' -- get procid and queue it via the external Rexx queue + + proc=getProc(cmd) -- get kate's proc id + if proc="" then -- found no kate instance for this user + do + "kate &" -- let the shell create a new instance of kate + call syssleep .5 -- wait a little bit to give this kate instance time to request a busname + proc=getProc(cmd) -- get kate's proc id + end + return proc -- return the proc id + +getProc: procedure -- do the work: execute the command, parse its output + parse arg cmd + cmd -- let the shell execute the passed command + proc="" + do while queued()>0 + parse pull proc -- pull the procid from the external Rexx queue, make sure its emptied + end + return proc + Property changes on: sandbox/rgf/misc/dbusoorexx/examples/margiolKate.rex ___________________________________________________________________ Added: svn:executable + * Added: sandbox/rgf/misc/dbusoorexx/examples/margiolVLC.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/examples/margiolVLC.rex (rev 0) +++ sandbox/rgf/misc/dbusoorexx/examples/margiolVLC.rex 2011-08-14 13:38:52 UTC (rev 29) @@ -0,0 +1,119 @@ +#!/usr/bin/rexx +/* + author: Rony G. Flatscher (c) 2011 + name: margiolVLC.rex + date: 2011-08-14 + purpose: demonstrate how to code the Sebastian Margiol examples for controlling "vlc" with the direct + DBUS language binding for ooRexx + + needs: get and install "vlc" (http://www.vlc.org), then go to "Tools -> Preferences", + "Show settings" to "All", then open "Interfaces" in the left frame and mark + "Control interfaces" and check "D-Bus control interface" + + version: 1.0 + + license: AL 2.0 + + ------------------------ Apache Version 2.0 license ------------------------- + Copyright 2011 Rony G. Flatscher + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ----------------------------------------------------------------------------- + + dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> +*/ + signal on syntax + signal on halt name syntax + + conn=.dbus~session -- get the session connection + listener=.SignalHandler~new -- create an instance of our signal handler + conn~listener("add",listener) -- add the listener to the connection + + -- tell DBus to forward us the signals matching the following rule/filter (cf. <http://dbus.freedesktop.org/doc/dbus-specification.html>) + matchRule="type='signal',interface='org.freedesktop.MediaPlayer'" + -- if third argument is given and set to .true, then the message may block, but also returns + -- error information, if the match rule is misformed (so this is recommended for debugging filters) + conn~match("add",matchRule,.true) -- tell DBus what to dispatch to our connection + + mp=conn~getObject("org.mpris.vlc","/Player") -- get the VLC player object + say "mp~pause..." + mp~pause -- pause the player (status gets changed) + say "paused position:" mp~PositionGet + -- call dump2 mp~getMetaData, "MetaData of current track" + wait=10 + say "sleeping" wait "seconds ..." + call sysSleep wait + + say "current volume: " mp~VolumeGet", setting to '40'..." + mp~volumeSet(40) + say "current volume: " mp~VolumeGet + mp~pause -- let it play again ... (status change) + say "sleeping" wait "seconds ..." + call sysSleep wait + say "-"~copies(50) + + say "now changing tracks a bit, mp~PositionGet:" mp~PositionGet + say "next, wait for" wait "seconds" + mp~next + say "now position:" mp~PositionGet + mp~PositionSet(60000) -- position at the one minute mark in the track + say "now position:" mp~PositionGet + call sysSleep wait + + say "next, wait for" wait "seconds" + mp~next + say "now position:" mp~PositionGet + call sysSleep wait + + say "prev, wait for" wait "seconds" + mp~~prev~~prev + say "now position:" mp~PositionGet + call sysSleep wait + say "stopping the media player." + mp~stop -- stop media player + say "--- The End. ---" + conn~close -- closing the connections, stops the message loop thread + exit + +syntax: + co=condition('object') -- get condition object + call dump2 co + conn~close -- closing the connections, stops the message loop thread + exit + + +::requires "dbus.cls" -- get access to DBus +::requires "rgf_util2.rex" -- package installed with BSF4ooRexx, eases debugging due to 'pp'-formatting and dump2() routines + + + /* only define methods by the name of the signal to intercept */ +::class SignalHandler +::method CapsChange + use arg i, slotDir + say "===> CapsChange-signal:" pp2(i) "received at:" slotDir~dateTime + +::method StatusChange + use arg ai, slotDir + say "===> StautsChange-signal:" "received at:" slotDir~dateTime + call dump2 ai, "statusChange data" + +::method TrackChange + use arg dir, slotDir + say "===> TrackChange-signal:" "received at:" slotDir~dateTime + call dump2 dir, "TrackChange submitted directory" + +::method unknown + use arg methName, methArgs + slotDir=methArgs[methArgs~last] -- last argument is the 'slotDir' directory + say "===> unknown signal: name="pp2(methName) "received at:" slotDir~dateTime + Property changes on: sandbox/rgf/misc/dbusoorexx/examples/margiolVLC.rex ___________________________________________________________________ Added: svn:executable + * Copied: sandbox/rgf/misc/dbusoorexx/listObjectPaths.rex (from rev 28, sandbox/rgf/misc/dbusoorexx/tests/testGetObjectPaths.rex) =================================================================== --- sandbox/rgf/misc/dbusoorexx/listObjectPaths.rex (rev 0) +++ sandbox/rgf/misc/dbusoorexx/listObjectPaths.rex 2011-08-14 13:38:52 UTC (rev 29) @@ -0,0 +1,61 @@ +#!/usr/bin/rexx +/* + author: Rony G. Flatscher (c) + date: 2011-08-14 + version: 1.0 + name: listObjectPaths.rex + purpose: interrogate given bus name for the object paths it publishes and list them + license: AL 2.0 + ------------------------ Apache Version 2.0 license ------------------------- + Copyright 2011 Rony G. Flatscher + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ----------------------------------------------------------------------------- +*/ + +parse arg bustype serviceName . -- command line argument +if servicename='' then +do + serviceName=busType + bustype="session" -- default to 'session' +end + +if wordpos(bustype,"session system")=0, pos(':',bustype)=0 then +do + say "Error: bustype" pp2(bustype) "is not 'system', 'session', nor an address, aborting..." + exit -1 +end +conn=.Dbus~connect(bustype) + +if serviceName="" then -- no service name given, list all known service names +do + o=conn~getObject(.dbus.dir~ServiceDBus, .dbus.dir~PathDBus) -- get the DBus object + say "available service/bus names:" + do sn over .array~new ~union(o~listNames) ~union(o~listActivatableNames)~sort + say " " sn + end + say + say "usage: testGetObjectPaths serviceName" +end +else -- get an array of published object paths +do + objPaths=conn~getObjectPaths(serviceName)~sort + + say "There are" objPaths~items "object paths for service/bus name ["serviceName"]:" + do i=1 to objPaths~items + say " #" i": ["objPaths[i]"]" + end +end + + +::requires 'dbus.cls' -- load DBUS support for ooRexx This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2011-08-15 21:36:48
|
Revision: 31 http://bsf4oorexx.svn.sourceforge.net/bsf4oorexx/?rev=31&view=rev Author: orexx Date: 2011-08-15 21:36:42 +0000 (Mon, 15 Aug 2011) Log Message: ----------- 20110815 Apple MacOSX makefile, MacOSX startup script. Added Paths: ----------- sandbox/rgf/misc/dbusoorexx/dev/apple-Makefile.mak sandbox/rgf/misc/dbusoorexx/tests/runtest-mac.sh Added: sandbox/rgf/misc/dbusoorexx/dev/apple-Makefile.mak =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/apple-Makefile.mak (rev 0) +++ sandbox/rgf/misc/dbusoorexx/dev/apple-Makefile.mak 2011-08-15 21:36:42 UTC (rev 31) @@ -0,0 +1,61 @@ +# usage: make -f apple-Makefile.mak [all \ i386 | x86_64 | ppc | universal \ clean ] +# rgf, 2011-08-15 + + +# Define a list of pkg-config packages we want to use +pkg_packages = dbus-1 + +PKG_CFLAGS = $(shell pkg-config --cflags $(pkg_packages)) +PKG_LDFLAGS = $(shell pkg-config --libs $(pkg_packages)) + +INC_PATH = -I. -I/opt/local/include/dbus-1.0 +INC_PATH_ORX = -I/opt/ooRexx/include $(INC_PATH) +LIB_PATH = -L/opt/local/lib + +ADD_CFLAGS := -g -Wall -DUNIX -D__cplusplus +# LDFLAGS = -shared -rdynamic -lpthread -lc -lm +ADD_LFLAGS = -shared -rdynamic + +CFLAGS = $(PKG_CFLAGS) $(ADD_CFLAGS) -fPIC +LFLAGS = $(PKG_LDFLAGS) $(ADD_LFLAGS) + + + +# -------------------------------------------------------- +all: i386 x86_64 ppc universal + +# -------------------------------------------------------- +i386: dbusoorexx.cc + g++ -c $(CFLAGS) $(INC_PATH) -I/opt/ooRexx-i386/include -m32 -arch i386 -DUSE_OREXX -DUNIX -odbusoorexx-mac-i386.o dbusoorexx.cc + + g++ -dynamiclib $(LFLAGS) -o libdbusoorexx-i386.dylib dbusoorexx-mac-i386.o /usr/lib/librexx.dylib /usr/lib/librexxapi.dylib $(LIB_PATH) -framework JavaVM -arch i386 + +# cp -p libdbusoorexx-i386.dylib 32/libdbusoorexx.dylib + +# --------------------------------------------------- +x86_64: dbusoorexx.cc + g++ -c $(CFLAGS) $(INC_PATH) -I/opt/ooRexx-x86_64/include -m64 -arch x86_64 -DUSE_OREXX -DUNIX -odbusoorexx-mac-x86_64.o dbusoorexx.cc + + g++ -dynamiclib $(LFLAGS) -o libdbusoorexx-x86_64.dylib dbusoorexx-mac-x86_64.o /opt/ooRexx-x86_64/lib/ooRexx/librexx.dylib /opt/ooRexx-x86_64/lib/ooRexx/librexxapi.dylib $(LIB_PATH) -framework JavaVM -arch x86_64 +# cp -p libdbusoorexx-x86_64.dylib 64/libdbusoorexx.dylib + +# --------------------------------------------------- +ppc: dbusoorexx.cc + g++ -c $(CFLAGS) $(INC_PATH) -I/opt/ooRexx-x86_64/include -I/opt/ooRexx-ppc/include -m32 -arch ppc -DUSE_OREXX -DUNIX -odbusoorexx-mac-ppc.o dbusoorexx.cc + + g++ -dynamiclib $(LFLAGS) -o libdbusoorexx-ppc.dylib dbusoorexx-mac-ppc.o /opt/ooRexx-ppc/lib/ooRexx/librexx.dylib /opt/ooRexx-ppc/lib/ooRexx/librexxapi.dylib $(LIB_PATH) -framework JavaVM -arch ppc + +# --------------------------------------------------- +universal: dbusoorexx.cc i386 x86_64 + lipo -create -output libdbusoorexx.dylib -arch x86_64 libdbusoorexx-x86_64.dylib -arch i386 libdbusoorexx-i386.dylib + +# lipo -create -output libdbusoorexx.dylib -arch x86_64 libdbusoorexx-x86_64.dylib -arch i386 libdbusoorexx-i386.dylib -arch ppc libdbusoorexx-ppc.dylib + + +# --------------------------------------------------- + + +.PHONY: clean +clean: + rm -f *.dylib + rm -f *.o Property changes on: sandbox/rgf/misc/dbusoorexx/dev/apple-Makefile.mak ___________________________________________________________________ Added: svn:executable + * Added: sandbox/rgf/misc/dbusoorexx/tests/runtest-mac.sh =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/runtest-mac.sh (rev 0) +++ sandbox/rgf/misc/dbusoorexx/tests/runtest-mac.sh 2011-08-15 21:36:42 UTC (rev 31) @@ -0,0 +1,8 @@ +#!/bin/sh +# run with a local version of libdbus +# DBUSLIB=$HOME/lib/libdbus-1.so +# DBUSLIB=$HOME/lib/libdbus-1.so.3.5.7 +DBUSLIB=$HOME/dev/bsf4oorexx/sandbox/rgf/misc/dbusoorexx/dev +DBUSPATH=$HOME/dev/bsf4oorexx/sandbox/rgf/misc/dbusoorexx +echo $0 running "DYLD_LIBRARY_PATH=$DBUSLIB PATH=$DBUSPATH rexx $1" +DYLD_LIBRARY_PATH=$DBUSLIB PATH=$DBUSPATH:$PATH rexx $1 Property changes on: sandbox/rgf/misc/dbusoorexx/tests/runtest-mac.sh ___________________________________________________________________ Added: svn:executable + * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2011-08-15 21:46:12
|
Revision: 32 http://bsf4oorexx.svn.sourceforge.net/bsf4oorexx/?rev=32&view=rev Author: orexx Date: 2011-08-15 21:46:06 +0000 (Mon, 15 Aug 2011) Log Message: ----------- 20110815 Added bitness information to Makefile, show DBusVersion() in tests/testDBusRoutines.rex. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dev/apple-Makefile.mak sandbox/rgf/misc/dbusoorexx/tests/testDBusRoutines.rex Modified: sandbox/rgf/misc/dbusoorexx/dev/apple-Makefile.mak =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/apple-Makefile.mak 2011-08-15 21:36:42 UTC (rev 31) +++ sandbox/rgf/misc/dbusoorexx/dev/apple-Makefile.mak 2011-08-15 21:46:06 UTC (rev 32) @@ -26,7 +26,7 @@ # -------------------------------------------------------- i386: dbusoorexx.cc - g++ -c $(CFLAGS) $(INC_PATH) -I/opt/ooRexx-i386/include -m32 -arch i386 -DUSE_OREXX -DUNIX -odbusoorexx-mac-i386.o dbusoorexx.cc + g++ -c $(CFLAGS) $(INC_PATH) -I/opt/ooRexx-i386/include -m32 -arch i386 -DDBUSOOREXX_32 -DUSE_OREXX -DUNIX -odbusoorexx-mac-i386.o dbusoorexx.cc g++ -dynamiclib $(LFLAGS) -o libdbusoorexx-i386.dylib dbusoorexx-mac-i386.o /usr/lib/librexx.dylib /usr/lib/librexxapi.dylib $(LIB_PATH) -framework JavaVM -arch i386 @@ -34,14 +34,14 @@ # --------------------------------------------------- x86_64: dbusoorexx.cc - g++ -c $(CFLAGS) $(INC_PATH) -I/opt/ooRexx-x86_64/include -m64 -arch x86_64 -DUSE_OREXX -DUNIX -odbusoorexx-mac-x86_64.o dbusoorexx.cc + g++ -c $(CFLAGS) $(INC_PATH) -I/opt/ooRexx-x86_64/include -m64 -arch x86_64 -DDBUSOOREXX_64 -DUSE_OREXX -DUNIX -odbusoorexx-mac-x86_64.o dbusoorexx.cc g++ -dynamiclib $(LFLAGS) -o libdbusoorexx-x86_64.dylib dbusoorexx-mac-x86_64.o /opt/ooRexx-x86_64/lib/ooRexx/librexx.dylib /opt/ooRexx-x86_64/lib/ooRexx/librexxapi.dylib $(LIB_PATH) -framework JavaVM -arch x86_64 # cp -p libdbusoorexx-x86_64.dylib 64/libdbusoorexx.dylib # --------------------------------------------------- ppc: dbusoorexx.cc - g++ -c $(CFLAGS) $(INC_PATH) -I/opt/ooRexx-x86_64/include -I/opt/ooRexx-ppc/include -m32 -arch ppc -DUSE_OREXX -DUNIX -odbusoorexx-mac-ppc.o dbusoorexx.cc + g++ -c $(CFLAGS) $(INC_PATH) -I/opt/ooRexx-x86_64/include -I/opt/ooRexx-ppc/include -m32 -arch ppc -DDBUSOOREXX_32 -DUSE_OREXX -DUNIX -odbusoorexx-mac-ppc.o dbusoorexx.cc g++ -dynamiclib $(LFLAGS) -o libdbusoorexx-ppc.dylib dbusoorexx-mac-ppc.o /opt/ooRexx-ppc/lib/ooRexx/librexx.dylib /opt/ooRexx-ppc/lib/ooRexx/librexxapi.dylib $(LIB_PATH) -framework JavaVM -arch ppc Modified: sandbox/rgf/misc/dbusoorexx/tests/testDBusRoutines.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/testDBusRoutines.rex 2011-08-15 21:36:42 UTC (rev 31) +++ sandbox/rgf/misc/dbusoorexx/tests/testDBusRoutines.rex 2011-08-15 21:46:06 UTC (rev 32) @@ -68,7 +68,8 @@ do s over signatures say " DbusValidateSignature:" pp2(s) pp2(DbusValidate(s,"s")) end +say "---" +say "DBusVersion():" pp2(DBusVersion()) - ::requires "dbus.cls" -- get access to the DBUS functionality from Rexx ::requires "rgf_util2.rex" -- get utilities This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2011-08-17 10:58:19
|
Revision: 34 http://bsf4oorexx.svn.sourceforge.net/bsf4oorexx/?rev=34&view=rev Author: orexx Date: 2011-08-17 10:58:12 +0000 (Wed, 17 Aug 2011) Log Message: ----------- 20110817 Added new 'isOpen()' method for a dbus-connection, employing it in disconnecting stalled client connections, if running private servers (needed as the 'org.freedesktop.DBus.Local.Disconnected' signal does not fire reliably in dbus 1.4.12). Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc sandbox/rgf/misc/dbusoorexx/tests/org.rexxla.oorexx.dbus.test.pong.properties.service sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPingSimple.rex Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-17 10:54:52 UTC (rev 33) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-17 10:58:12 UTC (rev 34) @@ -9,9 +9,11 @@ - BSF4ooRexx, if using the utf8-conversion routines, download from <https://sourceforge.net/projects/bsf4oorexx/> + credits: Mike F. Cowlishaw: for making his "utf8"-Rexx procedure available (cf. routine "stringToutf8") + cf.: dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> (as of 2011-07-14) - version: 091.20110804 + version: 099.20110817 changes: - 2011-07-20, rgf; DBusProxyObject: - added proxy.dispatch(methodName[,args...])-method to send messages that would be otherwise executed on the Rexx side, ie. all of .Object's methods @@ -45,7 +47,13 @@ - added "watchConnections" method to DBusServer, which asynchroneously probes client connections to see whether the clients are gone in the meantime; commented, because there are impacts on the clients and dbus should work correctly by sending the - "Disconnected" signal on a client connection that is discarded + "Disconnected" signal on a client connection that is discarded; removed it as probing + has adverse effects + - 2011-08-14, rgf + - adding Mike F. Cowlishaw's "utf8" procedure for "stringToUtf8", in case BSF.CLS is + not required + - 2011-08-17, rgf + - re-activated "watchConnections" method, this time employing "dbus_connection_get_is_connected(conn)" instead license: Apache License 2.0 @@ -74,7 +82,7 @@ */ .local~dbus.dir=.directory~new -.dbus.dir~version="095.20110813" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' +.dbus.dir~version="099.20110817" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' .dbus.dir~DBUS_SERVICE_DBUS ="org.freedesktop.DBus" -- "The bus name used to talk to the bus itself." .dbus.dir~DBUS_PATH_DBUS ="/org/freedesktop/DBus" -- "The object path used to talk to the bus itself." @@ -399,21 +407,24 @@ if busType="private" then -- if a private connection, then truly close it do -- send the "Disconnected" signal to the server, doesn't work :( -self~message("signal", "/org/freedesktop/DBus/Local", "org.freedesktop.DBus.Local", "Disconnected", "") +-- self~message("signal", "/org/freedesktop/DBus/Local", "org.freedesktop.DBus.Local", "Disconnected", "") self~nativeCloseConnection -- say self ":" "! ---> NATIVE CLOSE CONNECTION GOT CARRIED OUT <--- !" "busType:" pp2(busType) "self:" pp2(self) "server:" pp2(server) end +::method nativeIsConnected private external "LIBRARY dbusoorexx DbusConnectionIsConnected" +::method isOpen -- returns .true if connected (open), .false else + return self~nativeIsConnected ::method uninit expose busType cself - say self"::UNINIT ! cself="pp2(cself) "busType="pp2(busType) "self:" pp2(self) +-- say self"::UNINIT ! cself="pp2(cself) "busType="pp2(busType) "self:" pp2(self) - if cself<>.nil then -- a DBUS connection pointer in hand ? - self~close -- make sure connection gets closed + if cself<>.nil then -- a DBUS connection pointer in hand ? + self~close -- make sure connection gets closed /* add listener object, syntax: - a[dd] | r[emove], object [,[interface] [,signalname]] @@ -844,9 +855,35 @@ /* as of 2011-07-05 ooRexx from trunk does not support UTF-8, hence depending on BSF4ooRexx */ ::routine stringToUtf8 public -- needs BSF4ooRexx parse arg str + + if .bsf=".BSF" then -- no BSF available (need to uncomment the ::requires BSF.CLS statement above), hence using the Rexx conversion procedure + return utf8(str) + return BsfRawBytes(.java.lang.String~new(str)~getBytes("UTF-8")) +-- the following code was made available by Mike F. Cowlishaw in his e-mail on the ooRexx +-- Sourceforge developer list on 2011-07-05, many thanks! +/* --------------------------------------------------------------- */ +/* UTF-8 encoder (for 00-FF only) */ +/* --------------------------------------------------------------- */ +utf8: procedure + parse arg data + out='' + do while data\=='' -- generate escapes + parse var data char +1 data + d=c2d(char) + if d>=128 then do + bits=x2b(c2x(char)) + c1=x2c(b2x('110000'left(bits, 2))) + c2=x2c(b2x('10'substr(bits, 3))) + char=c1||c2 + end + out=out||char + end + return out + + /* ---------------------------------------------------------------------------------------- */ ::routine utf8ToString public -- needs BSF4ooRexx parse arg str @@ -1649,7 +1686,7 @@ ::class "DBusServer" public ::method init expose cself address allowAnonymous defaultService defaultListener connections - - watchLoopActive watchlist timeoutLoopActive -- watchConnections + watchLoopActive watchlist timeoutLoopActive watchConnections use strict arg address, defaultService=.nil, defaultListener=.nil, allowAnonymous=.false .ArgUtil~validateClass("address", address, .string) @@ -1658,7 +1695,7 @@ raise syntax 88.900 array ('Argument "allowAnonymous" must be a logical value, found "'allowAnonymous'"') connections=.array~new - -- watchConnections=.false + watchConnections=.false internalRegisteredServiceObjects=.directory~new internalSignalListeners =.array~new cself=.nil -- will be set by native code @@ -1679,7 +1716,7 @@ ::attribute watchLoopActive get -- indicates whether the server message loop is active or not ::method newConnection -- new connection to this server received (from native code) - expose defaultService defaultListener connections -- watchConnections + expose defaultService defaultListener connections watchConnections use strict arg conn -- signal on syntax @@ -1706,13 +1743,8 @@ conn~listener("add", defaultListener) -- will start message loop automatically end -/* rgf (2011-08-13): do not apply this, as it impacts valid client connections! if watchConnections=.false then -- start the watchConnections thread - do self~watchConnections - -- self~watchConnections(60) - end -*/ -- say pp2(self)"::newConnection - conn~messageLoop('active'):" pp2(conn~messageLoop('active')) -- say pp2(self)"::newConnection -" pp2(conn) "about to leave." @@ -1730,7 +1762,7 @@ expose connections use strict arg conn -say "..." self"::disconnect, 'conn'="pp2(conn) +-- say "..." self"::disconnect, 'conn'="pp2(conn) conn~messageLoop("stop") -- stop the connection's message loop res=connections~removeItem(conn) -- remove the disconnected connection to the client conn~close -- make sure we cannot use it anymore (it wouldn't work) @@ -1752,18 +1784,18 @@ self~nativeStartServerWatchLoop -- start the server message loop on the new thread -/* -- not good (rgf, 2011-08-13): if the server calls into a running client, dbus timeouts and NoReply may errors occur that impact the client + -- as of DBus 1.4.14, the private server does not receive a "Disconnected" signal ::method watchConnections unguarded -- check whether client connections are available, if not disconnect the stalled connecition expose connections watchConnections - use strict arg sleepTime=1 + use strict arg sleepTime=.1 -- check every 1/10 second guard on watchConnections=.true -- indicate that the watch Connections thread is started guard off reply -say "... ... probing" pp2(conn) "sleepTime:" pp2(sleepTime) "..." +-- say "... ... probing" pp2(conn) "sleepTime:" pp2(sleepTime) "..." do forever while connections~items>0 -- as long as client connections, probe them call sysSleep sleepTime -- sleep @@ -1771,8 +1803,12 @@ arr=connections~copy -- get a copy of all connections guard off do conn over arr -- iterate over all client connections and probe them -say "... ... probing" pp2(conn) "..." - call probe self, conn +-- say "... ... testing" pp2(conn)": conn~isOpen:" pp2(conn~isOpen) "..." + if conn~isOpen=.false then + do +-- say "... ... BINGO! " pp2(conn) "not connected/open anymore, DISCONNECTing connection !" + self~disconnect(conn) + end end end guard on @@ -1781,37 +1817,8 @@ return -probe: procedure - use arg thisServer, conn - signal on syntax -say "self: probing via signal ..." -conn~message("signal", "/", "org.rexxla.orrexx.dbus.server", "ProbePing", "s", .datetime~new~string) - - -- send a message expecting a reply to the client (the message will evoke an error) - res=conn~message("call", "private.org.rexxla.oorexx.dbus.server", "/private", "org.rexxla.oorexx.dbus.server", "ProbePing", "s", "s", .dateTime~new~string) -say "self: probing via method call seems o.k., res="pp2(res) "..." - - return - -syntax: - co=condition('object') - say "..." self":watchConnections, received error from" pp2(conn) - say ppCondition2(co) - - str="method/DbusBusCallMessage(), error 10: could not receive a valid pending message object from 'dbus_connection_send_with_reply()'" - if pos(str, co~message)>0 then -- check whether error indicates that no reply object can be created, then disconnect the client! - do - thisServer~disconnect(conn) -- disconnect the client connection (will stop its message loop as well) - say "..." self":watchConnections, removed client connection:" pp2(conn) "using server:" pp2(thisServer) - say "---" - end - return -*/ - - - ::method nativeStartServerTimeoutLoop private external "LIBRARY dbusoorexx DbusServerTimeoutLoop" ::method timerLoop unguarded -- "START" or "STOP" expose timeoutLoopActive Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2011-08-17 10:54:52 UTC (rev 33) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2011-08-17 10:58:12 UTC (rev 34) @@ -23,7 +23,7 @@ 2011-08-04, rgf: - added statistics support 2011-08-07, rgf: - finalized private/standalone dbus ability - version: 095.20110807 + version: 099.20110817 license: Apache License 2.0 ------------------------ Apache Version 2.0 license ------------------------- @@ -75,11 +75,11 @@ #ifdef DBUSOOREXX_32 - #define DBUS_REXXVERSION "095.20110811 32-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110817 32-bit" // version: "MajorNumber"."YYYYMMDD" #elif defined (DBUSOOREXX_64) - #define DBUS_REXXVERSION "095.20110811 64-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110817 64-bit" // version: "MajorNumber"."YYYYMMDD" #else - #define DBUS_REXXVERSION "095.20110811 n/a-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110817 n/a-bit" // version: "MajorNumber"."YYYYMMDD" #endif #ifndef TID @@ -599,6 +599,22 @@ } + // if open, returns true, false else; cf. <http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#ga611ae94556af36fe30bfb547366ca4e1> +RexxMethod1(RexxObjectPtr, DbusConnectionIsConnected, CSELF, connPtr) +{ +#if defined (DEBUG_METHODS) + fprintf(stderr, "===> arrived in DbusConnectionIsConnected\n"); + fflush(stderr); +#endif + DBusConnection *conn=(DBusConnection *) connPtr; + if (conn!=NULL && connPtr!=context->Nil() && dbus_connection_get_is_connected(conn)) + { + return context->True(); + } + return context->False(); +} + + // ============================================================================= // // busname related ---> @@ -6274,6 +6290,8 @@ REXX_METHOD( DbusServerWatchLoop , DbusServerWatchLoop ), // 2011-08-11 REXX_METHOD( DbusServerTimeoutLoop , DbusServerTimeoutLoop ), + // 2011-08-17 + REXX_METHOD( DbusConnectionIsConnected , DbusConnectionIsConnected ), REXX_LAST_METHOD() }; Modified: sandbox/rgf/misc/dbusoorexx/tests/org.rexxla.oorexx.dbus.test.pong.properties.service =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/org.rexxla.oorexx.dbus.test.pong.properties.service 2011-08-17 10:54:52 UTC (rev 33) +++ sandbox/rgf/misc/dbusoorexx/tests/org.rexxla.oorexx.dbus.test.pong.properties.service 2011-08-17 10:58:12 UTC (rev 34) @@ -1,6 +1,5 @@ [D-BUS Service] Name=org.rexxla.oorexx.dbus.test.pong.properties # adapt paths to your installation, rgf, 2011-07-27 -# Exec=/usr/bin/rexx /mnt/root_e/rony/dev/dbus20110602/tutorials-dbus/c-api/work/dbusoorexx/tests/testPropertiesServerPong.rex -Exec=/mnt/root_e/rony/dev/dbus20110602/tutorials-dbus/c-api/work/dbusoorexx/tests/testPropertiesServerPong.rex +Exec=/mnt/root_f/work/svn/bsf4oorexx/sandbox/rgf/misc/dbusoorexx/tests/testPropertiesServerPong.rex #copy this service file to /usr/share/dbus-1/services Modified: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPingSimple.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPingSimple.rex 2011-08-17 10:54:52 UTC (rev 33) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPingSimple.rex 2011-08-17 10:58:12 UTC (rev 34) @@ -13,8 +13,10 @@ - this sends any kind of arguments to the testRawPongServer.rex using - all DBus-methods directly (not taking advanatage of the class - DBusProxyObject + DBusProxyObject) + - test testing whether closing a private connection + usage: rexx testPrivateClientPingSimple.rex needs: testPrivatePongServer.rex running and listening on the address this @@ -98,6 +100,9 @@ say say "DbusVersion():" dbusVersion() +say "conn~isOpen: " conn~isOpen +conn~close +say "conn~isOpen: " conn~isOpen "(after closing)" call dumpConnectionStatistics conn This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2011-08-21 10:58:41
|
Revision: 37 http://bsf4oorexx.svn.sourceforge.net/bsf4oorexx/?rev=37&view=rev Author: orexx Date: 2011-08-21 10:58:32 +0000 (Sun, 21 Aug 2011) Log Message: ----------- 20110821 Adapting private dbus connection scripts to use tcpip for testing mix of Linux, MacOSX and Windows dbus-exploiting programs. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPing.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPingSimple.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesClientPing.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesServerPong.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServerPong.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServerPongDoingOtherStuff.rex sandbox/rgf/misc/dbusoorexx/tests/testDBusRoutines.rex Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-18 15:17:38 UTC (rev 36) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-21 10:58:32 UTC (rev 37) @@ -14,6 +14,7 @@ cf.: dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> (as of 2011-07-14) version: 099.20110817 + changes: - 2011-07-20, rgf; DBusProxyObject: - added proxy.dispatch(methodName[,args...])-method to send messages that would be otherwise executed on the Rexx side, ie. all of .Object's methods @@ -54,6 +55,9 @@ not required - 2011-08-17, rgf - re-activated "watchConnections" method, this time employing "dbus_connection_get_is_connected(conn)" instead + - 2011-08-18, rgf + - define attribute 'sendEmptyReply' on DBus, default: .true; if .true, then a method + call to a Rexx server object will reply, even if no return values are defined for it license: Apache License 2.0 @@ -82,7 +86,7 @@ */ .local~dbus.dir=.directory~new -.dbus.dir~version="099.20110817" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' +.dbus.dir~version="099.20110818" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' .dbus.dir~DBUS_SERVICE_DBUS ="org.freedesktop.DBus" -- "The bus name used to talk to the bus itself." .dbus.dir~DBUS_PATH_DBUS ="/org/freedesktop/DBus" -- "The object path used to talk to the bus itself." @@ -254,6 +258,21 @@ 'address', 'uniqueBusName' and 'wellKnownBusName', if given */ +/* controls whether a received message call without defined return value will return an empty message reply */ +::attribute sendEmptyReply get +::attribute sendEmptyReply set -- default: .true (append slotDir as last argument) + expose sendEmptyReply + use strict arg argSendEmptyReply=.true + + signal on syntax + if \datatype(argSendEmptyReply, "O") then + raise syntax 88.900 array ('Argument "argSendEmptyReply" must be a logical value, found "'argSendEmptyReply'"') + + sendEmptyReply=argSendEmptyReply + return +syntax: + raise propagate + /* attribute controls whether the arguments from a signal or a remote method call get appended with a slotDir-directory supplying possibly useful information about the DBUS message; default: .true @@ -314,7 +333,7 @@ expose cself busType makeSlotDir makeReplySlotDir active - internalRegisteredServiceObjects internalSignalListeners - unmarshalByteArrayAsString - - collectStatistics statistics server + collectStatistics statistics server sendEmptyReply cself=.nil /* will be set by a native method */ busType=.nil /* will be set by native method */ @@ -328,6 +347,8 @@ internalSignalListeners =.array~new unmarshalByteArrayAsString =.false /* if .true, then return 'ay' as strings */ + sendEmptyReply =.true /* if .true, then sends an empty reply upon a message call */ + collectStatistics =.true /* if .true, simple statistics are gathered and stored in 'statistics' */ statistics =.directory~new statistics~started=.dateTime~new -- remember this connection's creation time, define initial counter values @@ -1711,7 +1732,7 @@ ::attribute defaultListener -- default Rexx listener object, used, if internalSignalListeners is empty ::attribute connections get -- list of established connections expose connections - return connections~copy -- return a copy of the connections + return connections~copy -- return a copy of the current connections ::attribute watchLoopActive get -- indicates whether the server message loop is active or not @@ -1764,7 +1785,7 @@ -- say "..." self"::disconnect, 'conn'="pp2(conn) conn~messageLoop("stop") -- stop the connection's message loop - res=connections~removeItem(conn) -- remove the disconnected connection to the client + res=connections~removeItem(conn) -- remove the disconnected connection from the client conn~close -- make sure we cannot use it anymore (it wouldn't work) @@ -1778,9 +1799,9 @@ -- return self~nativeServerID -- say "address:" pp2(address) "cself="pp2(cself) - self~nativeServerStartup(address) + self~nativeServerStartup(address) -- create server listening on given address - reply -- create new thread + reply -- create a new thread self~nativeStartServerWatchLoop -- start the server message loop on the new thread @@ -1838,7 +1859,7 @@ -- now fetch RexxPointer value use strict arg action, timeoutDataPointer -say "... timeoutDataPointer:" pp2(timeoutDataPointer) copies("<-/\",10) +-- say "... timeoutDataPointer:" pp2(timeoutDataPointer) copies("<-/\",10) reply -- create a new thread self~nativeStartServerTimeoutLoop(timeoutDataPointer) -- start the timeout loop, pass (*data) via Rexx to native function Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2011-08-18 15:17:38 UTC (rev 36) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2011-08-21 10:58:32 UTC (rev 37) @@ -22,8 +22,10 @@ - added ability to force stopping all Rexx threads HALT_ALL_REXX_THREADS() 2011-08-04, rgf: - added statistics support 2011-08-07, rgf: - finalized private/standalone dbus ability + 2011-08-17, rgf: - rename variable 'interface' to 'interfaceName' as the MSCPP-compiler reserves 'interface' + 2011-08-18, rgf: - send empty reply messages by default, unless DBus' attribute 'sendEmptyReply' is not .true - version: 099.20110817 + version: 099.20110818 license: Apache License 2.0 ------------------------ Apache Version 2.0 license ------------------------- @@ -48,11 +50,24 @@ extern "C" { // make sure no C++ name mangling comes into the way #endif +#ifdef _MSC_VER + #pragma comment(lib, "dbus-1.lib") // as per the hint of Pontus Carlsson in an e-mail from 2011-08-19 +#endif + #define DBUS_API_SUBJECT_TO_CHANGE #include <dbus/dbus.h> -#include <stdbool.h> -#include <unistd.h> +#ifndef DBUS_TYPE_UNIX_FD // e.g. not defined for Windows + #define DBUS_TYPE_UNIX_FD ((int) 'h') +#endif + +#ifndef DBUS_VERSION_STRING // on Windows an older version of dbus has not defined it yet + #define DBUS_VERSION_STRING "<n/a>" +#endif + +// #include <stdbool.h> +// #include <unistd.h> + #include <stdio.h> #include <stdlib.h> @@ -75,11 +90,11 @@ #ifdef DBUSOOREXX_32 - #define DBUS_REXXVERSION "099.20110817 32-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110818 32-bit" // version: "MajorNumber"."YYYYMMDD" #elif defined (DBUSOOREXX_64) - #define DBUS_REXXVERSION "099.20110817 64-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110818 64-bit" // version: "MajorNumber"."YYYYMMDD" #else - #define DBUS_REXXVERSION "099.20110817 n/a-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110818 n/a-bit" // version: "MajorNumber"."YYYYMMDD" #endif #ifndef TID @@ -114,9 +129,7 @@ // #define DEBUG_DICT_2 #define DEBUG_VARIANT #define DEBUG_VARIANT_2 - #define DEBUG_MESSAGELOOP - #define DEBUG_FUNCTIONS #define DEBUG_METHODS @@ -4051,21 +4064,27 @@ CSTRING tmpInterface=dbus_message_get_interface(dbusMsg); CSTRING tmpMember=dbus_message_get_member(dbusMsg); +/* if ( tmpInterface!=NULL && tmpMember!= NULL && !strncmp("org.freedesktop.DBus.Local", tmpInterface, 26) // a client on a private server is disconnected && !strncmp("Disconnected", tmpMember, 12) ) +*/ + if (msgType==DBUS_MESSAGE_TYPE_SIGNAL) { -fprintf(stderr, "---- BINGO BINGO - DISCONNECT received: interface=[%s], member=[%s]\n", - dbus_message_get_interface(dbusMsg), dbus_message_get_member(dbusMsg)); - // TODO: send message "disconnect" to server object supplying the connection object as argument + if (dbus_message_is_signal(dbusMsg,DBUS_INTERFACE_LOCAL,"Disconnected") ) + { + fprintf(stderr, "----> SIGNAL-RECEIVED: BINGO BINGO - DISCONNECT received: interface=[%s], member=[%s]\n", + dbus_message_get_interface(dbusMsg), dbus_message_get_member(dbusMsg)); + } + else + { + fprintf(stderr, "----> SIGNAL-RECEIVED: interface=[%s], member=[%s]\n", + dbus_message_get_interface(dbusMsg), dbus_message_get_member(dbusMsg)); + } } - else - { - fprintf(stderr, "----- ----- ----- - DISCONNECT not received: interface=[%s], member=[%s]\n", - dbus_message_get_interface(dbusMsg), dbus_message_get_member(dbusMsg)); - } + // <---- #endif @@ -4167,18 +4186,18 @@ // unmarshal arguments RexxArrayObject arrArgs=NULL; + // { + arrArgs=helperUnmarshalMessageArgs(dbusMsg, + context->threadContext, + (context->GetObjectVariable("UNMARSHALBYTEARRAYASSTRING")==context->True()), + "%.16s/method/DbusMessageLoop(), error 99: %s" // base condition message + ); + + if (arrArgs==NULL) // make sure we have at least an empty array { - arrArgs=helperUnmarshalMessageArgs(dbusMsg, - context->threadContext, - (context->GetObjectVariable("UNMARSHALBYTEARRAYASSTRING")==context->True()), - "%.16s/method/DbusMessageLoop(), error 99: %s" // base condition message - ); - - if (arrArgs==NULL) // make sure we have at least an empty array - { - arrArgs=context->NewArray(0); - } + arrArgs=context->NewArray(0); } + // } if (bMakeSlotDir && slotDir!=NULL) { @@ -4186,9 +4205,9 @@ } // get Interface and Member - CSTRING interface=dbus_message_get_interface(dbusMsg); + CSTRING interfaceName=dbus_message_get_interface(dbusMsg); - RexxStringObject rxInterface=( interface==NULL ? context->NullString() : context->String(interface) ) ; + RexxStringObject rxInterface=( interfaceName==NULL ? context->NullString() : context->String(interfaceName) ) ; CSTRING member =dbus_message_get_member(dbusMsg); RexxStringObject rxMember= (member==NULL ? context->NullString() : context->String(member)); @@ -4264,13 +4283,16 @@ // message to the server supplying this connection as an argument if (bClientForPrivateRexxServer) { +/* if ( interface!=NULL && member!= NULL && !strncmp("org.freedesktop.DBus.Local", interface, 26) // a client on a private server is disconnected && !strncmp("Disconnected", member, 12) ) +*/ + if (dbus_message_is_signal(dbusMsg,DBUS_INTERFACE_LOCAL,"Disconnected") ) { #if defined (DEBUG_RGF) // debug private server connection to client - fprintf(stderr, "---- BINGO BINGO #2 - DISCONNECT received: interface=[%s], member=[%s]\n",interface, member); + fprintf(stderr, "---- BINGO BINGO #2 - DISCONNECT received: interfaceName=[%s], member=[%s]\n",interfaceName, member); #endif // send DISCONNECT message to server, supplying this connection instance as an argument context->SendMessage1(context->SendMessage0(self, "SERVER"), "DISCONNECT", self); @@ -4307,10 +4329,10 @@ fprintf(stderr, " ... message is a CALL, service object for object path [%s] does not exist! \n", objectPath); fflush(stderr); #endif char errMsg[512]=""; - SNPRINTF(errMsg, 512, "Rexx service object [%s] does not exist (you intended to invoke member=[%s] in the interface=[%s]", + SNPRINTF(errMsg, 512, "Rexx service object [%s] does not exist (you intended to invoke member=[%s] in the interfaceName=[%s]", objectPath, member, - interface); + interfaceName); DBusMessage *errReply=dbus_message_new_error(dbusMsg, "org.freedesktop.DBus.Error.ServiceUnknown", @@ -4320,7 +4342,7 @@ // send the reply && flush the connection if (!dbus_connection_send(conn, errReply, &serial)) { - fprintf(stderr, "%s: out of memory while sending DBUS error return message!\n", DLLNAME); + fprintf(stderr, "%s/DbusMessageLoop: out of memory while sending DBUS error return message!\n", DLLNAME); } dbus_connection_flush(conn); @@ -4381,14 +4403,49 @@ if (dbus_message_get_no_reply(dbusMsg)) // dispatch via separate thread, we don't care about Rexx conditions there ... { #ifdef DEBUG_MESSAGELOOP - fprintf(stderr, "\n ... message is a CALL, 1 - sending message [%s] (interface=[%s]) to service object for [%s] ASYNCHRONEOUSLY (no reply expected) ... \n", member, interface, objectPath); fflush(stderr); + fprintf(stderr, "\n ... message is a CALL, 1 - sending message [%s] (interfaceName=[%s]) to service object for [%s] ASYNCHRONEOUSLY (no reply expected) ... \n", member, interfaceName, objectPath); fflush(stderr); #endif context->SendMessage(rop, "STARTWITH", arr2); + + // send an empty reply-message, controlled by connection's attribute 'sendEmptyReply' + if (context->GetObjectVariable("SENDEMPTYREPLY")==rxTrue) + { +#ifdef DEBUG_MESSAGELOOP + fprintf(stderr, "\n ... message is a CALL, 1 - return EMPTY REPLY for message [%s] (interfaceName=[%s]) to service object for [%s] ASYNCHRONEOUSLY (controlled by attribute \"sendEmptyReply\") ... \n", member, interfaceName, objectPath); fflush(stderr); +#endif + DBusMessage *returnMsg=dbus_message_new_method_return(dbusMsg); + dbus_uint32_t serial = 0; + if (!dbus_connection_send(conn, returnMsg, &serial)) + { + fprintf(stderr, "%s/DbusMessageLoop: out of memory while sending DBUS return message!\n", DLLNAME); + } + dbus_connection_flush(conn); + + if (bCollectStatistics) // allows us to guard on only, if statistics should be collected ! + { + context->SetGuardOn(); // update statistics on call method + RexxDirectoryObject rdo=(RexxDirectoryObject) context->GetObjectVariable("STATISTICS"); + RexxDirectoryObject slotDir=context->NewDirectory(); + helperCreateSlotDirEntries(context->threadContext, slotDir, returnMsg); // setup slotDir + + CSTRING sentKind ="SENT"; + CSTRING kind ="LASTSENTMESSAGE"; + CSTRING countKind="COUNTSENTMESSAGES"; + context->DirectoryPut(rdo,slotDir,kind); // make error messages slotDir available + context->DirectoryPut(rdo,context->DirectoryAt(slotDir,"DATETIME"),sentKind); // adjust "RECEIVED" datetime-stamp + // increase kind's count + RexxObjectPtr count=context->DirectoryAt(rdo,countKind); + count=context->SendMessage1(count, "+", context->Int32ToObject(1)); + context->DirectoryPut(rdo,count,countKind); + context->SetGuardOff(); + } + dbus_message_unref(returnMsg); + } } else // dispatch synchroneously { #ifdef DEBUG_MESSAGELOOP - fprintf(stderr, "\n ... message is a CALL, 2 - about to send message [%s] (interface=[%s]) to service object for [%s] ... \n", member, interface, objectPath); fflush(stderr); + fprintf(stderr, "\n ... message is a CALL, 2 - about to send message [%s] (interfaceName=[%s]) to service object for [%s] ... \n", member, interfaceName, objectPath); fflush(stderr); #endif rxResult=context->SendMessage(rop, "SENDWITH", arr2); @@ -4396,7 +4453,7 @@ if (context->CheckCondition()) // oops a Rexx condition got raised { #ifdef DEBUG_MESSAGELOOP - fprintf(stderr, " ... message is a CALL, 2a - message [%s] (interface=[%s]) to service object for [%s], caused a Rexx CONDITION :-( ... \n", member, interface, objectPath); fflush(stderr); + fprintf(stderr, " ... message is a CALL, 2a - message [%s] (interfaceName=[%s]) to service object for [%s], caused a Rexx CONDITION :-( ... \n", member, interfaceName, objectPath); fflush(stderr); #endif RexxDirectoryObject condObj=context->GetConditionInfo(); // condition object ! @@ -4447,10 +4504,10 @@ else // an unexpected Rexx error has occurred, communicate it to the client { char errMsg[512]=""; - SNPRINTF(errMsg, 512, "Rexx service object [%s] running method=[%s] in the interface=[%s] raised a Rexx condition", + SNPRINTF(errMsg, 512, "Rexx service object [%s] running method=[%s] in the interfaceName=[%s] raised a Rexx condition", objectPath, member, - interface); + interfaceName); char *rexxLikeErrorMsg=RgfCreateRexxlikeErrorInfo (context->threadContext, condObj, errMsg); @@ -4465,7 +4522,7 @@ // send the error reply && flush the connection if (!dbus_connection_send(conn, errReply, &serial)) { - fprintf(stderr, "%s: out of memory while sending DBUS error return message!\n", DLLNAME); + fprintf(stderr, "%s/DbusMessageLoop: out of memory while sending DBUS error return message!\n", DLLNAME); } dbus_connection_flush(conn); @@ -4509,13 +4566,13 @@ else if (rxResult==NULLOBJECT) // || rxResult==rxNil) // no return value, do not reply { #ifdef DEBUG_MESSAGELOOP - fprintf(stderr, " ... message is a CALL, 2b - message [%s] (interface=[%s]) to service object for [%s], no condition, no return value, PROBLEM as caller expects one! :( \n", member, interface, objectPath); fflush(stderr); + fprintf(stderr, " ... message is a CALL, 2b - message [%s] (interfaceName=[%s]) to service object for [%s], no condition, no return value, PROBLEM as caller expects one! :( \n", member, interfaceName, objectPath); fflush(stderr); #endif char errMsg[512]=""; - SNPRINTF(errMsg, 512, "Rexx service object [%s] running method=[%s] in the interface=[%s] did not return a value, although client expects one", + SNPRINTF(errMsg, 512, "Rexx service object [%s] running method=[%s] in the interfaceName=[%s] did not return a value, although client expects one", objectPath, member, - (interface==NULL ? "" : interface) + (interfaceName==NULL ? "" : interfaceName) ); DBusMessage *errReply=dbus_message_new_error(dbusMsg, @@ -4526,7 +4583,7 @@ // send the error reply && flush the connection if (!dbus_connection_send(conn, errReply, &serial)) { - fprintf(stderr, "%s: out of memory while sending DBUS error return message!\n", DLLNAME); + fprintf(stderr, "%s/DbusMessageLoop: out of memory while sending DBUS error return message!\n", DLLNAME); } dbus_connection_flush(conn); @@ -4561,7 +4618,7 @@ { #ifdef DEBUG_MESSAGELOOP - fprintf(stderr, " ... message is a CALL, 3 - message [%s] (interface=[%s]) to service object for [%s], no condition, a return value to be processed! :( \n", member, interface, objectPath); fflush(stderr); + fprintf(stderr, " ... message is a CALL, 3 - message [%s] (interfaceName=[%s]) to service object for [%s], no condition, a return value to be processed! :( \n", member, interfaceName, objectPath); fflush(stderr); fprintf(stderr, " ... message is a CALL, 3i - rxResult=[%p], rxResult~class=[%s], if array, arr[1]=[%s], arr[2]=[%s]\n", rxResult, @@ -4601,7 +4658,7 @@ // this branch expects .array~of("replySignature=x", returnValueMatchingSignature) #ifdef DEBUG_MESSAGELOOP - fprintf(stderr, " ... message is a CALL, IsArray(rxResult): message [%s] (interface=[%s]) to service object for [%s], no condition, returned an array object ... \n", member, interface, objectPath); fflush(stderr); + fprintf(stderr, " ... message is a CALL, IsArray(rxResult): message [%s] (interfaceName=[%s]) to service object for [%s], no condition, returned an array object ... \n", member, interfaceName, objectPath); fflush(stderr); #endif dimension=context->ArrayDimension((RexxArrayObject) rxResult); @@ -4637,7 +4694,7 @@ // use second element of returned array object as return value matching the signature #ifdef DEBUG_MESSAGELOOP - fprintf(stderr, " ... message is a CALL, message [%s] (interface=[%s]) to service object for [%s] | signature=[%s] -> BINGO-SUPER-BINGO ! \n", member, interface, objectPath, signature); fflush(stderr); + fprintf(stderr, " ... message is a CALL, message [%s] (interfaceName=[%s]) to service object for [%s] | signature=[%s] -> BINGO-SUPER-BINGO ! \n", member, interfaceName, objectPath, signature); fflush(stderr); #endif // create new array with array arguments @@ -4688,11 +4745,11 @@ else if (rso!=context->Nil() && rso!=NULL) { #ifdef DEBUG_MESSAGELOOP - fprintf(stderr, " ... message is a CALL, 3a - DBusServiceObject-branch, rso=[%p]=[%s], CheckCondition=[%d] - message [%s] (interface=[%s]) to service object for [%s], no condition, a return value to be processed! :( \n", + fprintf(stderr, " ... message is a CALL, 3a - DBusServiceObject-branch, rso=[%p]=[%s], CheckCondition=[%d] - message [%s] (interfaceName=[%s]) to service object for [%s], no condition, a return value to be processed! :( \n", rso, (rso==NULL ? NULL : context->ObjectToStringValue(rso)), (int) context->CheckCondition(), - member, interface, objectPath); fflush(stderr); + member, interfaceName, objectPath); fflush(stderr); #endif // get and check signature @@ -4758,7 +4815,7 @@ if (!*signature) // signature not yet set, hence encode all elements as strings { #ifdef DEBUG_MESSAGELOOP - fprintf(stderr, " ... message is a CALL, message [%s] (interface=[%s]) to service object for [%s], no explicit return signature given ... \n", member, interface, objectPath); fflush(stderr); + fprintf(stderr, " ... message is a CALL, message [%s] (interfaceName=[%s]) to service object for [%s], no explicit return signature given ... \n", member, interfaceName, objectPath); fflush(stderr); #endif if (dimension>0 && dimension<254) // an array in hand, return it as a*s { @@ -4799,7 +4856,7 @@ } #ifdef DEBUG_MESSAGELOOP - fprintf(stderr, " ... message is a CALL, message [%s] (interface=[%s]) to service object for [%s], MARSHALLING return value with signature [%s] ...\n", member, interface, objectPath, signature); fflush(stderr); + fprintf(stderr, " ... message is a CALL, message [%s] (interfaceName=[%s]) to service object for [%s], MARSHALLING return value with signature [%s] ...\n", member, interfaceName, objectPath, signature); fflush(stderr); #endif // now marshal return value in rxResult with the given signature // let the helper function do the work (and raise an error, if necessary) @@ -4839,7 +4896,7 @@ { // if bRexxCondition is set, then the RexxCondition() is not cleared and will cause the respective condition in Rexx to be raised upon return - if(bMarshallingError==true) // create error message to inform caller that something went wrong in marshalling the return value ! + if(bMarshallingError) // ==true) // create error message to inform caller that something went wrong in marshalling the return value ! { char errMsg[512]=""; SNPRINTF(errMsg, 512, "Rexx service object [%s] supplied a return value that could not be marshalled with signature [%s]", @@ -4891,13 +4948,13 @@ char msg[1024]=""; // buffer for error message /* raise exception */ - SNPRINTF( msg, 1024, "%.16s/DbusMessageLoop, panic! Unexpected marshalling error for return value [%.64s] with signature [%.256s] by service object [%s] after returning from Rexx method [%s] (interface=[%s])", + SNPRINTF( msg, 1024, "%.16s/DbusMessageLoop, panic! Unexpected marshalling error for return value [%.64s] with signature [%.256s] by service object [%s] after returning from Rexx method [%s] (interfaceName=[%s])", DLLNAME, context->ObjectToStringValue(rxResult), signature, objectPath, member, - interface + interfaceName ); context->SetObjectVariable("active", context->False()); // indicate message processing has stopped @@ -4908,7 +4965,7 @@ #ifdef DEBUG_MESSAGELOOP - fprintf(stderr, " ... message is a CALL, message [%s] (interface=[%s]) to service object for [%s]: ***SUCCESS*** (RETURN MESSAGE GOT SUCCESSFULLY SENT)!\n", member, interface, objectPath); fflush(stderr); + fprintf(stderr, " ... message is a CALL, message [%s] (interfaceName=[%s]) to service object for [%s]: ***SUCCESS*** (RETURN MESSAGE GOT SUCCESSFULLY SENT)!\n", member, interfaceName, objectPath); fflush(stderr); #endif } } @@ -5012,7 +5069,7 @@ // create a signal & check for errors dbusMsg = dbus_message_new_signal(senderObjectPath, // object name of the signal - signalInterfaceName, // interface name of the signal + signalInterfaceName, // interfaceName name of the signal signalName ); // name of the signal fprintf(stderr, "... sending DbusBusSignalMessage(): dbusMsg=[%p] - [%s], [%s], [%s] ... \n", dbusMsg, senderObjectPath, signalInterfaceName, signalName); @@ -5087,7 +5144,7 @@ // ----------------------------------------------------------------------------------------------------- // ============================================================================= // // call a method -// use strict arg nixi, busName, receiverObjectPath, interface="", methodName, signature="", ... +// use strict arg nixi, busName, receiverObjectPath, interfaceName="", methodName, signature="", ... RexxMethod8(RexxObjectPtr, DbusBusCallMessage, CSTRING, busName, CSTRING, targetObjectPath, CSTRING, callInterfaceName, @@ -5195,13 +5252,13 @@ // create a call message & check for errors dbusMsg= dbus_message_new_method_call( busName, // busName to address (destination) targetObjectPath, // object name of the call - (!*callInterfaceName ? NULL : callInterfaceName), // interface name of the call + (!*callInterfaceName ? NULL : callInterfaceName), // interfaceName name of the call callMemberName ); // name of the call if (NULL == dbusMsg) { char msg[1024]=""; // buffer for error message - SNPRINTF( msg, 1024, "%.16s/method/DbusBusCallMessage(), error 6: cannot create call message 'dbus_message_new_method_call()' returned NULL; check spelling of bus name=[%s], object path=[%s], interface=[%s], method=[%s]", + SNPRINTF( msg, 1024, "%.16s/method/DbusBusCallMessage(), error 6: cannot create call message 'dbus_message_new_method_call()' returned NULL; check spelling of bus name=[%s], object path=[%s], interfaceName=[%s], method=[%s]", DLLNAME, busName, targetObjectPath, callInterfaceName, callMemberName); // raise exception Modified: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPing.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPing.rex 2011-08-18 15:17:38 UTC (rev 36) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPing.rex 2011-08-21 10:58:32 UTC (rev 37) @@ -55,11 +55,18 @@ address1="unix:path=/tmp/dbus-test" address2="tcp:host=localhost,port=23000,family=ipv4;" -- socket lingers after shutdown +address3="unix:path=/tmp/dbus-test;tcp:host=localhost,port=23000,family=ipv4;" -- address1="unix:path=/tmp/dbus-test-oopsla" -- address1="tcp:host=localhost,port=23001,family=ipv4;" -- socket lingers after shutdown -address=address1 --- address=address2 +-- address=address1 + +parse arg otherAddress . +if otherAddress<>"" then + address=otherAddress +else + address=address3 + say "creating a connection to the" pp2(busType) "message bus..." say "creating a connection to" pp2(address) "message bus..." conn=.dbus~new(address) -- get a connection Modified: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPingSimple.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPingSimple.rex 2011-08-18 15:17:38 UTC (rev 36) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPingSimple.rex 2011-08-21 10:58:32 UTC (rev 37) @@ -60,8 +60,14 @@ address1="unix:path=/tmp/dbus-test" address2="tcp:host=localhost,port=23000,family=ipv4;" -- socket lingers after shutdown -address=address1 +address3="unix:path=/tmp/dbus-test;tcp:host=localhost,port=23000,family=ipv4;" +parse arg otherAddress . +if otherAddress<>"" then + address=otherAddress +else + address=address3 + say "creating a connection to" pp2(address) "message bus..." conn=.dbus~new(address) -- get a connection Modified: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesClientPing.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesClientPing.rex 2011-08-18 15:17:38 UTC (rev 36) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesClientPing.rex 2011-08-21 10:58:32 UTC (rev 37) @@ -24,8 +24,14 @@ address1="unix:path=/tmp/dbus-test" address2="tcp:host=localhost,port=23000,family=ipv4;" -- socket lingers after shutdown -address=address1 +address3="unix:path=/tmp/dbus-test;tcp:host=localhost,port=23000,family=ipv4;" +parse arg otherAddress . +if otherAddress<>"" then + address=otherAddress +else + address=address3 + say "creating a connection to the private" pp2(address) "message bus..." conn=.dbus~new(address) -- get a connection say "(client) conn~busType="pp2(conn~busType) Modified: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesServerPong.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesServerPong.rex 2011-08-18 15:17:38 UTC (rev 36) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesServerPong.rex 2011-08-21 10:58:32 UTC (rev 37) @@ -39,8 +39,13 @@ address1="unix:path=/tmp/dbus-test" address2="tcp:host=localhost,port=23000,family=ipv4;" -- socket lingers after shutdown address3="unix:path=/tmp/dbus-test;tcp:host=localhost,port=23000,family=ipv4;" -address=address1 +parse arg otherAddress . +if otherAddress<>"" then + address=otherAddress +else + address=address3 + tso=.testServiceObject~new say "starting up server, listening for connections on:" pp2(address) -- note: if a default service listener object is defined for a private server, Modified: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServerPong.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServerPong.rex 2011-08-18 15:17:38 UTC (rev 36) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServerPong.rex 2011-08-21 10:58:32 UTC (rev 37) @@ -44,12 +44,18 @@ address1="unix:path=/tmp/dbus-test" address2="tcp:host=localhost,port=23000,family=ipv4;" -- socket lingers after shutdown address3="unix:path=/tmp/dbus-test;tcp:host=localhost,port=23000,family=ipv4;" -address=address1 +parse arg otherAddress . +if otherAddress<>"" then + address=otherAddress +else + address=address3 + defaultService =.testServiceObject~new defaultListener=.testSignalObject~new say "starting up server, listening for connections on:" pp2(address) server =.DBUSServer~new(address,defaultService,defaultListener) +server~allowAnonymous=.true server~startup say "server~active (after startup):" pp2(server~active) "cself="pp2(server~cself) say "server~serverId: " pp2(server~serverId) @@ -61,6 +67,7 @@ signal on halt say "DbusVersion()="pp2(DbusVersion()) +say "Private server listens at address:" pp2(server~address) say "Hit enter to end program ..." parse pull x Modified: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServerPongDoingOtherStuff.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServerPongDoingOtherStuff.rex 2011-08-18 15:17:38 UTC (rev 36) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServerPongDoingOtherStuff.rex 2011-08-21 10:58:32 UTC (rev 37) @@ -46,8 +46,13 @@ address1="unix:path=/tmp/dbus-test" address2="tcp:host=localhost,port=23000,family=ipv4;" -- socket lingers after shutdown address3="unix:path=/tmp/dbus-test;tcp:host=localhost,port=23000,family=ipv4;" -address=address1 +parse arg otherAddress . +if otherAddress<>"" then + address=otherAddress +else + address=address3 + defaultService =.testServiceObject~new defaultListener=.testSignalObject~new say "starting up server, listening for connections on:" pp2(address) Modified: sandbox/rgf/misc/dbusoorexx/tests/testDBusRoutines.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/testDBusRoutines.rex 2011-08-18 15:17:38 UTC (rev 36) +++ sandbox/rgf/misc/dbusoorexx/tests/testDBusRoutines.rex 2011-08-21 10:58:32 UTC (rev 37) @@ -71,5 +71,6 @@ say "---" say "DBusVersion():" pp2(DBusVersion()) + ::requires "dbus.cls" -- get access to the DBUS functionality from Rexx ::requires "rgf_util2.rex" -- get utilities This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2011-08-22 20:24:04
|
Revision: 39 http://bsf4oorexx.svn.sourceforge.net/bsf4oorexx/?rev=39&view=rev Author: orexx Date: 2011-08-22 20:23:58 +0000 (Mon, 22 Aug 2011) Log Message: ----------- 20110822 Add ability to test whether typeCodes are supported by connections (e.g. UNIX_FDs are not supported everywhere), make loop threads aware of Rexx conditions, and if they are present leave the respective thread. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-21 14:32:51 UTC (rev 38) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-22 20:23:58 UTC (rev 39) @@ -58,6 +58,9 @@ - 2011-08-18, rgf - define attribute 'sendEmptyReply' on DBus, default: .true; if .true, then a method call to a Rexx server object will reply, even if no return values are defined for it + - 2011-08-21, rgf + - added method "supports" to "DBus": currently returns all supported typecodes or tests + individual type codes (e.g. "h" cannot be sent on Windows and therefore is not supported there) license: Apache License 2.0 @@ -872,6 +875,38 @@ +::method nativeCanSendType private external "LIBRARY dbusoorexx DbusConnectionCanSendType" +/* + supports() ... return "typeCodes={a,...,x}" ... returns string denoting available types + supports("T[ypecode]", typecode) ... returns .false/.true; typecode can be a string: only returns .true then, if all characters are supported type codes +*/ +::method supports -- this name is neutral enough to allow extensions, if other connection-related tests are needed + if arg()=0 then + do + str="" + -- get all indexes, remove "", sort array + arr=.dbus.dir~dataTypes~allIndexes~~removeItem("")~sort + do char over arr + if self~nativeCanSendType(char) then -- supported + do + if str<>"" then str=str"," + str=str||char -- add supported type code + end + end + return "typeCode={"str"}" + end + + use strict arg kind="T", char -- fetch arguments + + if kind~strip~left(1)~upper<>"T" then + raise syntax 88.916 array ('"kind"', '"T[ypecode]"', action) + + do i=1 to char~length -- iterate over characters + if self~nativeCanSendType(char~subChar(i))=.false then return .false + end + return .true + + /* ---------------------------------------------------------------------------------------- */ /* as of 2011-07-05 ooRexx from trunk does not support UTF-8, hence depending on BSF4ooRexx */ ::routine stringToUtf8 public -- needs BSF4ooRexx Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2011-08-21 14:32:51 UTC (rev 38) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2011-08-22 20:23:58 UTC (rev 39) @@ -28,6 +28,9 @@ code will not be compiled - adjust Windows version: 32-bit MS compiler abends at runtime if "%zu" is used in fprintf/_snprintf - changed all debug fprintf's from "%zu" to "%lu" to not cause exceptions when debugging on Windows with MSC + 2011-08-22, rgf: - add ability to check whether type code is supported on the connection + - make the message, server and timeout loop aware of Rexx conditions; if a condition is active, leave the loop + setting the loop control variable to .false to reflect this fact in ooRexx code as well version: 099.20110821 license: Apache License 2.0 @@ -65,6 +68,12 @@ #define DBUS_VERSION_STRING "<n/a>" #endif + +#ifndef DBUS_TYPE_UNIX_FD // e.g. not defined for Windows, still incorporate it + #define DBUS_TYPE_UNIX_FD ((int) 'h') +#endif + + #include <stdio.h> #include <stdlib.h> @@ -87,11 +96,11 @@ #ifdef DBUSOOREXX_32 - #define DBUS_REXXVERSION "099.20110821 32-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110822 32-bit" // version: "MajorNumber"."YYYYMMDD" #elif defined (DBUSOOREXX_64) - #define DBUS_REXXVERSION "099.20110821 64-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110822 64-bit" // version: "MajorNumber"."YYYYMMDD" #else - #define DBUS_REXXVERSION "099.20110821 n/a-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110822 n/a-bit" // version: "MajorNumber"."YYYYMMDD" #endif #ifndef TID @@ -625,6 +634,28 @@ } + + // if open, returns true, false else; cf. <http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#ga611ae94556af36fe30bfb547366ca4e1> + // expects one char; if that is a supported type code returns .true, otherwise .false +RexxMethod2(RexxObjectPtr, DbusConnectionCanSendType, CSTRING, typeCode, CSELF, connPtr) +{ +#if defined (DEBUG_METHODS) + fprintf(stderr, "===> arrived in DbusConnectionCanSendType\n"); +DbusConnectionCanSendType + fflush(stderr); +#endif + DBusConnection *conn=(DBusConnection *) connPtr; + if (conn!=NULL && connPtr!=context->Nil() && dbus_connection_can_send_type(conn, *typeCode)) + { + return context->True(); + } + return context->False(); +} + + + + + // ============================================================================= // // busname related ---> @@ -4110,6 +4141,14 @@ } #endif + if (context->CheckCondition()) // is this thread affected by a Halt-condition? If so, leave + { + context->SetGuardOn(); + context->SetObjectVariable("ACTIVE",rxFalse); + context->SetGuardOff(); + break; + } + logical_t bLeave=(context->GetObjectVariable("active") == rxFalse); if (bLeave) @@ -5942,6 +5981,7 @@ } RexxObjectPtr rxTrue =context->True(); + RexxObjectPtr rxFalse =context->False(); CSTRING timeoutLoopActive="TIMEOUTLOOPACTIVE"; // as long as this variable is .true, the loop will get executed context->SetGuardOn(); @@ -5968,6 +6008,14 @@ // allow loop thread to be ended by Rexx, e.g. checking the status of the "active" attribute (if .false return from message loop) while (context->GetObjectVariable(timeoutLoopActive) == rxTrue) // while watch loop active, go ahead { + if (context->CheckCondition()) // is this thread affected by a Halt-condition? If so, leave + { + context->SetGuardOn(); + context->SetObjectVariable(timeoutLoopActive,rxFalse); + context->SetGuardOff(); + break; + } + #if defined (DEBUG_TIMEOUTLOOP) counter++; #endif @@ -6147,10 +6195,11 @@ RexxObjectPtr rxNil =context->Nil(); RexxObjectPtr rxTrue =context->True(); - CSTRING wlaName="WATCHLOOPACTIVE"; // as long as this variable is .true, the loop will get executed + RexxObjectPtr rxFalse=context->False(); + CSTRING watchLoopActive="WATCHLOOPACTIVE"; // as long as this variable is .true, the loop will get executed context->SetGuardOn(); - if (context->GetObjectVariable(wlaName) == rxTrue) // already running ? + if (context->GetObjectVariable(watchLoopActive) == rxTrue) // already running ? { context->SetGuardOff(); return NULLOBJECT; // return, do not start another message loop thread @@ -6191,20 +6240,28 @@ #endif context->SetGuardOn(); - context->SetObjectVariable(wlaName, context->True()); // indicate message processing is active + context->SetObjectVariable(watchLoopActive, context->True()); // indicate message processing is active context->SetGuardOff(); #ifdef DEBUG_WATCHLOOP fprintf(stderr, "... WatchLoop(): about to enter message loop, changed instance variable 'active' to .true: [%s], self=[%s] self~identityHash=[%s] ...\n", - context->ObjectToStringValue(context->GetObjectVariable(wlaName)), + context->ObjectToStringValue(context->GetObjectVariable(watchLoopActive)), context->ObjectToStringValue(self), context->ObjectToStringValue(context->SendMessage0(self,"IDENTITYHASH")) ); fflush(stderr); #endif // allow loop thread to be ended by Rexx, e.g. checking the status of the "active" attribute (if .false return from message loop) - while (context->GetObjectVariable(wlaName) == rxTrue) // while watch loop active, go ahead + while (context->GetObjectVariable(watchLoopActive) == rxTrue) // while watch loop active, go ahead { + if (context->CheckCondition()) // is this thread affected by a Halt-condition? If so, leave + { + context->SetGuardOn(); + context->SetObjectVariable(watchLoopActive,rxFalse); + context->SetGuardOff(); + break; + } + // create Select() attributes fd_set rfds, wfds, efds; // read, write, error fd sets int maxfd = 0; @@ -6277,7 +6334,7 @@ fprintf(stderr, "... WatchLoop(): after select() #2, res=[%d]... \n", res); #endif - if (context->GetObjectVariable(wlaName) != rxTrue) // stop watch loop ? + if (context->GetObjectVariable(watchLoopActive) != rxTrue) // stop watch loop ? { #ifdef DEBUG_WATCHLOOP fprintf(stderr, "... WatchLoop(): after select() #2, learned we need to stop watch loop, breaking! \n"); @@ -6319,7 +6376,7 @@ } // end while #ifdef DEBUG_WATCHLOOP - fprintf(stderr, "... WatchLoop(): about to leav.\n"); fflush(stderr); + fprintf(stderr, "... WatchLoop(): about to leave.\n"); fflush(stderr); #endif return NULL; // do not return anything @@ -6469,6 +6526,8 @@ REXX_METHOD( DbusServerTimeoutLoop , DbusServerTimeoutLoop ), // 2011-08-17 REXX_METHOD( DbusConnectionIsConnected , DbusConnectionIsConnected ), + // 2011-08-22 + REXX_METHOD( DbusConnectionCanSendType , DbusConnectionCanSendType ), REXX_LAST_METHOD() }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2014-08-05 11:24:28
|
Revision: 229 http://sourceforge.net/p/bsf4oorexx/code/229 Author: orexx Date: 2014-08-05 11:24:16 +0000 (Tue, 05 Aug 2014) Log Message: ----------- 20140805 Minor changes/additions, adding 32- and 64-bit binaries for convenience (turned out to become hard to compile for 32-bit). Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPong.rex Added Paths: ----------- sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx32.so sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx64.so Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-08-01 14:44:27 UTC (rev 228) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-08-05 11:24:16 UTC (rev 229) @@ -86,6 +86,9 @@ - if an error condition is raised in the message loop thread, it will get re-raised on the blocked thread upon return - added public routine DBusVersion() which includes the library and this package version + - 2014-08-05, rgf: - adding .DBus to .local such that in native code FindClass("DBUS") will + remain able to find this class in the case that the reported bug + <http://sourceforge.net/p/oorexx/bugs/1275> gets fixed license: Apache License 2.0 @@ -108,6 +111,8 @@ */ +.local~dbus=.dbus -- save .DBus class in .local to allow native code to use FindClass("DBUS") successfully + /* Defining dbus shared constants, leaving the dbus names untouched, such that dbus-samples employing these constants can be easily transcribed to Rexx. Cf. <http://dbus.freedesktop.org/doc/api/html/group__DBusShared.html> @@ -117,7 +122,7 @@ .dbus.dir~bDebug=.false -- .true -- .false -- .true .dbus.dir~bDebugServer=.false -- .true -- .false -- .true -.dbus.dir~version="100.20140730" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' +.dbus.dir~version="100.20140805" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' .dbus.dir~DBUS_SERVICE_DBUS ="org.freedesktop.DBus" -- "The bus name used to talk to the bus itself." .dbus.dir~DBUS_PATH_DBUS ="/org/freedesktop/DBus" -- "The object path used to talk to the bus itself." @@ -202,6 +207,7 @@ ::routine dynamicRequiresBSF4ooRexx -- BSF4ooRexx: needed need for UTF-8 conversion routines signal on any +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) .context~package~loadPackage("BSF.CLS") -- if not found a syntax condition is raised and -- control transferred to (immediately following) "ANY:" label any: @@ -351,6 +357,7 @@ ::attribute pseudoAddress set -- 20140728, rgf: allows private server to set a pseudo address for each connected client expose address use strict arg address -- just assign whatever we receive +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) /* --- instance methods --- */ /* much is implemented in native code, including setting attributes 'address', @@ -455,6 +462,7 @@ ::attribute sendEmptyReply set -- default: .true (append slotDir as last argument) expose sendEmptyReply use strict arg argSendEmptyReply=.true +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax if \datatype(argSendEmptyReply, "O") then @@ -473,6 +481,7 @@ ::attribute makeSlotDir set -- default: .true (append slotDir as last argument) expose makeSlotDir use strict arg argMakeSlotDir=.true +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax if \datatype(argMakeSlotDir, "O") then @@ -485,12 +494,13 @@ /* attribute controls whether the arguments from a reply (result of calling a message on a remote DBUS object) will get appended with a slotDir-directory supplying possibly - useful information about the DBUS message; default: .true + useful information about the DBUS message; default: .false */ ::attribute makeReplySlotDir get ::attribute makeReplySlotDir set -- default: .false (do not append slotDir to result of a message call (turning result into an array object) expose makeReplySlotDir - use strict arg argMakeReplySlotDir=.true + use strict arg argMakeReplySlotDir=.false -- changed, 201407 rgf +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax if \datatype(argMakeReplySlotDir, "O") then @@ -508,6 +518,7 @@ ::attribute unmarshalByteArrayAsString set -- default: .true (append slotDir to result of a message call (turning result into an array object) expose unmarshalByteArrayAsString use strict arg argUnmarshalByteArrayAsString=.true +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax if \datatype(argUnmarshalByteArrayAsString, "O") then @@ -528,6 +539,7 @@ */ ::method waitOnConnectionClosed unguarded expose active +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) guard on when active=.false /* @@ -669,6 +681,7 @@ /** Block until connection (message loop) gets closed (attribute <code>active</code> turns <code>.false</code>. */ ::method waitUntilClosed unguarded expose active +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) guard on when active=.false @@ -766,6 +779,7 @@ */ ::method query_worker parse upper arg option +1 1 option3 +3 . -- get first char and first three chars in uppercase +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax optionPos=pos(option, "ACOT") @@ -803,6 +817,7 @@ supports("T[ypecode]", typecode) ... returns .false/.true; typecode can be a string: only returns .true then, if all characters are supported type codes */ ::method canSendTypeCode private -- this name is neutral enough to allow extensions, if other connection-related tests are needed +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) if arg()=0 then do str="" @@ -847,6 +862,7 @@ ::method listener unguarded expose internalSignalListeners internalRegisteredServiceObjects +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg action, ... .ArgUtil~validateClass("action", action, .string) @@ -923,6 +939,8 @@ */ ::method serviceObject unguarded expose internalSignalListeners internalRegisteredServiceObjects -- a directory +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) + use strict arg action, objectPath=.nil, rexxObject=.nil -- say "---> rexxObject="pp2(rexxObject) "rexxObject~isA(.DbusServiceObject):" pp2(rexxObject~isA(.DbusServiceObject)) "self~bustype="pp2(self~bustype) "self~server="pp2(self~server) @@ -1054,6 +1072,7 @@ ::method uniqueBusID_worker unguarded expose bustype +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) if bustype="private" then return "private:rexx:"self~identityHash return self~nativeUniqueBusID @@ -1109,6 +1128,7 @@ */ ::method busName_worker unguarded parse upper arg function . +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax firstLetter=function~left(1) @@ -1183,6 +1203,7 @@ /* folding methods of the "match" group into one parametrized method */ ::method match_worker use strict arg action, filter, block=.false +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax firstLetter=action~strip~left(1)~upper @@ -1303,6 +1324,7 @@ ::method getObject unguarded -- request remote object, return a Rexx proxy object to allow interaction with it use strict arg busName, objectPath +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax res=DBusDatatype(busName,"Busname") @@ -1322,6 +1344,7 @@ ::method getObjectPaths unguarded -- return an array of object paths for the supplied bus name / service name use strict arg busName +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) objectPathList=.array~new self~workerGetObjectPaths("/",busName,objectPathList) @@ -1337,6 +1360,7 @@ ::method workerGetObjectPaths unguarded private -- interrogates service possessing bus/service name for object paths (if that service supports that) use arg objPath, busName, objectPathList +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax o=self~getObject(busName, objPath) -- try to get the DBus object @@ -1385,6 +1409,7 @@ /* as of 2011-07-05 ooRexx from trunk does not support UTF-8, hence depending on BSF4ooRexx */ ::routine stringToUtf8 public -- needs BSF4ooRexx parse arg str +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) if .bsf=".BSF" then -- no BSF available (need to uncomment the ::requires BSF.CLS statement above), hence using the Rexx conversion procedure return utf8(str) @@ -1418,12 +1443,14 @@ /* ---------------------------------------------------------------------------------------- */ ::routine utf8ToString public -- needs BSF4ooRexx parse arg str +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) return BsfRawBytes(.java.lang.String~new(bsfRawBytes(str),"UTF-8")~getBytes) /* ---------------------------------------------------------------------------------------- */ ::routine dbus.box public -- for variant types or overruling reply signatures, allow boxing use strict arg signature, argument=.nil +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax @@ -1444,6 +1471,7 @@ the message loop of the DBus connection that invoked the Rexx method calling this routine */ ::routine raiseDBusError public -- this condition will be turned into an error-message in native code use arg errName="org.freedesktop.DBus.Error.RexxServiceRaised", errMessage=.nil +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax raise syntax 93.900 array (errName, errMessage, "ERRORREPLY") @@ -1453,6 +1481,7 @@ /* ---------------------------------------------------------------------------------------- */ /* return the version information that includes the library version and this package's version */ ::routine DBusVersion public +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) return DBusVersionLibrary()", package dbus.cls=[".dbus.dir~version"]" @@ -1496,6 +1525,7 @@ ::attribute proxy.introspectRootNode set /* make introspection parse tree available */ expose proxy.methods proxy.introspectRootNode use arg proxy.introspectRootNode +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) -- create directory with those names that we should proxy for the proxy object proxy.methods=IDBus.getMethodsForProxy(proxy.introspectRootNode) @@ -1756,6 +1786,7 @@ ::attribute service.introspectRootNode set /* make introspection parse tree available */ expose service.methods service.introspectRootNode +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use arg service.introspectRootNode -- create directory with those names that we should proxy for the proxy object service.methods=IDBus.getMethodsForProxy(service.introspectRootNode) @@ -1765,6 +1796,7 @@ ::attribute service.replySignature get /* returns the reply signature for the given member or .nil */ expose service.methods service.objectPath +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use arg member, interface="" if service.methods<>.nil then @@ -2494,6 +2526,7 @@ -- say "... timeoutDataPointer:" pp2(timeoutDataPointer) copies("<-/\",10) reply -- create a new thread +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) "after REPLY" self~nativeStartServerTimeoutLoop(timeoutDataPointer) -- start the timeout loop, pass (*data) via Rexx to native function @@ -3436,7 +3469,7 @@ */ ::method executeQueuedMessages expose queuedMessages - +-- Uncommented as this method gets constantly invoked by the native message loop yielding too many debug outputs -- if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "queuedMessages:" pp(queuedMessages~items) signal on any -- trap any error condition to allow us to re-raise any of the trappable conditions in the blocked thread later @@ -3557,8 +3590,12 @@ when condition~word(1)="USER" then -- as of ooRexx 4.2.0 "usercondition" cannot be supplied in an expression :( do - descr=condition "-" descr - raise user surrogate_from_postMessage_method_see_description_in_condition_object additional (addtl) description (descr) + -- as of 4.2.0 we cannot raise a user condition directly, hence doing it via an interpret keyword statement instead + stmt="raise" condition('c') "additional (arr) description (descr)" + interpret stmt + + -- descr=condition "-" descr + -- raise user surrogate_from_postMessage_method_see_description_in_condition_object additional (addtl) description (descr) end otherwise @@ -3638,3 +3675,8 @@ syntax: raise propagate + +/* Poor man's pretty pring, used in many code snippets. */ +::routine pp public + parse arg a + return "["a"]" Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-08-01 14:44:27 UTC (rev 228) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-08-05 11:24:16 UTC (rev 229) @@ -40,10 +40,17 @@ may occur 2014-07-27, rgf: - marshalling and unmarshalling of dictionaries with multiple entries fixed 2014-07-31, rgf: - added routine DbusGetTID() to ease debugging + 2014-08-05, rgf: - adding ReleaseLocalReference() where methods/routines may be running forever,ie. + in the various message/server loops and the functions that may be invoked from + within (ooRexx releases local references when returning from native + Rexx methods/routines) + - ooRexx 4.2.0 now required (because of using .context~name + possible todos: - add globals for Nil(), True(), Flase(), .Array, .DateTime, .DBus, "1", NullString() - version: 100.20140801 + + version: 100.20140805 license: Apache License 2.0 ------------------------ Apache Version 2.0 license ------------------------- @@ -114,8 +121,8 @@ // rgf, 2011-06-11, cf. <>http://gcc.gnu.org/gcc-4.3/porting_to.html> - // (needed for old dbus-example to be able to compile unaltered) -#include <cstring> // ? maybe removable, once old code is replaced ? + // (needed for old dbus-example to be able to compile unaltered), but also for memset() strlen(), str[n]cpy() +#include <cstring> // ? maybe removable, once old code is replaced/tidied up ? #ifdef _MSC_VER # pragma warning(disable:4100) @@ -128,11 +135,11 @@ #ifdef DBUSOOREXX_32 - #define DBUS_REXXVERSION "100.20140801 32-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20140805 32-bit" // version: "MajorNumber"."YYYYMMDD" #elif defined (DBUSOOREXX_64) - #define DBUS_REXXVERSION "100.20140801 64-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20140805 64-bit" // version: "MajorNumber"."YYYYMMDD" #else - #define DBUS_REXXVERSION "100.20140801 n/a-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20140805 n/a-bit" // version: "MajorNumber"."YYYYMMDD" #endif #ifndef TID @@ -154,7 +161,7 @@ // hence the following def is not really needed // #define REXX_AUTO_DISCONNECT_FROM_PRIVATE_SERVER -#define DEBUG_OOREXX_FIND_CLASS +// #define DEBUG_OOREXX_FIND_CLASS // attempt to help RMG to debug FindClass() finding class that is not in .local or .environment // #define DEBUG_RGF // for temporary debug output @@ -415,25 +422,42 @@ RexxCondition cond; rtc->DecodeConditionInfo(condObj, &cond); + RexxObjectPtr rxNil=rtc->Nil(); + RexxObjectPtr rxTrue=rtc->True(); + RexxStringObject rsoSyntax=rtc->String("SYNTAX"); + char *msg=(char *)RexxAllocateMemory( 4096 ); msg[0]=0; // format message according to exception type - if (rtc->SendMessage1(cond.conditionName, "EQUALS", rtc->String("SYNTAX"))==rtc->True()) // SYNTAX condition ? + // if (rtc->SendMessage1(cond.conditionName, "EQUALS", rtc->String("SYNTAX"))==rtc->True()) // SYNTAX condition ? + RexxObjectPtr ropRes=rtc->SendMessage1(cond.conditionName, "EQUALS", rsoSyntax); + // if (rtc->SendMessage1(cond.conditionName, "EQUALS", rsoSyntax)==rxTrue()) // SYNTAX condition ? + if (ropRes==rxTrue) // SYNTAX condition ? { - char const *line1=rtc->CString(rtc->SendMessage0(rtc->DirectoryAt(condObj, "TRACEBACK"), "FIRSTITEM")) ; // first traceback line=error line + RexxObjectPtr ropTraceback=rtc->DirectoryAt(condObj, "TRACEBACK"); + // char const *line1=rtc->CString(rtc->SendMessage0(rtc->DirectoryAt(condObj, "TRACEBACK"), "FIRSTITEM")) ; // first traceback line=error line + RexxObjectPtr ropTmpRes=rtc->SendMessage0(ropTraceback, "FIRSTITEM"); + // char const *line1=rtc->CString(rtc->SendMessage0(ropTraceback, "FIRSTITEM")) ; // first traceback line=error line + char const *line1=rtc->CString(ropTmpRes) ; // first traceback line=error line char line2[2048]=""; // will only use 1024 of it SNPRINTF(line2, 2048, "Error %d running %.512s line %d: %.1024s", - (int) cond.rc, (NULL != cond.program && rtc->Nil() != cond.program ? rtc->CString( cond.program ) : "program n/a") , - (int) cond.position,(NULL != cond.errortext && rtc->Nil() != cond.errortext ? rtc->CString( cond.errortext ): "errortext n/a") ); + // (int) cond.rc, (NULL != cond.program && rtc->Nil() != cond.program ? rtc->CString( cond.program ) : "program n/a") , + // (int) cond.position,(NULL != cond.errortext && rtc->Nil() != cond.errortext ? rtc->CString( cond.errortext ): "errortext n/a") ); + (int) cond.rc, (NULL != cond.program && rxNil != cond.program ? rtc->CString( cond.program ) : "program n/a") , + (int) cond.position,(NULL != cond.errortext && rxNil != cond.errortext ? rtc->CString( cond.errortext ): "errortext n/a") ); char line3[2048]=""; // will only use 1024 of it SNPRINTF( line3, 2048, "Error %d.%d: %.1024s", (int) (cond.code / 1000), (int) (cond.code % 1000), - (NULL != cond.message && rtc->Nil() != cond.message ? rtc->CString( cond.message ) : "message n/a") ); + (NULL != cond.message && rxNil != cond.message ? rtc->CString( cond.message ) : "message n/a") ); + // (NULL != cond.message && rtc->Nil() != cond.message ? rtc->CString( cond.message ) : "message n/a") ); SNPRINTF( msg, 4096, "%.16s%.512s:\n%.1024s\n%.1024s\n%.1024s", DLLNAME, header, line1, line2, line3); + + rtc->ReleaseLocalReference(ropTraceback); + rtc->ReleaseLocalReference(ropTmpRes); } else { @@ -442,7 +466,11 @@ DLLNAME, header, (NULL != cond.conditionName && rtc->Nil() != cond.conditionName ? rtc->CString(cond.conditionName) : "conditionName n/a") ); } + rtc->ReleaseLocalReference(ropRes); + rtc->ReleaseLocalReference(rxTrue); + rtc->ReleaseLocalReference(rxNil); + return msg; } @@ -626,6 +654,7 @@ // * --- Methods --- * // ******************************************************************** +/* --- rgf, 20140804 RexxMethod0(RexxStringObject, DbusGetVersion) { #if defined (DEBUG_METHODS) @@ -644,9 +673,9 @@ return context->String(msg); } +--- */ - RexxMethod1(RexxObjectPtr, DbusNativeGetSystemBus, RexxObjectPtr, genericBusObject) { #if defined (DEBUG_METHODS) @@ -3504,6 +3533,7 @@ { rso=pmarsh->context->ObjectToString(tmpRop); bReleaseLocalReferenceRso=true; + pmarsh->context->ReleaseLocalReference(tmpRop); } } else // rao==NULL ! @@ -6687,9 +6717,11 @@ RexxStringObject rsoAddr=rtc->String("native:connectionFromclient@"); RexxStringObject rsoAddrWithDT=(RexxStringObject) rtc->SendMessage1(rsoAddr, "||", rsoDT); + // create an instance of DBus (a connection) RexxClassObject rco=rtc->FindClass("DBUS"); // get class + #if defined (DEBUG_METHODS) || defined (DEBUG_PRIVATE_SERVER) || defined (DEBUG_OOREXX_FIND_CLASS) fprintf(stderr, " in \"new_connection_callback(...)\", rco=[%p] \n", rco); fflush(stderr); #endif @@ -6948,7 +6980,9 @@ #endif // allow loop thread to be ended by Rexx, e.g. checking the status of the "active" attribute (if .false return from message loop) - while (context->GetObjectVariable(timeoutLoopActive) == rxTrue) // while watch loop active, go ahead + RexxObjectPtr ropTimeoutLoopActive=context->GetObjectVariable(timeoutLoopActive); + // while (context->GetObjectVariable(timeoutLoopActive) == rxTrue) // while watch loop active, go ahead + while (ropTimeoutLoopActive == rxTrue) // while watch loop active, go ahead { if (context->CheckCondition()) // is this thread affected by a Halt-condition? If so, leave { @@ -6996,7 +7030,11 @@ #endif dbus_timeout_handle(pto->timeout); // let DBus act ... } + + context->ReleaseLocalReference(ropTimeoutLoopActive); + ropTimeoutLoopActive=context->GetObjectVariable(timeoutLoopActive); } + context->ReleaseLocalReference(ropTimeoutLoopActive); #if defined (DEBUG_TIMEOUTLOOP) || defined (DEBUG_METHODS) @@ -7285,13 +7323,17 @@ fprintf(stderr, "... WatchLoop(): after select(maxfd+1,...) #2, res=[%d]... \n", res); #endif - if (context->GetObjectVariable(watchLoopActive) != rxTrue) // stop watch loop ? + RexxObjectPtr ropWatchLoopActive=context->GetObjectVariable(watchLoopActive); + // if (context->GetObjectVariable(watchLoopActive) != rxTrue) // stop watch loop ? + if (ropWatchLoopActive != rxTrue) // stop watch loop ? { #ifdef DEBUG_WATCHLOOP fprintf(stderr, "... WatchLoop(): after select() #2, learned we need to stop watch loop, breaking! \n"); #endif + context->ReleaseLocalReference(ropWatchLoopActive); break; } + context->ReleaseLocalReference(ropWatchLoopActive); // loop over list of DBusWatches for (PSTRUCT_WATCH pw=wl->watchList; pw && pw->watch; pw=pw->next ) @@ -7523,9 +7565,9 @@ RexxPackageEntry dbus_package_entry = { STANDARD_PACKAGE_HEADER - REXX_INTERPRETER_4_1_0, // anything including and after 4.1.0 will work + REXX_INTERPRETER_4_2_0, // anything including and after 4.2.0 will work "dbus", // name of the package - "0.96", // package information + "1.00", // package information #if defined(REXX_LOADER_UNLOADER) || defined (REXX_LOADER) dbusLoader, Added: sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx32.so =================================================================== (Binary files differ) Index: sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx32.so =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx32.so 2014-08-01 14:44:27 UTC (rev 228) +++ sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx32.so 2014-08-05 11:24:16 UTC (rev 229) Property changes on: sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx32.so ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/x-sharedlib \ No newline at end of property Added: sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx64.so =================================================================== (Binary files differ) Index: sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx64.so =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx64.so 2014-08-01 14:44:27 UTC (rev 228) +++ sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx64.so 2014-08-05 11:24:16 UTC (rev 229) Property changes on: sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx64.so ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/x-sharedlib \ No newline at end of property Modified: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPong.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPong.rex 2014-08-01 14:44:27 UTC (rev 228) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPong.rex 2014-08-05 11:24:16 UTC (rev 229) @@ -71,6 +71,10 @@ say "DbusVersion()="pp2(DbusVersion()) say "Private server listens at address:" pp2(server~address) + +call dump2 .environment, "DBUS in .environment?" +call dump2 .local, "DBUS in .local?" + say "Hit enter to end program ..." parse pull x This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2014-08-07 18:48:32
|
Revision: 232 http://sourceforge.net/p/bsf4oorexx/code/232 Author: orexx Date: 2014-08-07 18:48:25 +0000 (Thu, 07 Aug 2014) Log Message: ----------- 20140807 Minor changes, tidying up the code. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dbusdoc.rex sandbox/rgf/misc/dbusoorexx/dbusoorexx-32.dll sandbox/rgf/misc/dbusoorexx/dbusoorexx-64.dll sandbox/rgf/misc/dbusoorexx/dev/Makefile32 sandbox/rgf/misc/dbusoorexx/dev/Makefile64 sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc sandbox/rgf/misc/dbusoorexx/dev/rony-dbus-cheat-sheet.txt sandbox/rgf/misc/dbusoorexx/libdbusoorexx.dylib sandbox/rgf/misc/dbusoorexx/libdbusoorexx32.so sandbox/rgf/misc/dbusoorexx/libdbusoorexx64.so sandbox/rgf/misc/dbusoorexx/listObjectPaths.rex Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-08-06 17:25:57 UTC (rev 231) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-08-07 18:48:25 UTC (rev 232) @@ -13,7 +13,7 @@ cf.: dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> (as of 2011-07-14) - version: 100.20140730 + version: 100.20140807 changes: - 2011-07-20, rgf; DBusProxyObject: - added proxy.dispatch(methodName[,args...])-method to send messages that @@ -89,6 +89,8 @@ - 2014-08-05, rgf: - adding .DBus to .local such that in native code FindClass("DBUS") will remain able to find this class in the case that the reported bug <http://sourceforge.net/p/oorexx/bugs/1275> gets fixed + - 2014-08-07, rgf: - tidied up the code + - removed dependency on rgf_util2.rex license: Apache License 2.0 @@ -122,7 +124,7 @@ .dbus.dir~bDebug =.false -- .true -- .false -- .true .dbus.dir~bDebugServer=.false -- .true -- .false -- .true -.dbus.dir~version="100.20140805" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' +.dbus.dir~version="100.20140807" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' .dbus.dir~DBUS_SERVICE_DBUS ="org.freedesktop.DBus" -- "The bus name used to talk to the bus itself." .dbus.dir~DBUS_PATH_DBUS ="/org/freedesktop/DBus" -- "The object path used to talk to the bus itself." @@ -199,11 +201,10 @@ -- try to require BSF4ooRexx dynamically call dynamicRequiresBSF4ooRexx -- requires BSF.CLS --- TODO: 2014-07-26, rgf: determine whether we need an "::OPTIONS DIGITS 20" (if that influences int64 and double conversions in native code) ::requires "dbusoorexx" LIBRARY -- get access to the native routines and methods -::requires "rgf_util2.rex" -- installed with the BSF4ooRexx package +-- ::requires "rgf_util2.rex" -- installed with the BSF4ooRexx package ::routine dynamicRequiresBSF4ooRexx -- BSF4ooRexx: needed need for UTF-8 conversion routines signal on any @@ -222,7 +223,7 @@ ::class "DBus" public inherit Worker /* --- class methods ------ */ --- TODO: 201407 rgf + ::method init class expose system session tid2human tid2human=.directory~new -- attribute that allows to translate TIDs into human readable form @@ -230,10 +231,6 @@ session=.nil - /* return version string, includes version of dbus library that gets used */ --- instead use public routine "DbusVersion()" --- ::method version class external "LIBRARY dbusoorexx DbusGetVersion" - -- will be usually called from native DbusGetTID(), which allows one optional argument indicating the desired formatting ::method formatTID unguarded class -- unguarded (access to tid2human only in here) expose tid2human @@ -261,14 +258,13 @@ /* unique id for the computer */ ::method machineID class external "LIBRARY dbusoorexx DbusGetUniqueMachineId" --- TODO: 201407 rgf + ::method system class /* returns the shared system bus connection */ expose system if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "arg(1):" pp(arg(1)) if arg(1)="CLEAR", arg(2)=system then -- remove cached connection to force a new one to be created do --- say "... clearing system cache..." system=.nil return end @@ -277,19 +273,17 @@ system=self~new("system") return system --- TODO: 201407 rgf + ::method session class /* returns the shared session bus connection */ expose session if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "arg(1):" pp(arg(1)) if arg(1)="CLEAR", arg(2)=session then -- remove cached connection to force a new one to be created do --- say "... clearing session cache ..." session=.nil return end - if session=.nil then /* if not available yet, get and rember it */ session=self~new("session") return session @@ -297,12 +291,11 @@ ::method connect class /* connect to an existing dbus connection */ - -- use strict arg address -- "address" can also be "system", "session" if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) forward message ("NEW") -- let our version of NEW handle this --- TODO: 201407 rgf + ::method new class expose system session use strict arg address @@ -320,7 +313,6 @@ if system<>.nil then /* shared message bus already cached, use it */ return system - -- self~getSystemBus(bus) bus~connectToAddress(lcaddress) -- will start message loop system=bus end @@ -341,9 +333,6 @@ -- receiving the new dbus object if address<>"native" then do - -- bus~nativeConnectPrivate(address) -- create a private connection to the address --- TODO: 201407 - o.k. to do that here? If so, how about the "native" connection (probably from DBusServer's native peer) - -- bus~startupMessageLoop bus~connectToAddress(address) -- use address verbatimly end @@ -542,34 +531,20 @@ if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) guard on when active=.false -/* -::method waitOnMessageLoop private unguarded -- block invocation until message loop stopped - expose active - use arg value=.false - guard on when active=value -- resume, once the attribute gets the received Boolean value -*/ - ::method nativeStartMessageLoop private external "LIBRARY dbusoorexx DbusMessageLoop" --- DEPRECATED, FUNCTION REMOVED, raising a condition hinting of what to use instead ! - --- TODO: rgf, 20140728 - temporarily allow for everyone to use this method (for server connections) --- ::method startMessageLoop unguarded private ::method startMessageLoop unguarded expose active stopLoop address busType - -- expose stopLoop address busType if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "arrived" signal on syntax --- TODO: rgf, 20140728: if public then raise an error, if attempting to start a running messageLoop if active=.true then do info="(bustype='"||bustype"'" if var("ADDRESS") then info=info", address='"address"'" info=info")" raise syntax 98.900 array ("Message loop for this connection" info "already active (running)") - -- raise syntax 98.900 array ("Message loop for this connection (address='"address"', busType='"||busType"') got stopped already, cannot re-start it") end if stopLoop=.true then -- message loop got already stopped, we do not allow to restart it, a new conncection needs to be established @@ -578,7 +553,6 @@ if var("ADDRESS") then info=info", address='"address"'" info=info")" raise syntax 98.900 array ("Message loop for this connection" info "got stopped, cannot use it anymore") - -- raise syntax 98.900 array ("Message loop for this connection (address='"address"', busType='"||busType"') got stopped already, cannot re-start it") end reply -- start a new thread and start message loop @@ -606,78 +580,11 @@ -- raise syntax 88.900 array ('Argument "start" not "stop" not available anymore, use method "close" instead"'value'"') raise syntax 88.900 array (msg) -/* - if active=.true then - do - guard on - stopLoop=.true -- stop message loop, independent of the conncection's type - -- remove session or system bus object from cache (this will cause a new connection to be created) - if wordpos(busType,"session system")>0 then - self~class~send(busType,"CLEAR", self) -- if cached, remove this shared connection - guard off - end - return - end - return - syntax: raise propagate - act=action~left(1) - if pos(act,"AW")=0 then - act=action~left(3) -- "STA", "STO" - - pos=wordpos(act, "A W") --- pos=wordpos(act, "A STO W") - - if pos=0 then - raise syntax 88.916 array ('"action"', '"A[ctive]", "W[aitUntilStopped]"', action) --- raise syntax 88.916 array ('"action"', '"Sto[p]", "A[ctive]", "W[aitUntilStopped]"', action) - -/* - pos=wordpos(act, "A STA STO W") - - if pos=0 then - raise syntax 88.916 array ('"action"', '"Sta[rt]", "Sto[p]", "A[ctive]", "W[aitUntilStopped]"', action) -*/ - - if act="A" then return active -- messageLoop active/running? can be .true, .false - - if act="W" then - do - use strict arg nixi, value=.false - if datatype(value,'o')=.false then -- not a Boolean value ? - raise syntax 88.900 array ('Argument "waitForValue" must be a logical value, found "'value'"') - - self~waitOnMessageLoop(value) -- block until attribute 'active' assumes 'value' - return - end - - if act="STO" then -- stop message loop - do - raise syntax 88.900 array ('Argument "stop" not available anymore, use method "close" instead"'value'"') -/* - if active=.true then - do - guard on - stopLoop=.true -- stop message loop, independent of the conncection's type - -- remove session or system bus object from cache (this will cause a new connection to be created) - if wordpos(busType,"session system")>0 then - self~class~send(busType,"CLEAR", self) -- if cached, remove this shared connection - guard off - end - return -*/ - end - return -*/ - -syntax: raise propagate - - - --- TODO: 201407, rgf: do we still need this or let us remove it ? +-- 201407, rgf: added to make good for deprecated "messageLoop('wait')" /** Block until connection (message loop) gets closed (attribute <code>active</code> turns <code>.false</code>. */ ::method waitUntilClosed unguarded expose active @@ -685,6 +592,7 @@ guard on when active=.false + ::method nativeCloseConnection private EXTERNAL "LIBRARY dbusoorexx DbusNativeConnectionClose" ::method close -- unguarded -- close (private) connection @@ -692,23 +600,18 @@ if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) - -- TODO: ?if stopLoop=.true, then already closed, raise syntax error? - if active=.false then return -- nothing to close anymo + if active=.false then return -- nothing to close anymore, do not raise an error signal on syntax -- close connection by shutting down message loop thread (which must be used for communication) stopLoop=.true -- stop message loop, independent of the conncection's type --- guard off -- allow message loop to guard --- say "::close #2 - about to do a guard on" pp2(self) pp(bustype) pp(address) guard on when active=.false -- wait until message loop is stopped (attribute will be set there in native code) statistics~closed=.dateTime~new -- remember time of closing if busType="private" then -- if a private connection, then truly close it do - if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "==> busType="pp(busType) "address="pp(address) "about to close connection!" - self~nativeCloseConnection -- close the connection for good, will set CSELF to .nil end return @@ -718,7 +621,6 @@ - -- keep these private so to not blow up the amount of methods one needs to be aware of ::method nativeIsConnected private external "LIBRARY dbusoorexx DbusConnectionIsConnected" ::method nativeIsAuthenticated private external "LIBRARY dbusoorexx DbusConnectionIsAuthenticated" @@ -811,8 +713,10 @@ syntax: raise propagate --- TODO: 201407 rgf - assuming o.k. in any thread /* + Must only be invoked from a _worker-method as the functionality is connection-related, hence + the message loop thread must be used! + supports() ... return "typeCodes={a,...,x}" ... returns string denoting available types supports("T[ypecode]", typecode) ... returns .false/.true; typecode can be a string: only returns .true then, if all characters are supported type codes */ @@ -830,7 +734,6 @@ str=str||char -- add supported type code end end - -- return "typeCode={"str"}" return str end @@ -881,10 +784,6 @@ internalSignalListeners~append(o) guard off --- TODO: really to start/stop message loop ? No - message loop is connection-related, not instance related --- TODO: 201407 rgf --- self~messageLoop("start") -- start message loop - return .true end @@ -906,17 +805,6 @@ end guard off --- TODO: really to start/stop message loop ? --- TODO: 201407 rgf -/* - guard on -- how many listener and service objects are there ? - nr=internalSignalListeners~items+internalRegisteredServiceObjects~items - guard off - - if nr=0 then -- no registered listener & server objects, make sure message loop is stopped - self~messageLoop("stop") -*/ - return count end @@ -932,7 +820,6 @@ --- TODO: 201407 rgf /* add service Rexx object, syntax: - a[dd], objectPath, rexxObject - r[emove], objectPath - g[etRegisteredServiceObjects] @@ -943,8 +830,6 @@ use strict arg action, objectPath=.nil, rexxObject=.nil --- say "---> rexxObject="pp2(rexxObject) "rexxObject~isA(.DbusServiceObject):" pp2(rexxObject~isA(.DbusServiceObject)) "self~bustype="pp2(self~bustype) "self~server="pp2(self~server) - signal on syntax if objectPath<>.nil, objectPath<>"default" then do @@ -967,10 +852,6 @@ if rexxObject~isA(.DBusServiceObject) then do rexxObject~service.connections~put(self) -- add this connection to the serviceObject connection set -/* - rexxObject~service.connection=self -- set connection in DBusServiceObject - rexxObject~service.objectPath=objectPath -- save desired object-Path -*/ end guard on @@ -978,10 +859,6 @@ internalRegisteredServiceObjects[objectPath]=rexxObject guard off --- TODO: really to start/stop message loop ? --- TODO: 201407, rgf, do not think so, we now have one connection-based message loop only! --- self~messageLoop("start") -- start message loop - return oldValue end @@ -1013,17 +890,6 @@ guard off end --- TODO: really to start/stop message loop ? --- TODO: 201407, rgf, no, we use the connection message loop now -/* - guard on -- how many listener and service objects are there ? - nr=internalSignalListeners~items+internalRegisteredServiceObjects~items - guard off - - if nr=0 then -- no registered listener & server objects, make sure message loop is stopped - self~messageLoop("stop") -*/ - return count end @@ -1047,7 +913,6 @@ "session", "system", "starter" and maybe "private" in Rexx*/ ::attribute server /* if set, connection belongs to a DBusServer (i.e. a client connection) */ --- TODO: 201407 rgf /* unique id for the bus */ ::method nativeUniqueBusID private external "LIBRARY dbusoorexx DbusGetUniqueBusId" ::method uniqueBusID @@ -1079,7 +944,6 @@ --- TODO: 201407 rgf -- folding into a method busName( "request" | {"release"| "yield"} | "hasOwner" | "uniqueName", name [, flags] ) /* unique bus name for the dbus connection */ ::method nativeUniqueBusName private external "LIBRARY dbusoorexx DbusGetUniqueBusName" @@ -1310,14 +1174,14 @@ syntax: co=condition("o") --- say "in message-syntax:" ppCondition2(co) "... methName="pp2(methName) "signalName="pp2(signalName) if co~code=91.999 then -- "Message "NATIVECALLMESSAGE" did not return a result" do -- make error message more meaningful by supplying message that caused this instead: + signal on syntax name syntax2 if interface="" then raise syntax 91.999 array (methodName) else raise syntax 91.999 array (interface"."methodName) end - +syntax2: raise propagate -- raise any other error in caller @@ -1390,21 +1254,23 @@ return syntax: -- mostlikely: org.freedesktop.DBus.Error.Reply or org.freedesktop.DBus.Error.ServiceUnknown -/* - co=condition('o') - if co~additional~at(2)<>.nil then + if .dbus.dir~bDebug=.true then do - say "---> error:" co~additional~at(2) -- contains the substitution error message - say " (hint: you could retry immediately, maybe the service was not listening yet)" + co=condition('o') + if co~additional~at(2)<>.nil then + do + say "---> error:" pp(co~condition) pp(co~errortext) + say " " pp(co~additional~at(2)) -- contains the substitution error message + say " (hint: you could retry immediately, maybe the service was not listening yet)" "line:" pp(.line) + end + if .local~hasentry("RGF.ALPHA.LOW") then -- assuming that "rgf_util2.rex" is available + say ppCondition2(co) + say "---" end - say ppCondition2(co) - say "---" -*/ return --- TODO: 201407 rgf /* ---------------------------------------------------------------------------------------- */ /* as of 2011-07-05 ooRexx from trunk does not support UTF-8, hence depending on BSF4ooRexx */ ::routine stringToUtf8 public -- needs BSF4ooRexx @@ -1439,7 +1305,6 @@ return out --- TODO: 201407 rgf /* ---------------------------------------------------------------------------------------- */ ::routine utf8ToString public -- needs BSF4ooRexx parse arg str @@ -1460,7 +1325,6 @@ raise syntax 93.900 array("'signature':" res) return .array~of("useThisSignature="signature,argument) -- native code looks for "useThisSignature=" - -- return .array~of("variantSignature="signature,argument) syntax: raise propagate @@ -1506,7 +1370,6 @@ "s", - -- return signature "") -- arg signature (no args) -- create introspect parse tree and save it - -- self~proxy.introspectRootNode=.IDBus~newIntrospection(introspectionData) -- create parse tree for introspection data self~proxy.parseIntrospectData(proxy.introspectData) return @@ -1672,9 +1535,7 @@ ::attribute interface ::attribute signalName --- TODO: 201407: Sebastian Margiol suggested to add an UNKNOWN method; but then programmers might not realize what else they get? - /* =============================================================================== */ /* Allows an ooRexx object to serve DBus method invocations in an easy manner, by adding the ability to e.g. dynamically determine replySignatures from the introspect @@ -1686,8 +1547,6 @@ ::method init -- intorData, service.connection, service.objectPath; introData may be supplied later, using the respective methods expose service.connections service.introspectRootNode service.methods if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) --- expose service.connection service.objectPath service.introspectRootNode service.methods --- use strict arg introData=.nil, service.connection=.nil, service.objectPath=.nil use strict arg introData=.nil service.methods=.nil @@ -1695,7 +1554,6 @@ signal on syntax self~service.parseIntrospectData(introData) --- say "---> ---> --->" self": introData: ["introdata"]" return syntax: -- make sure a parse tree is available, as caller may intercept condition and proceed @@ -1705,7 +1563,6 @@ '"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> ' - '<node/> ' self~service.parseIntrospectData(empty) --- say self": supplying empty introData: ["introdata"]" raise propagate -- raise condition in caller @@ -1751,35 +1608,6 @@ ::attribute service.connections /* object's connection to use */ -/* -::attribute service.connections get /* object's connection to use */ - expose service.connections - return service.connections~copy /* return a copy of the current set of connections this service object services */ -*/ - -/* -::attribute service.objectPath get /* object's path on the dbus */ -::attribute service.objectPath set /* object's path on the dbus */ - expose service.objectPath service.connection - use arg oPath - signal on syntax - - -- if this connection is to the client of a DBusServer, then allow resetting service.objectPath (cf. DBusServer:newConnection) - if service.connection~busType="private", service.connection~server<>.nil, oPath=.nil then - do - service.objectPath=.nil - return - end - - if service.objectPath<>.nil then - raise syntax 93.900 array ('Attribute "service.objectPath" is not ".nil" (current value: "'service.objectPath'"), therefore must not accept new value "'arg(1)'")') - - service.objectPath=oPath - return -syntax: raise propagate -*/ - - ::attribute service.introspectRootNode get /* make introspection parse tree available */ ::attribute service.introspectData get ::attribute service.introspectFileName get @@ -1816,7 +1644,6 @@ -- will emit the signal to all connections this service object is registered with expose service.methods service.connections if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) --- expose service.methods service.connection service.objectPath use strict arg objectPath=.nil, interface="", member, ... signature="" -- default to no arguments @@ -1840,14 +1667,12 @@ end -- build arguments for "self~message": - -- args=.array~of("signal", service.objectPath, interface, member, signature) args=.array~of("signal", objectPath, interface, member, signature) do i=4 to arg() -- append arguments to the signal, if any args~append(arg(i)) end signal on syntax --- service.connection~sendWith("message", args) -- send the message do conn over service.connections -- send signal to all connections this service object is being used if conn~cself=.nil then -- connection closed? @@ -1934,7 +1759,6 @@ if self~hasMethod(attrName) then -- necessary for the unqualified name case do signal on syntax name syntax_get --- return self~send(attrName, slotDir) -- send slotDir with the message, may not be allowed -- using the org.freedsktop.DBus.Properites.Get() which returns always a 'v', therefore -- returning a 'v', which Rexx renders as 's', 'as', 'a{ss}' for atomic, array or dict types return dbus.box("v", self~send(attrName,slotDir)) -- send slotDir with the message, may not be allowed @@ -1991,7 +1815,6 @@ -- return self~send(attrName) -- using the org.freedsktop.DBus.Properites.Get() which returns always a 'v', therefore -- returning a 'v', which Rexx renders as 's', 'as', 'a{ss}' for atomic, array or dict types --- say "... syntax_get: self~send("pp2(attrName)"):" pp2(self~send(attrName)) "..." return dbus.box("v", self~send(attrName)) end signal continue @@ -2302,30 +2125,19 @@ return "signature ["value"] dict entry ended but not started, '{' missing" end -/* wrong: array closing, if datatype found not accounted for, as DBUSValidate() is used, this is o.k. - if arrayOpen<>0 then -- arrays without element type ! - do - return "signature ["value"] contains array without element type" - end -*/ + -- so far, so good, signature looks good, now let us validate the signature through dbus: + return DbusValidate(value,"s") - return DbusValidate(value,"s") -- now let us validate the signature through dbus - -- return .true -- checked out o.k. - - - - syntax: raise propagate -- raise in caller --- TODO: 201407: still .true ??? -/* as of 2011-07-29: not yet implemented in full in native code, hence not operational */ /* =============================== DBusServer ====================================================== */ --- TODO: 20140722 - which message loop to spawn and to control, just one, or multiples ? +-- a private ooRexx DBus server implemenation; connection to clients using .DBus + /* ------------------------------ class definition ------------------------------ */ ::class "DBusServer" public ::method init @@ -2363,16 +2175,13 @@ ::attribute watchLoopActive get -- indicates whether the server message loop is active or not -::method newConnection -- new connection to this server received (from native code) +::method newConnection -- new connection to this server received (from callback in native code) expose defaultService defaultListener connections watchConnections if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg conn - conn~startMessageLoop -- TODO: rgf, 20140728 + conn~startMessageLoop -- start message loop for this new connection --- signal on syntax --- say pp2(self)"::newConnection - just received a new connection conn="pp2(conn) "..." "defaultService~class="pp2(defaultService~class) - connections~append(conn) -- add new connection to our list of accepted connections if defaultService<>.nil then -- add service object do @@ -2380,7 +2189,6 @@ do aCopy=defaultService~copy -- each DBusServiceObject keeps its own connection to its client aCopy~service.connections~put(conn) -- assign this connection - -- aCopy~service.objectpath=.nil -- make sure no object path conn~serviceObject("add", "default", aCopy) -- will start message loop automatically end else -- plain object @@ -2394,31 +2202,18 @@ conn~listener("add", defaultListener) -- will start message loop automatically end - -- TODO: rgf, temporarily disable, 28.7.2014 if watchConnections=.false then -- start the watchConnections thread self~watchConnections --- say pp2(self)"::newConnection - conn~messageLoop('active'):" pp2(conn~messageLoop('active')) --- say pp2(self)"::newConnection - conn~messageLoop('active'):" pp2(conn~active) --- say pp2(self)"::newConnection -" pp2(conn) "about to leave." return -/* -syntax: - co=condition('o') - say pp2(self) ppCondition2(co) - raise propagate -*/ --- TODO: really to start/stop message loop ? ::method disconnect -- invoked from native code (not reliably invoked all the time as of 1.6.4 on Ubuntu) expose connections if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg conn --- say "..." self"::disconnect, 'conn'="pp2(conn) --- conn~messageLoop("stop") -- stop the connection's message loop conn~close -- make sure we cannot use it anymore (it wouldn't work) res=connections~removeItem(conn) -- remove the disconnected connection from the client @@ -2432,8 +2227,6 @@ if cself<>.nil then raise syntax 93.900 array (self": server was already started") - -- return self~nativeServerID --- say "address:" pp2(address) "cself="pp2(cself) if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "about to: self~nativeServerStartup" self~nativeServerStartup(address) -- create server listening on given address @@ -2444,23 +2237,21 @@ --- as of DBus 1.4.14, the private server does not receive a "Disconnected" signal +-- as of DBus 1.4.14, the private server does not receive a "Disconnected" signal, hence testing the connections constantly ::method watchConnections unguarded -- check whether client connections are available, if not disconnect the stalled connecition expose connections watchConnections if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg sleepTime=.1 -- check every 1/10 second --- TODO: rgf, make sleepTime higher to not disturb debug output -sleepTime=1 -- try every second + if arg()=0, .dbus.Dir~bDebugServer=.true then -- if no args and in server debug mode, enlarge sleepTime to not have too much debug output + sleepTime=1 - guard on watchConnections=.true -- indicate that the watch Connections thread is started guard off if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "before reply" reply --- say "... ... probing" pp2(conn) "sleepTime:" pp2(sleepTime) "..." if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "after reply, BEFORE: entering the loop" signal on halt @@ -2469,17 +2260,15 @@ call sysSleep sleepTime -- sleep -if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "awoke, connections~items="pp2(connections~items) +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "awoke, connections~items="pp(connections~items) guard on arr=connections~copy -- get a copy of all connections guard off do conn over arr -- iterate over all client connections and probe them --- say "... ... testing" pp2(conn)": conn~isOpen:" pp2(conn~isOpen) "..." -if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "conn~query('open': --> before, conn="pp2(conn) conn~query('open') +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "conn~query('open': --> before, conn="pp(conn) conn~query('open') if conn~query("open")=.false then do --- say "... ... BINGO! " pp2(conn) "not connected/open anymore, DISCONNECTing connection !" -if .dbus.dir~bDebugServer=.true then say "!!!" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "conn~query('open': --> DISCONNECTING conn="pp2(conn) +if .dbus.dir~bDebugServer=.true then say "!!!" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "conn~query('open': --> DISCONNECTING conn="pp(conn) self~disconnect(conn) -- disconnect will remove closed conn from connections ! end end @@ -2494,7 +2283,7 @@ halt: -- a HALT condition, make sure all known connections get closed guard off -- make sure guard is off --- say "... DEBUG..." self": HALT in watchConnections, closing all known connections (and thereby their messageloops)..." +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "HALT signal: closing all connections..." do conn over connections conn~close end @@ -2523,7 +2312,6 @@ -- now fetch RexxPointer value use strict arg action, timeoutDataPointer --- say "... timeoutDataPointer:" pp2(timeoutDataPointer) copies("<-/\",10) reply -- create a new thread if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) "after REPLY" @@ -2537,8 +2325,6 @@ expose connections cself watchLoopActive if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) --- say "..." .dateTime~new " arrived in shutdown, cself="pp2(cself) "..." --- say "."~copies(50) if cself=.nil then raise syntax 93.900 array (self": shutdown not possible, as server was not started") @@ -2548,9 +2334,8 @@ self~nativeServerShutdown -- stop accepting connections - do conn over connections + do conn over connections -- close all connections to service conn~close -- close connection --- say "shutdown: removing conn="pp2(conn)"..." connections~removeItem(conn) -- remove connection end @@ -2643,7 +2428,7 @@ currMeth=.nil currArg=.nil lastEl=currNode --- say "*** ----> ---> --> ->" self": node" pp2(name) +-- say "*** ----> ---> --> ->" self": node" pp(name) end when elName="interface" then @@ -2657,7 +2442,7 @@ currMeth=.nil currArg=.nil lastEl=currInterface --- say "*** ----> ---> --> ->" self": interface" pp2(name) +-- say "*** ----> ---> --> ->" self": interface" pp(name) end when elName="method" then @@ -2670,7 +2455,7 @@ currMeth~parent=currInterface currArg=.nil lastEl=currMeth --- say "*** ----> ---> --> ->" self": method" pp2(name) +-- say "*** ----> ---> --> ->" self": method" pp(name) end when elName="signal" then @@ -2683,7 +2468,7 @@ currMeth~parent=currInterface currArg=.nil lastEl=currMeth --- say "*** ----> ---> --> ->" self": signal" pp2(name) +-- say "*** ----> ---> --> ->" self": signal" pp(name) end when elName="arg" then @@ -2705,7 +2490,7 @@ currMeth~content~append(currArg) currArg~parent=currMeth lastEl=currArg --- say "*** ----> ---> --> ->" self": arg" pp2(name) +-- say "*** ----> ---> --> ->" self": arg" pp(name) end when elName="property" then @@ -2732,7 +2517,7 @@ if pos("write", access)>0 then currProp~content~append(.IDBusArg~new('newValue', type, 'in')) --- say "*** ----> ---> --> ->" self": property" pp2(name) +-- say "*** ----> ---> --> ->" self": property" pp(name) end when elName="annotation" then @@ -2754,7 +2539,7 @@ if currMeth<>.nil then currMeth~createSignatures -- pending method? --- say "*** ----> ---> --> ->" self": dumping tree using rootNode="pp2(rootNode) +-- say "*** ----> ---> --> ->" self": dumping tree using rootNode="pp(rootNode) -- call idbus.dumpIDBus rootNode return rootNode @@ -2953,7 +2738,7 @@ seenMethodNames=.directory~new - if bShowProgress=.true then say "node:" pp2(rootNode~name) + if bShowProgress=.true then say "node:" pp(rootNode~name) start=3 step=3 do n over rootNode~content @@ -2961,7 +2746,7 @@ do indent=start strIndent=" "~copies(indent) - if bShowProgress=.true then say strIndent "node:" pp2(n~name) -- "content~items:" pp2(n~content~items) + if bShowProgress=.true then say strIndent "node:" pp(n~name) -- "content~items:" pp(n~content~items) end do i over n~content -- interfaces etc. @@ -2969,7 +2754,7 @@ do indent=start+step strIndent=" "~copies(indent) - if bShowProgress=.true then say strIndent "interface:" pp2(i~name) + if bShowProgress=.true then say strIndent "interface:" pp(i~name) indent+=step strIndent=" "~copies(indent) @@ -2984,7 +2769,7 @@ if seenMethodNames~hasEntry(m~name) then do seen=seenMethodNames~entry(m~name) - say " ***" pp2(m~parent~name) kind pp2(m~name) "already defined as" pp2(seen~name) "a" pp2(seen~class~id) pp2(seen~parent~name) + say " ***" pp(m~parent~name) kind pp(m~name) "already defined as" pp(seen~name) "a" pp(seen~class~id) pp(seen~parent~name) end else seenMethodNames~setEntry(m~name,m) -- save seen method @@ -3003,7 +2788,7 @@ dt=.dbus.dir~dataTypes -- get datatype dir, "r" -> struct, "e" -> dict(entry) - say "node:" pp2(rootNode~name) + say "node:" pp(rootNode~name) start=3 step=3 do n over rootNode~content~sort @@ -3011,7 +2796,7 @@ do indent=start strIndent=" "~copies(indent) - say strIndent "node:" pp2(n~name) -- "content~items:" pp2(n~content~items) + say strIndent "node:" pp(n~name) -- "content~items:" pp(n~content~items) end do i over n~content~sort -- interfaces etc. @@ -3019,7 +2804,7 @@ do indent=start+step strIndent=" "~copies(indent) - say strIndent "interface:" pp2(i~name) + say strIndent "interface:" pp(i~name) indent+=step strIndent=" "~copies(indent) @@ -3054,20 +2839,20 @@ if bGetterSetter<>.true then -- could only be true for a property do - so=pp2(m~replySignature) + so=pp(m~replySignature) if so~length<minWidth then so=so~left(minWidth, ".") - say strIndent so kind~left(8) m~name "("tmpStr~strip")" "->" pp2(m~argSignature) + say strIndent so kind~left(8) m~name "("tmpStr~strip")" "->" pp(m~argSignature) end else -- special handling for get&set properties: show both signatures separately do - so=pp2("") -- first show the setter, which has no return value + so=pp("") -- first show the setter, which has no return value if so~length<minWidth then so=so~left(minWidth, ".") - say strIndent so kind~left(8) m~name "("tmpStr~strip")" "->" pp2(m~argSignature) + say strIndent so kind~left(8) m~name "("tmpStr~strip")" "->" pp(m~argSignature) - so=pp2(m~replySignature) -- show the getter method + so=pp(m~replySignature) -- show the getter method if so~length<minWidth then so=so~left(minWidth, ".") - say strIndent so kind~left(8) m~name "()" "->" pp2("") + say strIndent so kind~left(8) m~name "()" "->" pp("") end end @@ -3382,7 +3167,7 @@ expose paths use arg objectPath -- can also be a collection of paths --- say "..." self"::init, objectPath="pp2(objectPath) +-- say "..." self"::init, objectPath="pp(objectPath) signal on syntax paths=.relation~new @@ -3417,7 +3202,7 @@ else tmpNewPath=tmpNewPath"/"curr end --- call dump2 paths, self": 'paths'-relation after set-up for" pp2(objPath) +-- call dump2 paths, self": 'paths'-relation after set-up for" pp(objPath) return Modified: sandbox/rgf/misc/dbusoorexx/dbusdoc.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbusdoc.rex 2014-08-06 17:25:57 UTC (rev 231) +++ sandbox/rgf/misc/dbusoorexx/dbusdoc.rex 2014-08-07 18:48:25 UTC (rev 232) @@ -2,9 +2,11 @@ /* author: Rony G. Flatscher (c) date: 2011-07-29/31, 2011-08-01/05, 2011-08-14 - version: 1.0 + changed: 2014-08-07, rgf - make sure that connection gets closed, otherwise message loop thread lingers + version: 1.1 name: dbusdoc.rex purpose: documents given bus name in HTML form to allow the creation of API listings + usage: rexx dbusdoc.rex [session|system] [service.bus.name] license: AL 2.0 ------------------------ Apache Version 2.0 license ------------------------- Copyright 2011 Rony G. Flatscher @@ -72,6 +74,7 @@ say allBusNames~items "available bus names at the moment." say + conn~close signal usage -- show usage end end @@ -107,6 +110,7 @@ if filtered~items=0 then do say 'no bus name found containing "'||needle'"' + conn~close exit end @@ -139,6 +143,7 @@ call stream newFileName, "C", "close" call dumpStatistics conn +conn~close exit @@ -159,6 +164,7 @@ co=condition('o') say ppCondition2(co) -- "pretty prints" the condition object's information say + conn~close raise propagate Modified: sandbox/rgf/misc/dbusoorexx/dbusoorexx-32.dll =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/dbusoorexx-64.dll =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/dev/Makefile32 =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/Makefile32 2014-08-06 17:25:57 UTC (rev 231) +++ sandbox/rgf/misc/dbusoorexx/dev/Makefile32 2014-08-07 18:48:25 UTC (rev 232) @@ -7,8 +7,8 @@ # rgf, 2011-09-20 # DBUS_HOME = e:\programme\dbus -# rgf, 2014-08-06 -DBUS_HOME = e:\programme\dbus-20140805 +# rgf, 2014-08-07 +DBUS_HOME = e:\programme\dbus-20140807 DBUS_INCLUDE = $(DBUS_HOME)\include DBUS_LIB_HOME = $(DBUS_HOME)\lib Modified: sandbox/rgf/misc/dbusoorexx/dev/Makefile64 =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/Makefile64 2014-08-06 17:25:57 UTC (rev 231) +++ sandbox/rgf/misc/dbusoorexx/dev/Makefile64 2014-08-07 18:48:25 UTC (rev 232) @@ -6,8 +6,8 @@ # rgf, 2011-09-20 # DBUS_HOME = e:\programme\dbus -# rgf, 2014-08-06 -DBUS_HOME = e:\programme\dbus-20140805-64bit +# rgf, 2014-08-07 +DBUS_HOME = e:\programme\dbus-20140807-64bit DBUS_INCLUDE = $(DBUS_HOME)\include DBUS_LIB_HOME = $(DBUS_HOME)\lib Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-08-06 17:25:57 UTC (rev 231) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-08-07 18:48:25 UTC (rev 232) @@ -1,3 +1,40 @@ +/** This is the ooRexx native library for interfacing with the DBus message infrastructure that + * has been developed for Linux and has been employed by many Linux distributions. As ports to + * Windows and MacOSX of DBus exist, those platforms are supported as well. + * + * This library needs 'dbus.cls' which is tightly integrated as classes and methods of that ooRexx + * package are being used from the native code. + * + * The following scenarios are supported: + * + * <ul> + * <li> DBus interaction with DBus services. In this scenario first a connection to the DBus + * has to be established (e.g. 'session', 'system', or any other 'private address'), which + * kicks off a proper message loop (c.f. the RexxMethod DbusMessageLoop(...), which + * fulfills the libdbus requirement that messages get received and sent within the same + * thread. Code in the 'dbus.cls' package makes sure that any message to be sent via DBus + * will be dispatched within the message loop thread. + * + * <li> ooRexx DBus singal listeners and ooRexx service objects. In this scenario any messages + * directed to ooRexx signal listeners and ooRexx service objects get dispatched via the + * message loop for the connection which is used to filter signals or which was used to + * register the DBus service. + * + * <li> Private DBus servers. In this scenario an ooRexx program running on any operating system + * can serve any DBus clients from any other operating systems. In this scenario for each + * ooRexx private DBus server a watch loop is created in its own thread that dispatches + * client connections, whenever a private DBus client tries to establish a connection. For + * each new connection a proper message loop is established to receive and send DBus messages. + * It is possible to add ooRexx DBus service objects and add ooRexx listener objects on that + * connection as is the case in the first two scenarios above. + * + * </ul> + * + * @author Rony G. Flatscher + * @version 2014-08-07 + * + */ + /* author: Rony G. Flatscher (c) 2011 date: 2011-07-17 (2011-06-11, 2011-07-17) @@ -45,13 +82,16 @@ within (ooRexx releases local references when returning from native Rexx methods/routines); added a missing dbus_server_ref()-call (caused abend on Windows) - - ooRexx 4.2.0 now required (because of using .context~name + - ooRexx 4.2.0 now required (because of using .context~name in 'dbus.cls' package + 2014-08-07, rgf: - tidied up the source - possible todos: - add globals for Nil(), True(), Flase(), .Array, .DateTime, .DBus, "1", NullString() + + possible todos: - add globals for Nil(), True(), Flase(), .Array, .DateTime, .DBus, "1", "", as well + as index name in dateTime directory entries - change attribute name CSELF (probably misleading as it is not the same as CSELF in an ooRexx native method or routine argument type); if so, don't forget dbus.cls - version: 100.20140806 + version: 100.20140807 license: Apache License 2.0 ------------------------ Apache Version 2.0 license ------------------------- @@ -71,10 +111,7 @@ ----------------------------------------------------------------------------- */ -// TODO: 2014-07, rgf: - check for need of executing ReleaseLocalReference() ! -// - store ooRexx classes ARRAY, DATETIME, DBUS in global constants instead - #ifdef __cplusplus extern "C" { // make sure no C++ name mangling comes into the way #endif @@ -92,38 +129,18 @@ #define DBUS_VERSION_STRING "<n/a>" #endif - #ifndef DBUS_TYPE_UNIX_FD // e.g. not defined for Windows, still incorporate it #define DBUS_TYPE_UNIX_FD ((int) 'h') #endif -/* -#include "oorexxapi.h" // testing for cygwin-compilation, hence moved here because of re-definitions - -#include <sys/types.h> // rgf-temp -#include <unistd.h> // rgf-temp -#include <sys/select.h> // rgf-temp - #include <stdio.h> #include <stdlib.h> -#include <stdbool.h> // rgf-temp -#include <sys/types.h> // rgf-temp -#include <stdint.h> // rgf-temp -*/ - - -#include <stdio.h> -#include <stdlib.h> - // rgf, 2011-06-11 #include "oorexxapi.h" - // rgf, 2011-06-11, cf. <>http://gcc.gnu.org/gcc-4.3/porting_to.html> - // (needed for old dbus-example to be able to compile unaltered), but also for memset() strlen(), str[n]cpy() -// #include <cstring> // ? maybe removable, once old code is replaced/tidied up ? Clang won't accept that anymore (20140805) #include <string.h> // will allow access to memset() et.al. #ifdef _MSC_VER @@ -137,11 +154,11 @@ #ifdef DBUSOOREXX_32 - #define DBUS_REXXVERSION "100.20140806 32-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20140807 32-bit" // version: "MajorNumber"."YYYYMMDD" #elif defined (DBUSOOREXX_64) - #define DBUS_REXXVERSION "100.20140806 64-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20140807 64-bit" // version: "MajorNumber"."YYYYMMDD" #else - #define DBUS_REXXVERSION "100.20140806 n/a-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20140807 n/a-bit" // version: "MajorNumber"."YYYYMMDD" #endif #ifndef TID @@ -163,13 +180,11 @@ // hence the following def is not really needed // #define REXX_AUTO_DISCONNECT_FROM_PRIVATE_SERVER + // #define DEBUG_OOREXX_FIND_CLASS // attempt to help RMG to debug FindClass() finding class that is not in .local or .environment - // #define DEBUG_RGF // for temporary debug output - // #define DEBUG_MESSAGELOOP - // #define DEBUG_CONNECTION /* @@ -188,6 +203,7 @@ */ +#define DEBUG_TIMEOUTLOOP /* // for debugging private server @@ -260,15 +276,13 @@ RexxClassObject arrayClass; // for unmarshalling convenience logical_t is_ay; // special handling of byte array for Rexx active ?, - // marshalling: "s"->"ay", if "s" input and "ay" output! - // unmarshalling: "aay" -> "as" + // unmarshalling: "ay" -> "s" logical_t unmarshal_ay_as_string; // determined by connection attribute: true ay->string, ay->ay else logical_t marshal_ay_as_string; // determined in marshal(...)'s array branch logical_t is_dict; // special handling of byte array for Rexx active ?, // marshalling: .directory->"a{sY}" // unmarshalling: "a{xY}" -> .directory object ! -// int filler; // ---rgf, 2014-07-27, never used, but set to \0 } STRUCT_MARSHAL; @@ -279,17 +293,6 @@ #if (defined (DEBUG_MARSHAL) || defined (DEBUG_UNMARSHAL)) && defined (DEBUG_STRUCT_MARSHAL_PRINT) // rgf, 20140726 void dump_struct_marshal(PSTRUCT_MARSHAL pm) { - // fprintf(stderr, " \t\t--- PSTRUCT_MARSHAL() --->: RTC=[%p], \n\t\t\tsignature=[%s]/length=[%lu], cursor=[%c]/pos=[%d], \n\t\t\telementStart=[%c]/pos=[%d], elementEnd=[%c]/pos=[%d], arrStart=[%c]/pos=[%d], arrEnd=[%c]/pos=[%d]\n\t\t\tis_ay=[%d], is_dict=[%d], marsh_ay_as_s=[%d], unmarsh_ay_as_s=[%d]\n", - // pm->context, pm->signature, pm->signatureLength, - // *pm->cursor, (int)(pm->cursor - pm->signature), - // *pm->elementStart, (int)(pm->elementStart - pm->signature), - // *pm->elementEnd, (int)(pm->elementEnd - pm->signature), - // *pm->arrStart, (int)(pm->arrStart - pm->signature), - // *pm->arrEnd, (int)(pm->arrEnd - pm->signature), - // (int) pm->is_ay, (int) pm->is_dict, - // (int) pm->marshal_ay_as_string, (int) pm->unmarshal_ay_as_string - // ); - fprintf(stderr, " ---prr---> PSTRUCT_MARSHAL() --->: RTC=[%p],signature=[%p], cursor=[%p], elStart=[%p], elEnd=[%p], arrStart=[%p], arrEnd=[%p], dimensions=[%lu] ", pm->context, pm->signature, @@ -420,6 +423,10 @@ #endif } + +/** Create a Rexx-like/formatted error message (origin: BSF4ooRexx.cc. + * @return errorString must be freed by receiver +*/ // from BSF4ooRexx.cc // allocates and creates a Rexx-like error message // returned *msg must be freed @@ -436,21 +443,15 @@ msg[0]=0; // format message according to exception type - // if (rtc->SendMessage1(cond.conditionName, "EQUALS", rtc->String("SYNTAX"))==rtc->True()) // SYNTAX condition ? RexxObjectPtr ropRes=rtc->SendMessage1(cond.conditionName, "EQUALS", rsoSyntax); - // if (rtc->SendMessage1(cond.conditionName, "EQUALS", rsoSyntax)==rxTrue()) // SYNTAX condition ? if (ropRes==rxTrue) // SYNTAX condition ? { RexxObjectPtr ropTraceback=rtc->DirectoryAt(condObj, "TRACEBACK"); - // char const *line1=rtc->CString(rtc->SendMessage0(rtc->DirectoryAt(condObj, "TRACEBACK"), "FIRSTITEM")) ; // first traceback line=error line RexxObjectPtr ropTmpRes=rtc->SendMessage0(ropTraceback, "FIRSTITEM"); - // char const *line1=rtc->CString(rtc->SendMessage0(ropTraceback, "FIRSTITEM")) ; // first traceback line=error line char const *line1=rtc->CString(ropTmpRes) ; // first traceback line=error line char line2[2048]=""; // will only use 1024 of it SNPRINTF(line2, 2048, "Error %d running %.512s line %d: %.1024s", - // (int) cond.rc, (NULL != cond.program && rtc->Nil() != cond.program ? rtc->CString( cond.program ) : "program n/a") , - // (int) cond.position,(NULL != cond.errortext && rtc->Nil() != cond.errortext ? rtc->CString( cond.errortext ): "errortext n/a") ); (int) cond.rc, (NULL != cond.program && rxNil != cond.program ? rtc->CString( cond.program ) : "program n/a") , (int) cond.position,(NULL != cond.errortext && rxNil != cond.errortext ? rtc->CString( cond.errortext ): "errortext n/a") ); @@ -458,7 +459,6 @@ SNPRINTF( line3, 2048, "Error %d.%d: %.1024s", (int) (cond.code / 1000), (int) (cond.code % 1000), (NULL != cond.message && rxNil != cond.message ? rtc->CString( cond.message ) : "message n/a") ); - // (NULL != cond.message && rtc->Nil() != cond.message ? rtc->CString( cond.message ) : "message n/a") ); SNPRINTF( msg, 4096, "%.16s%.512s:\n%.1024s\n%.1024s\n%.1024s", DLLNAME, header, line1, line2, line3); @@ -467,7 +467,6 @@ } else { - // sprintf(msg, "%.16s%.512s: Rexx condition [%.512s] raised", DLLNAME, header, rtc->CString(cond.conditionName)); SNPRINTF( msg, 4096, "%.16s%.512s: Rexx condition [%.512s] raised", DLLNAME, header, (NULL != cond.conditionName && rtc->Nil() != cond.conditionName ? rtc->CString(cond.conditionName) : "conditionName n/a") ); @@ -484,9 +483,11 @@ #if defined (REXX_LOADER_UNLOADER) || defined (REXX_LOADER) - // typedef void (RexxEntry *RexxPackageLoader)(RexxThreadContext *); // as of ooRexx 4.0: the library gets loaded once and is available globally to all RexxInstances, // hece it runs once per process only +/** Run when ooRexx loads this native library. Could be used e.g. for creating ooRexx constant objects to +* be saved in gloabal variables. +*/ void RexxEntry dbusLoader (RexxThreadContext *rtc) { #if defined (DEBUG_LOADER_UNLOADER ) @@ -511,7 +512,6 @@ fflush(stderr); #endif -// rgfInitLocks(); // Initialize critical section (from BSF4ooRexx) } #endif @@ -519,7 +519,6 @@ #if defined (REXX_LOADER_UNLOADER) || defined (REXX_UNLOADER) -// typedef void (RexxEntry *RexxPackageUnloader)(RexxThreadContext *); // as of ooRexx 4.0: the library gets loaded once and is available globally to all RexxInstances, // hece it runs once per process only void RexxEntry dbusUnloader (RexxThreadContext * rtc) @@ -547,7 +546,10 @@ // * --- Routines --- * // ******************************************************************** + // get and return various version information as a string +/** Returns the library version information together with the versions of runtime DBus and compile time DBus. +*/ RexxRoutine0(RexxStringObject, DbusVersionLibrary) { #ifdef RGF_INFO @@ -569,6 +571,13 @@ // ---rgf, 2003-08-06: allow Rexx to retrieve its TID (i.e. Java's "JNIEnv" object) +/** Returns the thread identification string. Can be used for debugging thread-related activations. +* +* @pparam option optional, by default a 'H'uman conceivable string ('java n', where 'n' is a +* consecutively numbered value), otherwise 'S'ystem (numeric) value gets returned +* +* @return threadInfoString +*/ RexxRoutine1(RexxStringObject, DbusGetTID, OPTIONAL_CSTRING, option) // 20090505, ---rgf, only a stub for backward compatibility { #ifdef UNIX @@ -593,17 +602,19 @@ RexxStringObject rsoOption=context->String(option==NULL ? "H" : option ); RexxStringObject rsoFormatted=(RexxStringObject) context->SendMessage2(rco, "FORMATTID", rso, rsoOption); // get DBus (bus connection) object - return rsoFormatted; } - - // external Rexx function for validating values; as DBUS 1.4.x only supports validating signatures, // initially only signatures get evaluated -// -// validate signature: if o.k. return .true, else the error message +/** Validates a signature. + * + * @param strValue the string to be validated + * @param option optional, currently only 'S' + * + * @return <code>.true</code> or <code>.false</code> + */ RexxRoutine2(RexxObjectPtr, DbusValidate, CSTRING, strValue, OPTIONAL_CSTRING, flag) { #ifdef RGF_INFO @@ -641,9 +652,7 @@ - // -------------------------------------------------------------------------------- -// TODO: decide whether to make it available // allows to halt all Rexx threads of current interpreter; experimental RexxRoutine0(RexxStringObject, DbusHaltRexx) // create Halt condition in all threads { @@ -660,28 +669,8 @@ // * --- Methods --- * // ******************************************************************** -/* --- rgf, 20140804 -RexxMethod0(RexxStringObject, DbusGetVersion) -{ -#if defined (DEBUG_METHODS) - fprintf(stderr, "===> arrived in DbusGetVersion\n"); - fflush(stderr); -#endif - int major, minor, micro; - dbus_get_version(&major, &minor, µ); - - char msg[256]=""; // buffer for error message - SNPRINTF(msg, 256, "%s=[%s], compile-time dbus=[%s], runtime dbus=[%d.%d.%d]", - DLLNAME, DBUS_REXXVERSION, DBUS_VERSION_STRING, - major, minor, micro - ); - return context->String(msg); -} - ---- */ - - +// return a connection to the system bus RexxMethod1(RexxObjectPtr, DbusNativeGetSystemBus, RexxObjectPtr, genericBusObject) { #if defined (DEBUG_METHODS) @@ -728,6 +717,7 @@ } +// return a connection to the session bus RexxMethod1(RexxObjectPtr, DbusNativeGetSessionBus, RexxObjectPtr, genericBusObject) { #if defined (DEBUG_METHODS) @@ -773,7 +763,7 @@ } - // get and return unique bus name (.Dbus instance method) +// get and return unique bus name (.Dbus instance method) RexxMethod1(RexxStringObject, DbusGetUniqueBusName, CSELF, connPtr) { #if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) @@ -799,7 +789,8 @@ return rso; } - // get and return unique machine id + +// get and return unique machine i... [truncated message content] |
From: <or...@us...> - 2014-11-02 12:14:03
|
Revision: 264 http://sourceforge.net/p/bsf4oorexx/code/264 Author: orexx Date: 2014-11-02 12:13:50 +0000 (Sun, 02 Nov 2014) Log Message: ----------- 20141102 Make sure 'rgf_util2.rex' is available, added optional open-switch to dbusdoc.rex. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dbusdoc.rex sandbox/rgf/misc/dbusoorexx/install/install_ooRexx_dbus.rex Added Paths: ----------- sandbox/rgf/misc/dbusoorexx/rgf_util2.rex Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-10-27 18:46:23 UTC (rev 263) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-11-02 12:13:50 UTC (rev 264) @@ -264,7 +264,7 @@ ::requires "dbusoorexx" LIBRARY -- get access to the native routines and methods --- ::requires "rgf_util2.rex" -- installed with the BSF4ooRexx package +::requires "rgf_util2.rex" -- utility package, e.g. installed with BSF4ooRexx /** This routine requires dynamically the ooRexx package <code>BSF.CLS</code> and * in the case it is not available allows to continue gracefully. Modified: sandbox/rgf/misc/dbusoorexx/dbusdoc.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbusdoc.rex 2014-10-27 18:46:23 UTC (rev 263) +++ sandbox/rgf/misc/dbusoorexx/dbusdoc.rex 2014-11-02 12:13:50 UTC (rev 264) @@ -3,13 +3,15 @@ author: Rony G. Flatscher (c) date: 2011-07-29/31, 2011-08-01/05, 2011-08-14 changed: 2014-08-07, rgf - make sure that connection gets closed, otherwise message loop thread lingers - version: 1.1 + 2014-11-02, rgf - made debug output parametrized, added option to open generated html fiel + version: 1.2 name: dbusdoc.rex - purpose: documents given bus name in HTML form to allow the creation of API listings - usage: rexx dbusdoc.rex [session|system] [service.bus.name] + purpose: documents given bus name in HTML form to allow the creation of API listings, + if no argument is given the available session bus names get listed on stdout + usage: rexx dbusdoc.rex [ [session|system] [service.bus.name] [-a|r] [/open] ] license: AL 2.0 ------------------------ Apache Version 2.0 license ------------------------- - Copyright 2011 Rony G. Flatscher + Copyright 2011-2014 Rony G. Flatscher Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,8 +27,26 @@ ----------------------------------------------------------------------------- */ -parse arg connection needle "-"switch . +.local~dbus.doc.debug = .true +parse arg val -- get argument string +switch="" -- make sure empty string +open ="" -- make sure empty string +if pos("-",val)>0 then -- extract "-" switch ? +do + parse var val before "-" switch after + val=before after +end + +if pos("/",val)>0 then -- extract "/" switch? +do + parse var val before "/" open after + val=before after +end + +-- parse arg connection needle . 1 "-" switch . 1 "/" open . +parse var val connection needle . + bAllBuses=.false -- by default do not inspect all buses, but those that have explicit service (bus) names bAllReservedBuses=.false -- by default do not process reserved buses only if switch<>"" then @@ -36,6 +56,21 @@ bAllReservedBuses=(sw='R') end +bOpen=.false -- by default do not open generated html-file with default app (browser) +if open<>"" then + bOpen=(open~left(1)~upper = 'O') + +if .dbus.doc.debug=.true then +do + say "settings in effect:" + say " connection: " pp(connection) + say " needle: " pp(needle) + say " process all buses: " pp(bAllBuses) + say " process all reserved buses:" pp(bAllReservedBuses) + say " open generated html-file: " pp(bOpen) + say +end + if needle="" then do if connection<>"",pos(connection, "session system")=0 then @@ -48,11 +83,16 @@ if connection<>"" then conn=.dbus~connect(connection) else + do + connection="session" conn=.dbus~session -- default to "session" connection + end o=conn~getObject(.dbus.dir~ServiceDBus, .dbus.dir~PathDBus) -- get the DBus object allBusNames=.set~new ~union(o~listNames) ~union(o~listActivatableNames) -- get all bus names on this connection + say pp(connection)"-connection, the following bus names are currently available:" + do busName over allBusNames~allIndexes~sort if bAllReservedBuses=.true then -- skip all non reserved bus names do @@ -71,7 +111,7 @@ say " " busName end - say allBusNames~items "available bus names at the moment." + say pp(connection)"-connection:" pp(allBusNames~items) "bus name(s) currently available." say conn~close @@ -145,13 +185,27 @@ call dumpStatistics conn conn~close +if bOpen=.true then -- if "/o[pen]" given then open generated html-file with default pp +do +say "Openen ljl fjdl fjlds j!" + -- open generated HTML file + parse upper source s +1 + say "attempt to open" pp(newFileName) "in browser..." + select + when s="W" then newFileName -- Windows + when s="M" then "open" newFileName -- MacOSX + otherwise + "xdg-open" newFileName -- freedesktop.org-utility (e.g. Linux) + end +end + exit usage: parse source . . fullName thisName=filespec("name",fullName) - say "usage:" thisName "[session|system] [service.bus.name]" + say "usage:" thisName "[ [session|system] [service.bus.name] ]" say say " ... session|system - optional, defaults to 'session' message bus " say " ... service.bus.name - optional, if omitted lists all known service.bus.names on the message bus" @@ -169,7 +223,7 @@ ::requires "dbus.cls" -- get support for DBus -::requires "rgf_util2.rex" -- utility package from BSF4ooRexx +::requires "rgf_util2.rex" -- utility package (e.g. from BSF4ooRexx) ::class analyzedService @@ -422,7 +476,7 @@ m~~append(crlf)~~append(crlf) -- create the object path headers -say "servicename:" pp2(servicename) +say tab1 "servicename:" pp2(servicename) call createObjectPathDocs m, o say end @@ -474,11 +528,12 @@ dt=.dbus.dir~dataTypes -- get datatype dir, "r" -> struct, "e" -> dict(entry) - say "node:" pp2(rootNode~name) +say tab2 " node:" pp2(rootNode~name) do n over rootNode~content~sort -- sortWith(comparator) if n~isA(.IDBusNode) then do -say "**debug node:" pp2(n~name) -- "content~items:" pp2(n~content~items) +if .dbus.doc.debug=.true then say tab4 "**debug node:" pp2(n~name) -- "content~items:" pp2(n~content~items) + if n~contains("interfaces")=.false then -- a fragment node attached to introspect data? iterate @@ -495,7 +550,7 @@ m~~append(tab4) ~~append('<table class="interface">')~~append(crlf) bEven=.false -say " *** debug interface:" pp2(i~name) +if .dbus.doc.debug=.true then say tab4 "*** debug interface:" pp2(i~name) oldType="" nr=0 @@ -820,4 +875,3 @@ say "now: " pp2(now) say "duration:" pp2(now-started) - Modified: sandbox/rgf/misc/dbusoorexx/install/install_ooRexx_dbus.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/install/install_ooRexx_dbus.rex 2014-10-27 18:46:23 UTC (rev 263) +++ sandbox/rgf/misc/dbusoorexx/install/install_ooRexx_dbus.rex 2014-11-02 12:13:50 UTC (rev 264) @@ -4,8 +4,8 @@ Purpose: link the necessary files to their target locations, such that liboorexx.dbus is operational Author: Rony G. Flatscher (c) 2011 Date: 2011-07-19, 2011-12-01 - Version: 1.0 - Changed: -- + Version: 1.1 + Changed: 2014-10-28, rgf: cater for new directory "installation" Usage: rexx install_ooRexx_dbus.rex [-u] ... no switch -> install @@ -14,7 +14,7 @@ license: ------------------------ Apache Version 2.0 license ------------------------- - Copyright (C) 2011 Rony G. Flatscher + Copyright (C) 2011-2014 Rony G. Flatscher Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -61,6 +61,8 @@ cmd.eDelete="rm -fv" cmd.eCopy="cp -pfv" /* force, verbose: source target(dir) [works on FAT32/NTFS systems from Linux as well] */ cmd.eLink="ln -fsv" /* force, verbose: source target(dir); (source link-to-target) */ +cmd.eSourceInstallDir="." +cmd.eSourceBinDir=".." -- defining dirs to work for ldconfig cmd.eLdConfig="ldconfig -n /usr/lib" @@ -75,7 +77,7 @@ -- link Rexx package if switch="" then -- install do - fn="dbus.cls" + fn=cmd.eSourceBinDir"/dbus.cls" tgt="/usr/bin" cmd=cmd.eCopy fn tgt say "copying DBUS Rexx package:"~left(width) cmd @@ -93,9 +95,9 @@ if switch="" then --install do if cmd.eBitness=32 then - cmd=cmd.eCopy "libdbusoorexx32.so" cmd.eTgtLib32"/"tgtLibName + cmd=cmd.eCopy cmd.eSourceInstallDir"/libdbusoorexx32.so" cmd.eTgtLib32"/"tgtLibName else if cmd.eBitness=64 then - cmd=cmd.eCopy "libdbusoorexx64.so" cmd.eTgtLib64"/"tgtLibName + cmd=cmd.eCopy cmd.eSourceInstallDir"/libdbusoorexx64.so" cmd.eTgtLib64"/"tgtLibName say "copying DBUS Rexx shared library:"~left(width) cmd end Added: sandbox/rgf/misc/dbusoorexx/rgf_util2.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/rgf_util2.rex (rev 0) +++ sandbox/rgf/misc/dbusoorexx/rgf_util2.rex 2014-11-02 12:13:50 UTC (rev 264) @@ -0,0 +1,3324 @@ +/* + url to documentation and reference card (as of 2010-05-14): + http://wi.wu.ac.at/rgf/rexx/orx20/ + + author: Rony G. Flatscher, copyright 2008-2011, all rights reserved + date: 2007-06-01 - 2007-06-02; 2007-07-30; 2007-08-02, 2007-08-07, 2007-08-15, + 2007-10-20, 2007-10-23 + 2007-12-30 - made NumberComparator more flexible, allows to use + intermixed non-numbers, if programmer wishes to do so + - MessageComparator: now allows collection of message-names + and/or message objects to use for comparisons + 2008-01-08 - added "/numeric" hint for message names + 2008-02-15 - changed StringComparator to be more flexible with its + argument + 2008-02-16 - changed StringComparator to be simpler & more flexible, + as well as sort2, stableSort2; created samples (f:\test\orx\rgf_util2) + 2008-02-17 - changed/improved StringColumnComparator, created samples for it + 2008-02-19 - removed usage of built-in comparators in sort2() and + stableSort2(), so none of the 3.2.0 specialized + Comparators are needed + - added "-length" to ABBREV2(), + 2008-02-20 - added "-count" to CHANGESTR2() ("change last 'count' needle occurrences) + - added negative starting position to lastPos2() + - added left2()-BIF, handling with negative start position + - added right2()-BIF, handling with negative start position + - added/enhanced pos2()-BIF with negative start position + 2008-02-21 - added DELSTR2(), LOWER2(), SUBSTR2(), UPPER2() + which now all accept negative numbers + 2008-02-22 - added OVERLAY2(), which now accepts negative numbers + 2008-02-25 - added PARSEWORDS2() + 2008-03-13 - changed DUMP2 to cater for the different kind of collections, + ones), will not sort OrderedCollections, but honor their order + [will show exact array-index values (including multi-dimensional], + will sort by index-value otherwise, in the case of "allAt"-collections + (e.g. Relation) will give a list of the items associated with the + same index + 2008-03-14 - changed DUMP2() to display item, if allAt() returns a collection + containing only one item; added SUBCHAR2() allowing negative + positions as well + added negative position to WORDPOS2() + added DELWORD2, SUBWORD2(), WORD2(), WORDINDEX2(), WORDLENGTH2() + 2008-03-16 - tested and fixed StringOfWords class + 2008-03-19 - recoded sort2() and stableSort2() to take advantage of .StringComparator + and .StringColumnComparator + 2008-03-27 - allow in list of messages array-elements with two entries, where + - arr[1]=messageString|messageObject + - arr[2]=flagString + - added option "M" (message sort) to sort2() and stableSort2() + 2008-03-29, - sort2() and stableSort2() now accept as their first argument + an object with a "makeArray" method in addition to instances + of array + - .MessageComparator: if an array-element is given, then index 3 in + addition to index 2 are regarded to be flag (parts) + 2008-03-16: - dump2 now gracefully deals with non-collection and non-supplier + objects: an appropriate hint is given, as well as the type and + (string) value of the argument + 2009-03-15: - changed default of string-routines to use the "caseless" + version + 2009-03-20: - changed NumericComparator to use caseless comparison in case + relaxed comparisons are carried out + - change default sort2() and stableSort2() to use "N", i.e. + ascending sort with numeric comparisons, and caseless comparisons + - added MakeArray to class StringOfWords + + 2009-12-14: - make sure all public routines have a trailing "2" to indicate that + they come from this package and to avoid name clashes with earlier + implementations + 2009-12-19: - changed default for sort2() and stableSort2() to "ignore case", if + string objects are to be sorted + 2009-12-22: - When creating a NumberComparator one can now determine the order (A|D) + and kind of comparison (I | C) + 2009-12-26: - default to "I"gnore case in .StringColumnComparator + - parseWords2: if returning position array, supply third array element + 2009-12-27: - .StringOfWords: + - delWord(): make sure dirty flags are set + - subWord(): don't change string itself, if returning subwords + - wordPos(): default for compare now "I[gnore]" case + 2009-12-28: - .StringOfWords: + - delWord(): do not edit string in place, return an edited copy + 2010-01-16, change "rgf.numbers" to "rgf.digits" (thanks to Walter Pachl!) + 2010-08-15, .NumberComparator ignored second argument (order) in constructor, + if first argument was set to .true (thanks to Glenn Knickerbocker + on comp.lang.rexx) + 2011-05-30, - fix error not allowing suppliers to be shown in dump2(); this + follows Jean-Louis fix in his ooRexx sandbox as of 2011-05-30; + also changed sequence of argument checking to follow sequence + of arguments as seen in Jean-Louis' version of rgf_util2.rex + 2011-06-08, - new routine ppCondition2(co[,bShowPackage=.false [,indent1="09"x [,indent2="0909"x [,indent3="090909"x [,lf=.endOfLine]]]]]]): + returns a string rendering of the supplied condition object "co" + + - new routine ppPackage2(package[,indent1=""[, indent2="09"x[, lf==.endOfLine]]): + returns a string rendering of the supplied package object + 2011-08-03, - ppCondition2(): make sure that length is only calculated, if a string in hand + + + purpose: set of 3.2 utilities to ease programming of 3.2.0, e.g. offer sort2()- and + stableSort2()-BIFs that handle all kind of standard sorting needs, thereby + removing the need for "low level" coding in ooRexx itself + + TODO: - ? create a DateTime2 class with renaming existing conversion + methods to start with "to"; also supply epoch-related + conversions (from/to); also allow to define the date + when Julian calendar took effect; supply method to determine + Easter Sunday (depending on the calendar in use) + + - create routines "leftWord([-]n)", "rightWord([-]n)" + + license: Choice of + ASF 2.0, <http://www.apache.org/licenses/LICENSE-2.0>: + --------------- cut here ---------------- + Copyright 2008-2011 Rony G. Flatscher + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --------------- cut here ---------------- + + or + + LGPL 3.0, <http://www.fsf.org/licensing/licenses/lgpl.html> (as of: 2008-02-17) + + version: 1.0.6 +*/ + +.local~rgf.non.printable=xrange("00"x,"1F"x)||"FF"x +.local~rgf.alpha.low="abcdefghijklmnopqrstuvwxyz" +.local~rgf.alpha.upper =.rgf.alpha.low~upper +.local~rgf.alpha =.rgf.alpha.low || .rgf.alpha.upper +.local~rgf.digits ="0123456789" +.local~rgf.alphanumeric=.rgf.alpha || .rgf.digits + +.local~rgf.symbol.chars=".!_?" + + +parse version "_" v "(" + +if v<4 then -- ooRexx smaller than 4.0.0, then use ".public_routines" +do + -- make version"2" BIFs globally available + do idx over .methods + .public_routines~put(.methods[idx], idx) + end + + -- make the classes seen globally via .local directory + .local~messageComparator =.messageComparator + .local~NumberComparator =.NumberComparator + .local~StringComparator =.StringComparator + .local~StringColumnComparator=.StringColumnComparator + .local~StringOfWords =.StringOfWords +end +else -- running under ooRexx 4.0.0 or higher +do + thisPackage=.context~package + do idx over .methods + -- routine=.routine~new(idx, .methods[idx]~source) + routine=.routine~new("DYNAMICALLY_CREATED_"idx, .methods[idx]~source) + thisPackage~addPublicRoutine(idx, routine) + end + + -- make the classes seen globally via the package's public classes + thisPackage~addPublicClass("MessageComparator" , .messageComparator ) + thisPackage~addPublicClass("NumberComparator" , .NumberComparator ) + thisPackage~addPublicClass("StringComparator" , .StringComparator ) + thisPackage~addPublicClass("StringColumnComparator", .StringColumnComparator) + thisPackage~addPublicClass("StringOfWords" , .StringOfWords ) +end + +/* ======================================================================= */ +/* === methods to be used for new BIFs === */ +/* ======================================================================= */ + + -- 2008-02-19, rgf: abbrev info, string [, n-length] + /* if length is negative, then */ +/* ======================================================================= */ +::method "abbrev2" + use strict arg arg1, arg2, ... + + argNr=arg() -- get maximum number of arguments + BIFpos=3 -- last classic BIF argument position + maxArgs=4 + + signal on syntax + if argNr>maxArgs then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArgs) + + methName="abbrev" -- base name for the message to send + + bCaseDependent =.false -- default to caseless version + if argNr>=BIFpos, \datatype(arg(argNr),"N") then + do + letter=arg(argNr)~strip~left(1)~upper + if pos(letter,"CI")=0 then -- illegal argument! + raise syntax 93.914 array (argNr, "C, I", arg(argNr)) + bCaseDependent=(letter="C") + argNr-=1 -- decrease one from total number of arguments + end + + newArr=.array~new -- create new array for the arguments + newArr[1]=arg2 -- save info + if arg(3,"Exists"), datatype(arg(3),"N") then + do + arg3=arg(3) -- negative? + if arg3<0 then -- length, i.e. extract from right + do + newArr[1]=arg2~right(-arg3) -- get the chars from the right + end + else + do + newArr[2]=arg3 + end + end + + -- now invoke the operation + if bCaseDependent then + return .message~new(arg(1), methName, "A", newArr)~send + else + return .message~new(arg(1), "caseless"methName, "A", newArr)~send + +syntax: + raise propagate + +/* ======================================================================= */ +/* if count is negative, then the number of changes occur from the right side + ("change the last 'count' of 'needle' occurrences in string") +*/ +::method "changeStr2" -- (needle,haystack,newNeedle[,[-]count][,CI]) + use strict arg arg1needle, arg2haystack, arg3newNeedle, ... -- make sure at least three args are supplied + parse arg arg1needle, arg2haystack, arg3newNeedle, arg4count + + argNr=arg() -- get maximum number of arguments + BIFpos=3 -- last mandatory BIF argument position + maxArgs=5 + + signal on syntax + if argNr>maxArgs then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArgs) + + methName="changeStr" -- base name for the message to send + + bCaseDependent =.false -- default to caseless version + + newArr=.array~new -- create new array for the arguments + newArr[1]=arg1needle + newArr[2]=arg3newNeedle + + signal on syntax + if argNr>(BIFpos) then -- either count or "CI" + do + count=.nil + if \datatype(arg(argNr),"W") then -- "C" or "I" + do + letter=arg(argNr)~strip~left(1)~upper + if pos(letter,"CI")=0 then -- illegal argument! + raise syntax 93.914 array (argNr, "C, I", arg(argNr)) + bCaseDependent=(letter="C") + + if argNr>4, arg(4,"E") then -- check for "count" argument + count=arg4count -- save count-value + end + else + count=arg4count -- save count-value + end + + if datatype(count,"N") then -- count is numeric, check it out + do + if count<0 then -- change the "count" last occurrences in string! + do + -- search starting position for changes + len=length(arg2haystack) -- remember length of string + pos=len -- start out with last position of string + + -- find starting position + do i=1 to -count until pos=0 + oldPos=pos + + if oldPos<=1 then leave -- already at beginning! + if bCaseDependent then + do + pos= lastPos(arg1needle, arg2haystack, oldPos-(1-(len=oldPos))) + end + else -- ignore case + do + pos=lastPos2(arg1needle, arg2haystack, oldPos-(1-(len=oldPos)), "I") + end + end + + -- carry out the changes + if oldPos>1, pos>0 then -- o.k., not all "needle"s to change: split, change and return + do + -- extract part that does not get changed + mb=.MutableBuffer~new~~append( arg2haystack~substr(1,Pos-1) ) + + -- change needle in remainder, add changed string to MutableBuffer + if bCaseDependent then + mb~append( .message~new(arg2haystack~substr(Pos), methName, "A", newArr)~send) + else + mb~append( .message~new(arg2haystack~substr(Pos), "caseless"methName, "A", newArr)~send) + return mb~string -- return changed string + end + end + else + do + newArr[3]=arg4count -- save "count" argument + end + end + + -- now invoke the operation + if bCaseDependent then + return .message~new(arg2haystack, methName, "A", newArr)~send + else + return .message~new(arg2haystack, "caseless"methName, "A", newArr)~send + +syntax: + raise propagate + +/* ======================================================================= */ +-- string1, string2[, [padChar] [,{C|I}]] +::method "compare2" + use strict arg arg1string1, arg2string2, arg3padChar=" ", ... + + argNr=arg() -- get maximum number of arguments + BIFpos=3 -- last classic BIF argument position + maxArg=4 + + signal on syntax + if argNr>maxArg then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArg) + + methName="compare" -- base name for the message to send + + bCaseDependent =.false -- default to caseless version + if argNr>BIFpos then + do + letter=arg(maxArg)~strip~left(1)~upper + if pos(letter,"CI")=0 then -- illegal argument! + raise syntax 93.914 array (argNr, "C, I", arg(maxArg)) + bCaseDependent=(letter="C") + argNr-=1 -- decrease one from total number of arguments + end + + newArr=.array~new -- create new array for the arguments + newArr[1]=arg2string2 -- other string + newArr[2]=arg3padChar -- pad character + + -- now invoke the operation + if bCaseDependent then + return .message~new(arg1string1, methName, "A", newArr)~send + else + return .message~new(arg1string1, "caseless"methName, "A", newArr)~send + +syntax: + raise propagate + + +/* ======================================================================= */ +-- not a BIF ::method "compareTo2" + +/* ======================================================================= */ +-- needle, haystack[,{C|I}] +::method "countStr2" + use strict arg arg1needle, arg2haystack, ... + + argNr=arg() -- get maximum number of arguments + BIFpos=2 -- last classic BIF argument position + maxArg=3 + + signal on syntax + if argNr>maxArg then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArg) + + methName="countStr" -- base name for the message to send + + bCaseDependent =.false -- default to caseless version + if argNr>BIFpos then + do + letter=arg(maxArg)~strip~left(1)~upper + if pos(letter,"CI")=0 then -- illegal argument! + raise syntax 93.914 array (maxArg, "C, I", arg(maxArg)) + bCaseDependent=(letter="C") + end + + -- now invoke the operation + if bCaseDependent then + return .message~new(arg2haystack, methName, "I", arg1needle )~send + else + return .message~new(arg2haystack, "caseless"methName, "I", arg1needle )~send + +syntax: + raise propagate + + + -- 2008-02-21, rgf: delStr2(string ,n-start [, n-length]) + /* if length is negative, then */ +/* ======================================================================= */ +::method "delStr2" + use strict arg arg1, ... -- make sure we have at least one arg + parse arg ., arg2, arg3 + + argNr=arg() -- get maximum number of arguments + BIFpos=3 -- last classic BIF argument position + maxArgs=3 + + signal on syntax + if argNr>maxArgs then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArgs) + + methName="delStr" -- base name for the message to send + + len1=length(arg1) -- get length of string + newArr=.array~new -- create new array for the arguments + + if datatype(arg2,"W") then -- start + do + if arg2<0 then -- negative, start from right + do + tmp=len1+arg2+1 -- get starting position + if tmp<2 then -- start at first char + arg2=1 + else + arg2=tmp + end + newArr[1]=arg2 -- start position + end + else + do + raise syntax 93.905 array('2 ("start position")', arg2) + end + + if arg(3,"Exists") then -- length + do + if datatype(arg2, "W") then + do + if arg3<0 then -- we need to move the starting point to the left! + do + arg2=arg2+arg3+1 -- subtract arg3 + if arg2<1 then -- reset start to 1 + newArr[1]=1 + else -- new start pos + newArr[1]=arg2 + + arg3=-arg3 -- turn it into a positive number + end + end + else + do + raise syntax 93.905 array('3 ("length")', arg3) + end + + newArr[2]=arg3 -- length + end + + -- now invoke the operation + return .message~new(arg(1), methName, "A", newArr)~send + +syntax: + raise propagate + + + -- 2008-03-14, rgf: +/* ======================================================================= */ +/* delWord2(string, start[, length]) + ... if no words, returns received string + +*/ +::method "delWord2" -- allows negative start and length + use strict arg string, arg2, ... -- make sure we have at least one arg + + parse arg string, arg2, arg3 + + argNr=arg() -- get maximum number of arguments + maxArgs=3 + + signal on syntax + if argNr>maxArgs then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArgs) + + methName="delWord" -- base name for the message to send + newArr=.array~new -- create new array for the arguments + + nrWords=words(string) -- calc # of words + + if \datatype(arg2, "W") then + raise syntax 93.905 array('2 ("starting word position")', arg3) + + newArr[1]=arg2 -- save starting pos + if arg2<0 then + do + tmp=nrWords+arg2+1 -- calc starting position from right + if tmp<1 then -- if before first word, start at first word + tmp=1 + newArr[1]=tmp -- save new starting position + end + + if arg(3,"Exists") then -- if given, process length argument + do + if \datatype(arg3, "W") then + raise syntax 93.905 array('3 ("number of words")', arg3) + + if arg3<0 then -- determine new starting position and number of words to delete + do + oldStart=newArr[1] -- save old starting position + tmp=oldStart+arg3+1 + if tmp<1 then -- oops, make sure we start at first word + tmp=1 + + newArr[1]=tmp -- new start position + newArr[2]=oldStart-tmp+1 -- length argument (nr of words to delete) + end + else + do + newArr[2]=arg3 -- length argument + end + end + + if nrWords=0 then -- nothing to do, return empty/spacy string + return string + + -- now invoke the operation + return .message~new(string, methName, "A", newArr)~send + +syntax: + raise propagate + + + + + +/* ======================================================================= */ +-- not a BIF ::method "Equals2" + + + +/* ======================================================================= */ +/* lastPos needle, haystack [,[n-start] [,{C|I}]] */ +::method "lastPos2" + use strict arg arg1needle, arg2haystack, ... + + argNr=arg() -- get maximum number of arguments + BIFpos=3 -- last classic BIF argument position + maxArgs=4 + + signal on syntax + if argNr>maxArgs then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArgs) + + StringPos=1 -- position of string object to work with + methName="lastPos" -- base name for the message to send + + bCaseDependent =.false -- default to caseless version + if argNr>=BIFpos, \datatype(arg(argNr),"N") then + do + letter=arg(argNr)~strip~left(1)~upper + if pos(letter,"CI")=0 then -- illegal argument! + raise syntax 93.914 array (argNr, "C, I", arg(argNr)) + bCaseDependent=(letter="C") + argNr-=1 -- decrease one from total number of arguments + end + + newArr=.array~new -- create new array for the arguments + newArr[1]=arg1needle -- needle + arg3=arg(3) + if arg(3,"Exists"), datatype(arg3,"N") then + do + if arg3<0 then -- negative start column: count from right + do + len2=length(arg2haystack) -- get length of string to scan + if -arg3 >= len2 then -- beyond starting position, scan string normally + return 0 -- beyond start, needle cannot be found! + else + newArr[2]=len2+arg3+1 -- determine starting position + end + else -- positive start column + do + newArr[2]=arg3 -- save starting position + end + end + + -- now invoke the operation + if bCaseDependent then + return .message~new(arg2haystack, methName, "A", newArr)~send + else + return .message~new(arg2haystack, "caseless"methName, "A", newArr)~send + +syntax: + raise propagate + + +/* ======================================================================= */ +-- not a BIF ::method "match2" + +/* ======================================================================= */ +/* left2 string, length [,pad] */ +::method "left2" + use strict arg arg1string, arg2length, ... + + argNr=arg() -- get maximum number of arguments + BIFpos=3 -- last classic BIF argument position + maxArgs=3 + + --signal on syntax + if argNr>maxArgs then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArgs) + + if \datatype(arg2length,"W") then + do + raise syntax 93.905 array('"length"', arg2) + end + + + bLeftBIF=(arg2length>0) -- use left() or right() BIF ? + newArr=.array~new -- create new array for the arguments + + if bLeftBIF then + newArr[1]=arg2length + else + newArr[1]=-arg2length + + if arg(3,"Exists") then -- padChar supplied ? + newArr[2]=arg(3) + + -- now invoke the operation + if bLeftBIF then + return .message~new(arg1string, "left", "A", newArr)~send + else + return .message~new(arg1string, "right", "A", newArr)~send + +syntax: + raise propagate + + + + -- 2008-02-21, rgf: lower2(string [,[n-start] [, n-length]]) + /* if length is negative, then */ +/* ======================================================================= */ +::method "lower2" + use strict arg arg1, ... -- make sure we have at least one arg + parse arg ., arg2, arg3 + + argNr=arg() -- get maximum number of arguments + BIFpos=3 -- last classic BIF argument position + maxArgs=3 + + signal on syntax + if argNr>maxArgs then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArgs) + + methName="lower" -- base name for the message to send + + len1=length(arg1) -- get length of string + newArr=.array~new -- create new array for the arguments + + if arg(2,"Exists") then -- start + do + if datatype(arg2, "W") then + do + if arg2<0 then -- negative, start from right + do + tmp=len1+arg2+1 -- get starting position + if tmp<2 then -- start at first char + arg2=1 + else + arg2=tmp + end + end + else + do + raise syntax 93.905 array('2 ("start position")', arg2) + end + + newArr[1]=arg2 -- start position + end + + if arg(3,"Exists") then -- length + do + if datatype(arg3,"W") then + do + if arg3<0 then -- we need to move the starting point to the left! + do + arg2=arg2+arg3+1 -- subtract arg3 + if arg2<1 then -- reset start to 1 + newArr[1]=1 + else -- new start pos + newArr[1]=arg2 + + arg3=-arg3 -- turn it into a positive number + end + end + else + do + raise syntax 93.905 array('3 ("length")', arg3) + end + + newArr[2]=arg3 -- length + end + + -- now invoke the operation + return .message~new(arg(1), methName, "A", newArr)~send + +syntax: + raise propagate + + + +/* ======================================================================= */ +-- not a BIF ::method "match2" +/* ======================================================================= */ +-- not a BIF ::method "matchChar2" + + + -- 2008-02-22, rgf: overlay2(new, target [,[n-target-start] [, n-new-length]] [,pad]) + --> ATTENTION: if beyond start, prepend appropriate length pad-filled ! +/* ======================================================================= */ +::method "overlay2" + use strict arg new1string, arg1string, ... -- make sure we have at least two arg + parse arg ., ., arg2start, arg3NewLength, arg4pad + + argNr=arg() -- get maximum number of arguments + BIFpos=5 -- last classic BIF argument position + maxArgs=5 + + signal on syntax + if argNr>maxArgs then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArgs) + + methName="overlay" -- base name for the message to send + + len1=length(arg1string) -- get length of string + newArr=.array~new -- create new array for the arguments + newArr[1]=new1string -- "new"-string + + prepend="" -- optional prepend string (if positioning before start!) + + arg2startori=arg2start -- save passed-in value, if any + if arg4pad=="" then arg4pad=" "-- define blank as the default pad char + + if arg(3,"Exists") then -- start in "target"-string + do + if datatype(arg2start,"W") then + do + if arg2start<0 then -- negative, start from right + do + tmp=len1+arg2start+1 -- get starting position + if tmp<2 then -- start at first char + do + if tmp<0 then + prepend=copies(arg4pad, -tmp+1) -- create prepend-string + else if tmp=0 then -- fencepost + prepend=arg4pad + + arg2start=1 + end + else + arg2start=tmp + end + end + else + do + raise syntax 93.905 array('3 ("start position in ''target'' string")', arg2start) + end + + newArr[2]=arg2start -- start position + end + + if arg(4,"Exists") then -- "new"-length + do + if datatype(arg3NewLength,"W") then + do + if arg3NewLength<0 then -- we need to move the starting point to the left! + do + arg3NewLength=-arg3NewLength -- turn into a positive number + newArr[1]=right(new1string, arg3NewLength, arg4pad) -- "new"-string + end + else + newArr[1]=left(new1string, arg3NewLength, arg4pad) -- "new"-string + end + else + do + raise syntax 93.905 array('3 ("length of ''new''-string")', arg3NewLength) + end + + newArr[3]=arg3NewLength -- length + end + + if arg4pad<>"" then -- pad-char + newArr[4]=arg4pad + + -- now invoke the operation + return .message~new(prepend||arg1string, methName, "A", newArr)~send + +syntax: + raise propagate + + + + +/* ======================================================================= */ +/* Pos needle, haystack [,[n-start] [,{C|I}]] */ +::method "Pos2" + use strict arg arg1needle, arg2haystack, ... + + argNr=arg() -- get maximum number of arguments + BIFpos=3 -- last classic BIF argument position + maxArgs=4 + + signal on syntax + if argNr>maxArgs then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArgs) + + methName="Pos" -- base name for the message to send + + bCaseDependent =.false -- default to caseless version + if argNr>=BIFpos, \datatype(arg(argNr),"W") then + do + letter=arg(argNr)~strip~left(1)~upper + if pos(letter,"CI")=0 then -- illegal argument! + raise syntax 93.914 array (argNr, "C, I", arg(argNr)) + bCaseDependent=(letter="C") + argNr-=1 -- decrease one from total number of arguments + end + + newArr=.array~new -- create new array for the arguments + newArr[1]=arg1needle -- needle + arg3=arg(3) + if arg(3,"Exists"), datatype(arg3,"N") then + do + if arg3<0 then -- negative start column: count from right + do + len2=length(arg2haystack) -- get length of string to scan + if -arg3 >= len2 then -- beyond starting position, scan string normally + return 0 -- beyond start, needle cannot be found! + else + newArr[2]=len2+arg3+1 -- determine starting position + end + else -- positive start column + do + newArr[2]=arg3 -- save starting position + end + end + + -- now invoke the operation + if bCaseDependent then + return .message~new(arg2haystack, methName, "A", newArr)~send + else + return .message~new(arg2haystack, "caseless"methName, "A", newArr)~send + +syntax: + raise propagate + + + + +/* ======================================================================= */ +/* right2 string, length [,pad] */ +::method "right2" + use strict arg arg1string, arg2length, ... + + argNr=arg() -- get maximum number of arguments + BIFpos=3 -- last classic BIF argument position + maxArgs=3 + + --signal on syntax + if argNr>maxArgs then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArgs) + + if \datatype(arg2length,"W") then + do + raise syntax 93.905 array('"length"', arg2) + end + bLeftBIF=(arg2length>0) -- use left() or right() BIF ? + + newArr=.array~new -- create new array for the arguments + + if bLeftBIF then + newArr[1]=arg2length + else + newArr[1]=-arg2length + + if arg(3,"Exists") then -- padChar supplied ? + newArr[2]=arg(3) + + -- now invoke the operation + if bLeftBIF then + return .message~new(arg1string, "right", "A", newArr)~send + else + return .message~new(arg1string, "left", "A", newArr)~send + + +syntax: + raise propagate + + + + + +/* ======================================================================= */ +/* "Front end" to .Arrays two sort methods "sort" and "sortWith" to simplify usage. + Sorts array in place, but also returns it. +*/ + +/* + usage: sort2(array [,A|D][,][C|I][N]) + sort2(array, comparator [,A|D]) + + A|D ... Ascending (default) | Descending + C|I|N ... respect Case | Ignore case (default) | Numeric (Rexx-style numbers, default) + +------------ + sort2(array) ... sort() + + sort2(array, comparator[,"A|D"]) ... sortWith(comparator) + + sort2(array, collection) ... sortWith(.StringColumnComparator(...)) + sort2(array, n, ...) + + sort2(array, ["A|D"][,"C|I|N"]) ... sortWith(.StringComparator) + sort2(array, "[A[scending]|D[escending]][",C[aseDependent]|I[gnoreCase]|N[umeric]"]) + sort2(array, "A[C|I|N] | D[C|I|N]"...) + + Sort2(array, "M[essages]", message...) ... sortWith(.MessageComparator(...)) + Sort2(array, "M[essages]", arrayOfMessages...) + +*/ +::method "sort2" + use strict arg arg1, arg2="A", arg3="IN", ... + + signal on syntax + + if \arg1~isA(.array) then + do + if \arg1~hasMethod("makeArray") then + raise syntax 93.948 array (1, "Array (or a class with a method 'MAKEARRAY')") + arg1=arg1~makeArray -- get the array that represents the collection + end + + argNr=arg() -- get number of args + if argNr=1 then -- default sort as only array collection is given + do + if arg1[1]~isA(.string) then -- string objects to sort? + return sort2(arg1, "A", "IN") -- sort decimal numerically and caselessly + + return arg1~sort -- sort without any assumptions + end + + -- two arguments only, if strings to sort default to "IN" (case-independent, numeric) + if argNr=2, arg2~isA(.string) then -- if a descending sort + do + order=arg2~strip~left(1)~upper -- extract first letter in capital + if order="A" then -- sort ascendingly + do + if arg1[1]~isA(.string) then -- string objects to sort? + return sort2(arg1, "A", "IN") -- sort ignoring case, compare numbers as numbers + + return arg1~sort + end + else if order="D" then -- sort descendingly + do + if arg1[1]~isA(.string) then -- string objects to sort? + return sort2(arg1, "D", "IN") -- sort ignoring case, compare numbers as numbers + + return arg1~sortWith(.DescendingComparator~new) + end + end + + + if arg2~isA(.Comparator) then -- o.k. a comparator given, use it + do + if argNr>3 then -- in this case a maximum of three args allowed + raise syntax 93.902 array (3) + + kind="A" -- default to ascending sort + if argNr=3 then -- a third argument given + do + kind=arg3~strip~left(1)~upper -- get first char in uppercase + if pos(kind, "AD")=0 then -- not a valid argument given! + raise syntax 93.914 array (3, "A, D", arg3) + end + + if kind="A" then -- sort ascendingly + return arg1~sortWith(arg2) + else + return arg1~sortWith(.InvertingComparator~new(arg2)) + end + + if datatype(arg2,"W") | arg2~isA(.OrderedCollection) | arg2~isA(.Supplier) then + do + if arg2~isA(.Collection) | arg2~isA(.Supplier) then -- a collection indicating positions, lengths, type of sort + do + if argNr>2 then -- in this case only two arguments allowed! + raise syntax 93.902 array (2) + end + else -- argument is a number, hence interpreted as a starting column + do + arg2=arg(2,"Array") -- turn all args into an array collection + end + + -- use a StringColumnComparator for sorting + return arg1~sortWith(.StringColumnComparator~new(arg2)) + end + + -- ---rgf, 2008-03-27: allow message(s) as arguments + if arg2~isA(.string) then -- check whether "M"essage argument given + do + if arg2~strip~left(1)~upper="M" then + do + if argNr=3 then -- single argument follows + comparator=.MessageComparator~new(arg3) + else -- turn remaining args into an array object + comparator=.MessageComparator~new(arg(3,"Array")) + + return arg1~sortWith(comparator) + end + end + + -- o.k. now use ".StringComparator" for sorting ("CIN") + if argNr>3 then -- in this case only three args allowed at most + raise syntax 93.902 array (3) + + if argNr=2 then -- let .StringComparator deal with the args + return arg1~sortWith(.StringComparator~new(arg2)) + else + return arg1~sortWith(.StringComparator~new(arg2, arg3)) + +syntax: raise propagate + + + + + +/* + usage: stableSort2(array [,A|D][,][C|I|N]) + stableSort2(array, comparator [,A|D]) + + A|D ... Ascending (default) | Descending + C|I|N ... respect Case | Ignore case (default) | Numeric (Rexx-style numbers) + +------------ + stableSort2(array) ... sort() + + stableSort2(array, comparator[,"A|D"]) ... sortWith(comparator) + + stableSort2(array, collection) ... sortWith(.StringColumnComparator(...)) + stableSort2(array, n, ...) + + stableSort2(array, ["A|D"][,"C|I|N"]) ... sortWith(.StringComparator) + stableSort2(array, "[A[scending]|D[escending]][",C[aseDependent]|I[gnoreCase]|N[umeric]"]) + stableSort2(array, "A[C|I|N] | D[C|I|N]"...) + + stableSort2(array, "M[essages]", message...) ... sortWith(.MessageComparator(...)) + stableSort2(array, "M[essages]", arrayOfMessages...) + +*/ +::method "stableSort2" + use strict arg arg1, arg2="A", arg3="I", ... + + signal on syntax + + if \arg1~isA(.array) then + do + if \arg1~hasMethod("makeArray") then + raise syntax 93.948 array (1, "Array (or a class with a method 'MAKEARRAY')") + arg1=arg1~makeArray -- get the array that represents the collection + end + + argNr=arg() -- get number of args + if argNr=1 then -- default sort as only array collection is given + do + if arg1[1]~isA(.string) then -- string objects to sort? + return stableSort2(arg1, "A", "N") -- sort decimal numerically and caselessly + + return arg1~stableSort -- sort without any assumptions + end + + -- two arguments only, if strings to sort default to "IN" (case-independent, numeric) + if argNr=2, arg2~isA(.string) then -- if a descending sort + do + order=arg2~strip~left(1)~upper -- extract first letter in capital + if order="A" then -- sort ascendingly + do + if arg1[1]~isA(.string) then -- string objects to sort? + return stableSort2(arg1, "A", "IN") -- sort ignoring case, compare numbers as numbers + + return arg1~stableSort + end + else if order="D" then -- sort descendingly + do + if arg1[1]~isA(.string) then -- string objects to sort? + return stableSort2(arg1, "D", "IN") -- sort ignoring case, compare numbers as numbers + + return arg1~stableSortWith(.DescendingComparator~new) + end + end + + + if arg2~isA(.Comparator) then -- o.k. a comparator given, use it + do + if argNr>3 then -- in this case a maximum of three args allowed + raise syntax 93.902 array (3) + + kind="A" -- default to ascending sort + if argNr=3 then -- a third argument given + do + kind=arg3~strip~left(1)~upper -- get first char in uppercase + if pos(kind, "AD")=0 then -- not a valid argument given! + raise syntax 93.914 array (3, "A, D", arg3) + end + + if kind="A" then -- sort ascendingly + return arg1~stableSortWith(arg2) + else + return arg1~stableSortWith(.InvertingComparator~new(arg2)) + end + + if datatype(arg2,"W") | arg2~isA(.OrderedCollection) | arg2~isA(.Supplier) then + do + if arg2~isA(.Collection) | arg2~isA(.Supplier) then -- a collection indicating positions, lengths, type of sort + do + if argNr>2 then -- in this case only two arguments allowed! + raise syntax 93.902 array (2) + end + else -- argument is a number, hence interpreted as a starting column + do + arg2=arg(2,"Array") -- turn all args into an array collection + end + + -- use a StringColumnComparator for sorting + return arg1~stableSortWith(.StringColumnComparator~new(arg2)) + end + + -- ---rgf, 2008-03-27: allow message(s) as arguments + if arg2~isA(.string) then -- check whether "M"essage argument given + do + if arg2~strip~left(1)~upper="M" then + do + if argNr=3 then -- single argument follows + comparator=.MessageComparator~new(arg3) + else -- turn remaining args into an array object + comparator=.MessageComparator~new(arg(3,"Array")) + + return arg1~stableSortWith(comparator) + end + end + + -- o.k. now use ".StringComparator" for sorting ("CIN") + if argNr>3 then -- in this case only three args allowed at most + raise syntax 93.902 array (3) + + if argNr=2 then -- let .StringComparator deal with the args + return arg1~stableSortWith(.StringComparator~new(arg2)) + else + return arg1~stableSortWith(.StringComparator~new(arg2, arg3)) + +syntax: raise propagate + + + + + + + -- 2008-03-14, rgf: subChar2(string,n-pos) + /* if length is negative, then position from right (end of string) */ + --> ATTENTION: if beyond start, prepend appropriate length pad-filled ! +/* ======================================================================= */ +::method "subchar2" + use strict arg arg1, arg2 -- make sure we have at least one arg + parse arg arg1, arg2 + + argNr=arg() -- get maximum number of arguments + maxArgs=2 + + signal on syntax + if argNr<>maxArgs then -- not correct amount of arguments ? + do + if argNr<maxArgs then + raise syntax 93.901 array (2) + else + raise syntax 93.902 array (2) + end + + + len1=length(arg1) -- get length of string + + if datatype(arg2,"W") then + do + if arg2<0 then -- negative, start from right + do + arg2=len1+arg2+1 -- calc starting position + if arg2<1 then -- beyond string, return empty string (i.e. no char) + return "" + end + + if arg2=0 then + raise syntax 93.924 array (arg2) + else if arg2>len1 then-- beyond string, return empty string (i.e. no char) + return "" + end + else + do + raise syntax 93.905 array('2 ("start position")', arg2) + end + + -- now invoke the operation + return arg1~substr(arg2,1) -- return extracted char + +syntax: + raise propagate + + + + -- 2008-02-21, rgf: substr2(string [,[n-start] [, n-length]] [,pad]) + /* if length is negative, then */ + --> ATTENTION: if beyond start, prepend appropriate length pad-filled ! +/* ======================================================================= */ +::method "substr2" + use strict arg arg1, ... -- make sure we have at least one arg + parse arg ., arg2, arg3, arg4 + + argNr=arg() -- get maximum number of arguments + BIFpos=4 -- last classic BIF argument position + maxArgs=4 + + signal on syntax + if argNr>maxArgs then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArgs) + + methName="substr" -- base name for the message to send + + len1=length(arg1) -- get length of string + newArr=.array~new -- create new array for the arguments + + prepend="" -- optional prepend string (if positioning before start!) + + arg2ori=arg2 -- save passed-in value, if any + if arg4=="" then arg4=" "-- define blank as the default pad char + + if arg(2,"Exists") then -- start + do + if datatype(arg2,"W") then + do + if arg2<0 then -- negative, start from right + do + tmp=len1+arg2+1 -- get starting position + if tmp<2 then -- start at first char + do + if tmp<0 then + prepend=copies(arg4, -tmp+1) -- create prepend-string + else if tmp=0 then -- fencepost + prepend=arg4 + + arg2=1 + end + else + arg2=tmp + end + end + else + do + raise syntax 93.905 array('2 ("start position")', arg2) + end + + newArr[1]=arg2 -- start position + end + + if arg(3,"Exists") then -- length + do + if datatype(arg3,"W") then + do + if arg3<0 then -- we need to move the starting point to the left! + do + tmp =arg2+arg3 -- subtract arg3 + + if tmp <1 then -- reset start to 1 + do + newArr[1]=1 -- substring from new pos "1" + if tmp <0 then -- create (new?) prepend string + prepend=prepend||copies(arg4, -tmp) -- create prepend-string + end + else -- new start pos + newArr[1]=tmp+1 + arg3=-arg3 -- turn it into a positive number + end + end + else + do + raise syntax 93.905 array('3 ("length")', arg3) + end + + newArr[2]=arg3 -- length + end + + if arg4<>"" then -- pad-char + newArr[3]=arg4 + + -- now invoke the operation + return .message~new(prepend||arg1, methName, "A", newArr)~send + +syntax: + raise propagate + +pp: + if arg(1)=.nil then return "" + else return "," arg(1) + + + + + -- 2008-03-14, rgf: +/* ======================================================================= */ +/* subWord2(string, start[, length]) + ... if no words, returns received string +*/ +::method "subWord2" -- allows negative start and length + use strict arg string, arg2, ... -- make sure we have at least two args + + parse arg string, arg2, arg3 + + argNr=arg() -- get maximum number of arguments + maxArgs=3 + + signal on syntax + if argNr>maxArgs then -- too many arguments ? + raise syntax 93.902 array ("at most" maxArgs) + + methName="subWord" -- base name for the message to send + newArr=.array~new -- create new array for the arguments + + nrWords=words(string) -- calc # of words + + if \datatype(arg2, "W") then + raise syntax 93.905 array('2 ("starting word position")', arg3) + + newArr[1]=arg2 -- save starting pos + if arg2<0 then + do + tmp=nrWords+arg2+1 -- calc starting position from right + if tmp<1 then -- if before first word, start at first word + tmp=1 + newArr[1]=tmp -- save new starting position + end + + if arg(3,"Exists") then -- if given, process length argument + do + if \datatype(arg3, "W") then + raise syntax 93.905 array('3 ("number of words")', arg3) + + if arg3<0 then -- determine new starting position and number of words to delete + do + oldStart=newArr[1] -- save old starting position + tmp=oldStart+arg3+1 + if tmp<1 then -- oops, make sure we start at first word + tmp=1 + + newArr[1]=tmp -- new start position + newArr[2]=oldStart-tmp+1 -- length argument (nr of words to delete) + end + else + do + newArr[2]=arg3 -- length argument + end + end + + if nrWords=0 then -- nothing to do, return empty/spacy string + return string + + -- now invoke the operation + return .message~new(string, methName, "A", newArr)~send + +syntax: + raise propagate + + + -- 2008-02-21, rgf: upper2(string [,[n-start] [, n-length]]) + /* if length is negative, then */ +/* ======================================================================= */ +::method "upper2" + use strict arg arg1, ... -- make sure we have at least one arg + parse arg ., arg2, arg3 + + argNr=arg() -- get maximum number of arguments + BIFpos=3... [truncated message content] |
From: <or...@us...> - 2014-11-04 17:38:07
|
Revision: 266 http://sourceforge.net/p/bsf4oorexx/code/266 Author: orexx Date: 2014-11-04 17:38:03 +0000 (Tue, 04 Nov 2014) Log Message: ----------- 20141104 Make the programs independent of 'rgf_util2.rex'. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dbusdoc.rex Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-11-02 12:18:04 UTC (rev 265) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-11-04 17:38:03 UTC (rev 266) @@ -264,8 +264,6 @@ ::requires "dbusoorexx" LIBRARY -- get access to the native routines and methods -::requires "rgf_util2.rex" -- utility package, e.g. installed with BSF4ooRexx - /** This routine requires dynamically the ooRexx package <code>BSF.CLS</code> and * in the case it is not available allows to continue gracefully. */ Modified: sandbox/rgf/misc/dbusoorexx/dbusdoc.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbusdoc.rex 2014-11-02 12:18:04 UTC (rev 265) +++ sandbox/rgf/misc/dbusoorexx/dbusdoc.rex 2014-11-04 17:38:03 UTC (rev 266) @@ -4,6 +4,7 @@ date: 2011-07-29/31, 2011-08-01/05, 2011-08-14 changed: 2014-08-07, rgf - make sure that connection gets closed, otherwise message loop thread lingers 2014-11-02, rgf - made debug output parametrized, added option to open generated html fiel + 2014-11-04, rgf - removed dependency on "rgf_util2.rex" version: 1.2 name: dbusdoc.rex purpose: documents given bus name in HTML form to allow the creation of API listings, @@ -27,6 +28,7 @@ ----------------------------------------------------------------------------- */ + .local~dbus.doc.debug = .false parse arg val -- get argument string @@ -177,7 +179,7 @@ newFileName=conn~busType"_"needle"_".DateTime~new~string~translate("_-",":.")".html" -say "creating HTML output, writing to" pp2(newFileName) "..." +say "creating HTML output, writing to" pp(newFileName) "..." call stream newFileName, "C", "open replace" call charout newFileName, m~string call stream newFileName, "C", "close" @@ -215,14 +217,14 @@ syntax: co=condition('o') - say ppCondition2(co) -- "pretty prints" the condition object's information + say ppCondition(co) -- "pretty prints" the condition object's information say conn~close raise propagate ::requires "dbus.cls" -- get support for DBus -::requires "rgf_util2.rex" -- utility package (e.g. from BSF4ooRexx) +-- ::requires "rgf_util2.rex" -- utility package (e.g. from BSF4ooRexx) ::class analyzedService @@ -251,7 +253,7 @@ if objectPathList~items=0, pos(":",busname)=0 then -- no object paths found and not a system bus name do testObjPath="/" || busname~changeStr('.','/') -- create object path from busname - say self":getObjectPathList: no object path(s) found, testing busname-derived object path" pp2(testObjPath) + say self":getObjectPathList: no object path(s) found, testing busname-derived object path" pp(testObjPath) self~getAllObjectPaths(testObjPath) end @@ -402,7 +404,7 @@ tab3=tab1~copies(3) -- m~~append('<h1>Overview of Analyzed Service/Bus Name(s)</h1>') ~~append(crlf) - m~~append('<h1>Overview of Analyzed Service/Bus Name(s) on the ')~~append(pp2(conn~busType))~~append('-Bus </h1>') ~~append(crlf) + m~~append('<h1>Overview of Analyzed Service/Bus Name(s) on the ')~~append(pp(conn~busType))~~append('-Bus </h1>') ~~append(crlf) m~~append('<ol class="jumplist">')~~append(crlf) @@ -450,7 +452,7 @@ exposeVars='crlf tab1 tab2 tab3 tab4 tab5 tab6 tab7 comparator complexSignatures exposeVars' -- list of variables to be exposed to procedures -- m~~append('<h1>Details of Analyzed Service/Bus Name(s)</h1>') ~~append(crlf) - m~~append('<h1>Details of Analyzed Service/Bus Name(s) on the ')~~append(pp2(conn~busType))~~append('-Bus </h1>') ~~append(crlf) + m~~append('<h1>Details of Analyzed Service/Bus Name(s) on the ')~~append(pp(conn~busType))~~append('-Bus </h1>') ~~append(crlf) m~~append('<ol class="servicename">')~~append(crlf) @@ -459,23 +461,23 @@ -- create the service name header m~~append(tab1) - m~~append('<li class="servicename">') ~~append("Bus Type: ") ~~append('<em class="bustype">')~~append(pp2(conn~busType)) ~~append("</em>") + m~~append('<li class="servicename">') ~~append("Bus Type: ") ~~append('<em class="bustype">')~~append(pp(conn~busType)) ~~append("</em>") m~~append(", Service (Bus) Name: ") if o~objectPathDefs~items = 0 then do - m~~append('<em class="servicename">')~~append(pp2(serviceName)) ~~append("</em>") + m~~append('<em class="servicename">')~~append(pp(serviceName)) ~~append("</em>") m~~append("<br/> (no interface definitions found)") end else do -- define anchor name m~~append('<a name="') ~~append(.hrefmgr~getId(serviceName,'serviceName')) ~~append('">') - m~~append('<em class="servicename">')~~append(pp2(serviceName)) + m~~append('<em class="servicename">')~~append(pp(serviceName)) m~~append('</a>') ~~append("</em><br/>") m~~append(crlf)~~append(crlf) -- create the object path headers -say tab1 "servicename:" pp2(servicename) +say tab1 "servicename:" pp(servicename) call createObjectPathDocs m, o say end @@ -509,7 +511,7 @@ -- list all object paths that share the identical (canonized) introspect data (they returned the same introspect data upon "Introspect()") do tmpPath over rel~allAt(introData)~sortWith(comparator) - m~~append(tab3)~~append('<li>') ~~append(pp2(tmpPath)) ~~append('</li>') ~~append(crlf) + m~~append(tab3)~~append('<li>') ~~append(pp(tmpPath)) ~~append('</li>') ~~append(crlf) allPaths~remove(tmpPath) -- remove object path from set end m~~append(tab2)~~append('</ul><br/>') ~~append(crlf) @@ -527,16 +529,16 @@ dt=.dbus.dir~dataTypes -- get datatype dir, "r" -> struct, "e" -> dict(entry) -say tab2 " node:" pp2(rootNode~name) +say tab2 " node:" pp(rootNode~name) do n over rootNode~content~sort -- sortWith(comparator) if n~isA(.IDBusNode) then do -if .dbus.doc.debug=.true then say tab4 "**debug node:" pp2(n~name) -- "content~items:" pp2(n~content~items) +if .dbus.doc.debug=.true then say tab4 "**debug node:" pp(n~name) -- "content~items:" pp(n~content~items) if n~contains("interfaces")=.false then -- a fragment node attached to introspect data? iterate - m~~append(tab2) ~~append("Node name: ")~~append('<em class="node">')~~append(pp2(n~name)) ~~append("</em><br/>") ~~append(crlf) + m~~append(tab2) ~~append("Node name: ")~~append('<em class="node">')~~append(pp(n~name)) ~~append("</em><br/>") ~~append(crlf) m~~append(tab2) ~~append('<ul class="node">') ~~append(crlf) end @@ -544,12 +546,12 @@ if i~isA(.IDBusInterface) then do m~~append(tab3) ~~append('<br/><li>') ~~append('Interface: ') ~~append('<em class="interface">') - m~~append(pp2(i~name))~~append('</em>') ~~append(crlf) + m~~append(pp(i~name))~~append('</em>') ~~append(crlf) m~~append(tab4) ~~append('<table class="interface">')~~append(crlf) bEven=.false -if .dbus.doc.debug=.true then say tab4 "*** debug interface:" pp2(i~name) +if .dbus.doc.debug=.true then say tab4 "*** debug interface:" pp(i~name) oldType="" nr=0 @@ -614,7 +616,7 @@ m~~append('</span>') ~~append(crlf) -- TD # 6 - kind m~~append(tab6) m~~append('<span class="arrow">') ~~append(' → ') ~~append("</span>") - m~~append('<span class="signature">') ~~append(pp2(t)) ~~append("</span>") + m~~append('<span class="signature">') ~~append(pp(t)) ~~append("</span>") m~~append('</td>') ~~append(crlf) -- TD # 7 - show untranslated argSignature end @@ -677,7 +679,7 @@ if meth~argSignature<>"" then do m~~append(tab6) ~~append('<span class="arrow">') ~~append(' → ') ~~append("</span>") - m~~append('<span class="signature">')~~append(pp2(meth~argSignature)) + m~~append('<span class="signature">')~~append(pp(meth~argSignature)) m~~append('</span>') -- ~~append(crlf) -- TD # 4 - name end m~~append(tab6)~~append('</td>') ~~append(crlf) -- TD # 7 - show untranslated argSignature @@ -722,15 +724,15 @@ else m~~append(tab1) ~~append('<tr class="odd">') ~~append(crlf) - m~~append(tab2) ~~append('<td class="argtype">') ~~append(pp2(char)) ~~append('</td>') ~~append(crlf) - m~~append(tab2) ~~append('<td class="datatype">') ~~append(" … ") ~~append(pp2(dt[char])) ~~append('</span></td>') ~~append(crlf) + m~~append(tab2) ~~append('<td class="argtype">') ~~append(pp(char)) ~~append('</td>') ~~append(crlf) + m~~append(tab2) ~~append('<td class="datatype">') ~~append(" … ") ~~append(pp(dt[char])) ~~append('</span></td>') ~~append(crlf) m~~append(tab2) ~~append('<td class="emptycell"> </td>') ~~append(crlf) datatype=sortedItems[i] char =dt~index(datatype) - m~~append(tab2) ~~append('<td class="datatype">') ~~append(pp2(datatype)) ~~append('</td>') ~~append(crlf) - m~~append(tab2) ~~append('<td class="argtype">') ~~append(" … ") ~~append(pp2(char)) ~~append('<td>') ~~append(crlf) + m~~append(tab2) ~~append('<td class="datatype">') ~~append(pp(datatype)) ~~append('</td>') ~~append(crlf) + m~~append(tab2) ~~append('<td class="argtype">') ~~append(" … ") ~~append(pp(char)) ~~append('<td>') ~~append(crlf) m~~append(tab1) ~~append('</tr>')~~append(crlf) bEven=\bEven -- toggle @@ -859,18 +861,172 @@ ::routine dumpStatistics -- dump connection's statistics use arg conn statistics=conn~statistics - say "conn~collectStatistics:" pp2(conn~collectStatistics) - call dump2 statistics, "statistics" + say "conn~collectStatistics:" pp(conn~collectStatistics) + call dump statistics, "statistics" do e over .array~of("lastSentError","lastSentMessage", "lastSentSignal", "lastReceivedError", "lastReceivedMessage", "lastReceivedSignal") d=statistics~entry(e) if d=.nil then iterate - say " " pp2(e)":" - call dump2 d, e"'s slotDir:" + say " " pp(e)":" + call dump d, e"'s slotDir:" end started=statistics~started now=.dateTime~new - say "started: " pp2(started) - say "now: " pp2(now) - say "duration:" pp2(now-started) + say "started: " pp(started) + say "now: " pp(now) + say "duration:" pp(now-started) + +/* from "rgf_util2.rex", using pp() instead of pp2(): + create and return a string rendering of the supplied condition object rgf, 2011-06-08 +*/ +::routine ppCondition + use strict arg co, bShowPackageInfo=.false, indent1="09"x, lf=.endOfLine + + indent2=indent1~copies(2) + indent3=indent1~copies(3) + + maxWidth=0 -- determine length of widest index + do idx over co + if idx~isA(.string) then maxWidth=max(maxWidth,idx~length) + end + maxWidth+=2 -- add square brackets + + mb=.MutableBuffer~new + + do idx over co~allindexes~sort + entry=co[idx] + mb~~append(indent1) ~~append(pp(idx)~left(maxWidth)) ~~append("=") ~~append(pp(entry)) ~~append(lf) + if entry~isA(.collection) then + do val over entry + mb ~~append(indent2) ~~append(pp(val)) ~~append(lf) + end + end + + return mb~string + + +/* ======================================================================= */ +/* copied from "rgf_util2.rex", removed non-available features, hence simplified version, ---rgf, 20141104 +*/ +::routine dump + use arg coll, title=("type: The" coll~class~id "class"), comparator=.nil + + if .nil=comparator, title~isA(.comparator) then + do + comparator=title + title=("type: The" coll~class~id "class") + end + + + if coll~isA(.supplier) then + do + s=coll + len=5 -- define an arbitrary high width + say title + end + else if \coll~isA(.Collection) then -- make sure we have a Collection else + do + if arg(2,"E") then -- title omitted ! + say title + + say "DUMP(): ---> argument to dump is *NOT* a *COLLECTION/SUPPLIER* ! <--- " + say " type:" pp(coll~class) + say " default string value:" pp(coll) + -- .ArgUtil~validateClass("collection", coll, .Collection) -- must be of type Collection + return + end + else -- a collection in hand + do + say title": ("coll~items "items)" + len=length(coll~items) + end + + say + count=0 + + + if coll~isA(.Collection) then + do + s=makeSortedSupplier(coll, comparator) + end + + -- determine maximum length of "pretty printed" index-value + maxWidth=0 + s2=s~copy + do while s2~available + maxWidth=max(maxWidth,length(s2~index)+2) + s2~next + end + + count=0 + do while s~available + count=count+1 + say " " "#" right(count,len)":" "index="pp(s~index)~left(maxWidth) "-> item="pp(s~item) + s~next + end + say "-"~copies(50) + return + + +/* Sort a collection considering its type and return a sorted supplier object. */ +makeSortedSupplier: procedure + use arg coll, comparator=.nil + + if coll~isA(.OrderedCollection) then -- don't sort, just return the supplier + return coll~supplier + + if coll~isA(.SetCollection) then -- use items part, sort it and return it as a supplier + do + arr=coll~allItems -- get array representation + call sortArray arr, comparator -- sort elements + return .supplier~new(arr, arr) -- return supplier with sorted elements + end + + if coll~hasMethod('allAt') then -- handle collections with idx -> coll + do + arr=.set~new~union(coll~allIndexes)~makeArray -- remove duplicate indexes, if any + call sortArray arr, comparator -- sort elements + + arr2=.array~new + + do i=1 to arr~items -- iterate over all indexes + tmp=coll~allAt(arr[i]) -- get all items associated with index + if tmp~items=1 then + arr2[i]=tmp~at(1) -- save single item to show + else + arr2[i]=coll~allAt(arr[i]) -- save collection of associated items + + end + + return .supplier~new(arr2, arr) + end + + -- o.k. only MapCollection/Collection left, assuming 1:1 mapping between index and item + arr=coll~allIndexes -- remove duplicate indexes, if any + call sortArray arr, comparator -- sort elements + + arr2=.array~new + do i=1 to arr~items -- iterate over all indexes + arr2[i]=coll[arr[i]] -- retrieve item part + end + return .supplier~new(arr2, arr) + + + -- just sort the passed in array, depending on whether a comparator is needed or not +sortArray: procedure + use arg arr, comparator=.nil + + if comparator<>.nil then + arr~sortWith(comparator) + else + do + comparator=.CaselessComparator~new + do i=1 to arr~items + arr[i]=arr[i]~string + end + arr~sortWith(.CaselessComparator~new) + end + + return + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2011-08-23 22:08:52
|
Revision: 40 http://bsf4oorexx.svn.sourceforge.net/bsf4oorexx/?rev=40&view=rev Author: orexx Date: 2011-08-23 22:08:44 +0000 (Tue, 23 Aug 2011) Log Message: ----------- 20110824 Added option to halt all threads, if a service raise unexpectedly a Rexx condition. Folded some query methods into a method 'query' to simplify the interface to DBus a little bit more (saving methods to memorize). Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-22 20:23:58 UTC (rev 39) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-23 22:08:44 UTC (rev 40) @@ -13,7 +13,7 @@ cf.: dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> (as of 2011-07-14) - version: 099.20110817 + version: 099.20110823 changes: - 2011-07-20, rgf; DBusProxyObject: - added proxy.dispatch(methodName[,args...])-method to send messages that @@ -61,6 +61,10 @@ - 2011-08-21, rgf - added method "supports" to "DBus": currently returns all supported typecodes or tests individual type codes (e.g. "h" cannot be sent on Windows and therefore is not supported there) + - 2011-08-23, rgf + - added attribute "haltAllThreadsOnUnexpectedError" to "DBus": if .true and an unexpected + Rexx condition is raised while servicing a request, then all Rexx threads will get halted + (intended to stop/abend program) license: Apache License 2.0 @@ -89,7 +93,7 @@ */ .local~dbus.dir=.directory~new -.dbus.dir~version="099.20110818" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' +.dbus.dir~version="099.20110823" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' .dbus.dir~DBUS_SERVICE_DBUS ="org.freedesktop.DBus" -- "The bus name used to talk to the bus itself." .dbus.dir~DBUS_PATH_DBUS ="/org/freedesktop/DBus" -- "The object path used to talk to the bus itself." @@ -331,12 +335,14 @@ ::attribute collectStatistics -- default: .true (keep slotDirs of last received messages/errors/signals and their respective counters) ::attribute statistics -- a directory +::attribute haltAllThreadsOnUnexpectedError -- if set to .true, then an unexpected Rexx condition will cause all Rexx threads to be halted ::method init expose cself busType makeSlotDir makeReplySlotDir active - internalRegisteredServiceObjects internalSignalListeners - unmarshalByteArrayAsString - - collectStatistics statistics server sendEmptyReply + collectStatistics statistics server sendEmptyReply - + haltAllThreadsOnUnexpectedError cself=.nil /* will be set by a native method */ busType=.nil /* will be set by native method */ @@ -352,6 +358,9 @@ sendEmptyReply =.true /* if .true, then sends an empty reply upon a message call */ + haltAllThreadsOnUnexpectedError=.false -- set to .true when all running threads should be halted, if the + -- there is an unexpected Rexx condition while servicing a request + collectStatistics =.true /* if .true, simple statistics are gathered and stored in 'statistics' */ statistics =.directory~new statistics~started=.dateTime~new -- remember this connection's creation time, define initial counter values @@ -437,11 +446,91 @@ -- say self ":" "! ---> NATIVE CLOSE CONNECTION GOT CARRIED OUT <--- !" "busType:" pp2(busType) "self:" pp2(self) "server:" pp2(server) end -::method nativeIsConnected private external "LIBRARY dbusoorexx DbusConnectionIsConnected" -::method isOpen -- returns .true if connected (open), .false else +/* Fold functions/methods that query the state or abilities of a connection. + "Authenticated" or "IsAuthenticated" are synonyms: returns .true, if the connection was authenticated, .false else + "O" or "C" or "IsO" or "IsC" are synonyms: return .true, if the connection is open, .false else + "Supported" or "TypeCode" are synonyms: if no second argument, returns all supported type codes; if + second argument given, returns .true, if all type codes are supported, .false if any one is not supported +*/ +::method query + parse upper arg option +1 1 option3 +3 . -- get first char and first three chars in uppercase + + optionPos=pos(option, "ACOST") + if optionPos=0 then -- option not identified just as of yet + do + option3Pos=wordPos(option3, "ISA ISC ISO") + if option3Pos>0 then + do + option="AOO"~subChar(option3Pos) -- set option + end + else + do + raise syntax 88.916 array ('"option"', '"a[uthenticated]" or "IsA[uthenticated]", "O[pen]" or "IsO[pen" or "C[onnected]" or "IsC[onnected]", "S[upports]" or "T[ypecode]"', arg(1)) + end + end + else + do + if option="T" then option="S" -- "Supports" functionality + if option="C" then option="O" -- test "Open" functionality + end + + if option="A" then return self~nativeIsAuthenticated + if option="O" then return self~nativeIsConnected + +say "option="pp2(option) "arg()="pp2(arg()) + if arg()<=1 then return self~supportsTypeCode + + use strict arg nix, char -- fetch arguments + return self~supportsTypeCode("T",char) -- test whether given type codes are supported + + +::method nativeIsConnected private external "LIBRARY dbusoorexx DbusConnectionIsConnected" +::method nativeIsAuthenticated private external "LIBRARY dbusoorexx DbusConnectionIsAuthenticated" +/* +::method isOpen -- returns .true if connected (open), .false else; synonym for "isConnected" return self~nativeIsConnected +::method isConnected -- returns .true if connected (open), .false else + return self~nativeIsConnected +::method isAuthenticated + return self~nativeIsAuthenticated +*/ + +-- keep these private so to not blow up the amount of methods one needs to be aware of +::method nativeCanSendType private external "LIBRARY dbusoorexx DbusConnectionCanSendType" +/* + supports() ... return "typeCodes={a,...,x}" ... returns string denoting available types + supports("T[ypecode]", typecode) ... returns .false/.true; typecode can be a string: only returns .true then, if all characters are supported type codes +*/ +::method supportsTypeCode private -- this name is neutral enough to allow extensions, if other connection-related tests are needed + if arg()=0 then + do + str="" + -- get all indexes, remove "", sort array + arr=.dbus.dir~dataTypes~allIndexes~~removeItem("")~sort + do char over arr + if self~nativeCanSendType(char) then -- supported + do + if str<>"" then str=str"," + str=str||char -- add supported type code + end + end + return "typeCode={"str"}" + end + + use strict arg kind="T", char -- fetch arguments + + if kind~strip~left(1)~upper<>"T" then + raise syntax 88.916 array ('"kind"', '"T[ypecode]"', action) + + do i=1 to char~length -- iterate over characters + if self~nativeCanSendType(char~subChar(i))=.false then return .false + end + return .true + + + ::method uninit expose busType cself @@ -875,38 +964,6 @@ -::method nativeCanSendType private external "LIBRARY dbusoorexx DbusConnectionCanSendType" -/* - supports() ... return "typeCodes={a,...,x}" ... returns string denoting available types - supports("T[ypecode]", typecode) ... returns .false/.true; typecode can be a string: only returns .true then, if all characters are supported type codes -*/ -::method supports -- this name is neutral enough to allow extensions, if other connection-related tests are needed - if arg()=0 then - do - str="" - -- get all indexes, remove "", sort array - arr=.dbus.dir~dataTypes~allIndexes~~removeItem("")~sort - do char over arr - if self~nativeCanSendType(char) then -- supported - do - if str<>"" then str=str"," - str=str||char -- add supported type code - end - end - return "typeCode={"str"}" - end - - use strict arg kind="T", char -- fetch arguments - - if kind~strip~left(1)~upper<>"T" then - raise syntax 88.916 array ('"kind"', '"T[ypecode]"', action) - - do i=1 to char~length -- iterate over characters - if self~nativeCanSendType(char~subChar(i))=.false then return .false - end - return .true - - /* ---------------------------------------------------------------------------------------- */ /* as of 2011-07-05 ooRexx from trunk does not support UTF-8, hence depending on BSF4ooRexx */ ::routine stringToUtf8 public -- needs BSF4ooRexx @@ -965,6 +1022,8 @@ /* ---------------------------------------------------------------------------------------- */ +/* allow for sending error-messages instead of a reply back to the invoker, will get honored in + the message loop of the DBus connection that invoked the Rexx method calling this routine */ ::routine raiseDBusError public -- this condition will be turned into an error-message in native code use arg errName="org.freedesktop.DBus.Error.RexxServiceRaised", errMessage=.nil signal on syntax Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2011-08-22 20:23:58 UTC (rev 39) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2011-08-23 22:08:44 UTC (rev 40) @@ -32,7 +32,7 @@ - make the message, server and timeout loop aware of Rexx conditions; if a condition is active, leave the loop setting the loop control variable to .false to reflect this fact in ooRexx code as well - version: 099.20110821 + version: 099.20110823 license: Apache License 2.0 ------------------------ Apache Version 2.0 license ------------------------- @@ -57,9 +57,11 @@ extern "C" { // make sure no C++ name mangling comes into the way #endif +/* #ifdef _MSC_VER #pragma comment(lib, "dbus-1.lib") // as per the hint of Pontus Carlsson in an e-mail from 2011-08-19 #endif +*/ #define DBUS_API_SUBJECT_TO_CHANGE #include <dbus/dbus.h> @@ -74,9 +76,25 @@ #endif +/* +#include "oorexxapi.h" // testing for cygwin-compilation, hence moved here because of re-definitions + +#include <sys/types.h> // rgf-temp +#include <unistd.h> // rgf-temp +#include <sys/select.h> // rgf-temp + #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> // rgf-temp +#include <sys/types.h> // rgf-temp +#include <stdint.h> // rgf-temp +*/ + + +#include <stdio.h> +#include <stdlib.h> + // rgf, 2011-06-11 #include "oorexxapi.h" @@ -96,11 +114,11 @@ #ifdef DBUSOOREXX_32 - #define DBUS_REXXVERSION "099.20110822 32-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110823 32-bit" // version: "MajorNumber"."YYYYMMDD" #elif defined (DBUSOOREXX_64) - #define DBUS_REXXVERSION "099.20110822 64-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110823 64-bit" // version: "MajorNumber"."YYYYMMDD" #else - #define DBUS_REXXVERSION "099.20110822 n/a-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110823 n/a-bit" // version: "MajorNumber"."YYYYMMDD" #endif #ifndef TID @@ -634,14 +652,11 @@ } - - // if open, returns true, false else; cf. <http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#ga611ae94556af36fe30bfb547366ca4e1> - // expects one char; if that is a supported type code returns .true, otherwise .false + // expects a single char; if that is a supported type code returns .true, otherwise .false RexxMethod2(RexxObjectPtr, DbusConnectionCanSendType, CSTRING, typeCode, CSELF, connPtr) { #if defined (DEBUG_METHODS) fprintf(stderr, "===> arrived in DbusConnectionCanSendType\n"); -DbusConnectionCanSendType fflush(stderr); #endif DBusConnection *conn=(DBusConnection *) connPtr; @@ -653,6 +668,20 @@ } + // if authenticated, returns true, false else +RexxMethod1(RexxObjectPtr, DbusConnectionIsAuthenticated, CSELF, connPtr) +{ +#if defined (DEBUG_METHODS) + fprintf(stderr, "===> arrived in DbusConnectionIsAuthenticated\n"); + fflush(stderr); +#endif + DBusConnection *conn=(DBusConnection *) connPtr; + if (conn!=NULL && connPtr!=context->Nil() && dbus_connection_get_is_authenticated(conn)) + { + return context->True(); + } + return context->False(); +} @@ -4570,6 +4599,7 @@ dbus_message_unref(returnMsg); } } + else // dispatch synchroneously { #ifdef DEBUG_MESSAGELOOP @@ -4688,7 +4718,17 @@ context->SetGuardOn(); context->SetObjectVariable("ACTIVE", rxFalse); // stop message loop thread context->SetGuardOff(); + + if (context->GetObjectVariable("HALTALLTHREADSONUNEXPECTEDERROR")==rxTrue) // halt all Rexx threads? (trying to force program to exit) + { + context->threadContext->instance->Halt(); // raise Halt condition in all threads of this Rexx interpreter instance + } } + else // clear Rexx condition and proceed as normal + { + context->ClearCondition(); + + } } else if (rxResult==NULLOBJECT) // || rxResult==rxNil) // no return value, do not reply @@ -6528,7 +6568,9 @@ REXX_METHOD( DbusConnectionIsConnected , DbusConnectionIsConnected ), // 2011-08-22 REXX_METHOD( DbusConnectionCanSendType , DbusConnectionCanSendType ), + REXX_METHOD( DbusConnectionIsAuthenticated , DbusConnectionIsAuthenticated ), + REXX_LAST_METHOD() }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2011-08-24 15:52:13
|
Revision: 41 http://bsf4oorexx.svn.sourceforge.net/bsf4oorexx/?rev=41&view=rev Author: orexx Date: 2011-08-24 15:52:05 +0000 (Wed, 24 Aug 2011) Log Message: ----------- 20110824 Saving intermediate (test) work, before the electricity is turned off for today. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/runtest.sh Added Paths: ----------- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClient.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServer.rex Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-23 22:08:44 UTC (rev 40) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-24 15:52:05 UTC (rev 41) @@ -449,13 +449,13 @@ /* Fold functions/methods that query the state or abilities of a connection. "Authenticated" or "IsAuthenticated" are synonyms: returns .true, if the connection was authenticated, .false else "O" or "C" or "IsO" or "IsC" are synonyms: return .true, if the connection is open, .false else - "Supported" or "TypeCode" are synonyms: if no second argument, returns all supported type codes; if - second argument given, returns .true, if all type codes are supported, .false if any one is not supported + "Supports" or "TypeCode" are synonyms: if no second argument, returns all supported type codes; if + second argument given, returns .true, if all type codes are supported, .false if any one is not supported */ ::method query parse upper arg option +1 1 option3 +3 . -- get first char and first three chars in uppercase - optionPos=pos(option, "ACOST") + optionPos=pos(option, "ACOT") if optionPos=0 then -- option not identified just as of yet do option3Pos=wordPos(option3, "ISA ISC ISO") @@ -465,23 +465,21 @@ end else do - raise syntax 88.916 array ('"option"', '"a[uthenticated]" or "IsA[uthenticated]", "O[pen]" or "IsO[pen" or "C[onnected]" or "IsC[onnected]", "S[upports]" or "T[ypecode]"', arg(1)) + raise syntax 88.916 array ('"option"', '"A[uthenticated]" or "IsA[uthenticated]", "O[pen]" or "IsO[pen]" or "C[onnected]" or "IsC[onnected]", "T[ypecode]"', arg(1)) end end else do - if option="T" then option="S" -- "Supports" functionality if option="C" then option="O" -- test "Open" functionality end if option="A" then return self~nativeIsAuthenticated if option="O" then return self~nativeIsConnected -say "option="pp2(option) "arg()="pp2(arg()) - if arg()<=1 then return self~supportsTypeCode + if arg()<=1 then return self~canSendTypeCode -- return list of all supported type codes use strict arg nix, char -- fetch arguments - return self~supportsTypeCode("T",char) -- test whether given type codes are supported + return self~canSendTypeCode(char) -- test whether given type codes are supported ::method nativeIsConnected private external "LIBRARY dbusoorexx DbusConnectionIsConnected" @@ -503,7 +501,7 @@ supports() ... return "typeCodes={a,...,x}" ... returns string denoting available types supports("T[ypecode]", typecode) ... returns .false/.true; typecode can be a string: only returns .true then, if all characters are supported type codes */ -::method supportsTypeCode private -- this name is neutral enough to allow extensions, if other connection-related tests are needed +::method canSendTypeCode private -- this name is neutral enough to allow extensions, if other connection-related tests are needed if arg()=0 then do str="" @@ -516,13 +514,16 @@ str=str||char -- add supported type code end end - return "typeCode={"str"}" + -- return "typeCode={"str"}" + return str end - use strict arg kind="T", char -- fetch arguments + use strict arg char -- fetch arguments +/* if kind~strip~left(1)~upper<>"T" then raise syntax 88.916 array ('"kind"', '"T[ypecode]"', action) +*/ do i=1 to char~length -- iterate over characters if self~nativeCanSendType(char~subChar(i))=.false then return .false @@ -1919,7 +1920,7 @@ guard off do conn over arr -- iterate over all client connections and probe them -- say "... ... testing" pp2(conn)": conn~isOpen:" pp2(conn~isOpen) "..." - if conn~isOpen=.false then + if conn~query("open")=.false then do -- say "... ... BINGO! " pp2(conn) "not connected/open anymore, DISCONNECTing connection !" self~disconnect(conn) Modified: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/runtest.sh =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/runtest.sh 2011-08-23 22:08:44 UTC (rev 40) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/runtest.sh 2011-08-24 15:52:05 UTC (rev 41) @@ -2,5 +2,5 @@ # run with a local version of libdbus DBUSLIB=$HOME/lib/libdbus-1.so # DBUSLIB=$HOME/lib/libdbus-1.so.3.5.7 -echo $0 running "LD_PRELOAD=$DBUSLIB rexx $1" -LD_PRELOAD=$DBUSLIB rexx $1 +echo $0 running "LD_PRELOAD=$DBUSLIB rexx $*" +LD_PRELOAD=$DBUSLIB rexx $* Added: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClient.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClient.rex (rev 0) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClient.rex 2011-08-24 15:52:05 UTC (rev 41) @@ -0,0 +1,1250 @@ +#!/usr/bin/rexx +/* + author: Rony G. Flatscher, (c) 2011 + name: testPrivateClientPing.rex + date: 2011-08-07, 2011-08-24 + license: 3.0, AL 2.0 + purpose: - test marshalling and unmarshalling; will unmarshal received arguments and + marshal them for the reply using the same signature + + - this sends any kind of arguments to the testRawPongServer.rex using + + - all DBus-methods directly (not taking advanatage of the class + DBusProxyObject + + usage: rexx testPrivateClientPing.rex + + needs: testPrivatePongServer.rex running and listening on the address this + clients attaches to + + hint: derived from testRawServerPong.rex, merely replaced "session" with the address + where the server is listening for clients + + + dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> (as of 2011-07-14) + + license: AL 2.0 + ------------------------ Apache Version 2.0 license ------------------------- + Copyright 2011 Rony G. Flatscher + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ----------------------------------------------------------------------------- +*/ + +say "DbusVersion():" dbusVersion() + +objectPath="/org/rexxla/oorexx/dbus/test/Pong" +busName ="org.rexxla.oorexx.dbus.test.pong" +interface ="" + +/* +busType="session" -- default to session bus +say "creating a connection to the" pp2(busType) "message bus..." +conn=.dbus~new(busType) -- get a connection +*/ + +address1="unix:path=/tmp/dbus-test" +address2="tcp:host=localhost,port=23000,family=ipv4;" -- socket lingers after shutdown +address3="tcp:host=localhost,port=23000,family=ipv4;unix:path=/tmp/dbus-test;" + +-- address1="unix:path=/tmp/dbus-test-oopsla" +-- address1="tcp:host=localhost,port=23001,family=ipv4;" -- socket lingers after shutdown +-- address=address1 + +parse arg otherAddress . +if otherAddress<>"" then + address=otherAddress +else + address=address3 + +say "creating a connection to the" pp2(busType) "message bus..." +say "creating a connection to" pp2(address) "message bus..." +conn=.dbus~new(address) -- get a connection + +say "conn~uniqueBusName ="pp2(conn~busName("unique")) +say "conn~uniqueBusId ="pp2(conn~uniqueBusId) +say "conn~busType ="pp2(conn~busType) + +signal on syntax + +say "now sending the first test message to the service object, saying 'halli,hallo'..." +res=conn~message("call", busName, objectPath, interface, "nixinoxi", "s", "s", "halli,hallo") +say 'res=conn~message("call", busName, objectPath, interface, "nixinoxi", "s", "s", "halli,hallo":' pp2(res) +call dump2 res, "roundtrip, 'res'-content" +say "<--*--> "~copies(7) + +-- +say "now sending a test signal named 'OhA' ..." +signalObjectPath="/this/was/rony" +signalInterface ="org.rexxla.dbus.test.interface" +conn~message("signal", signalObjectPath, signalInterface, "OhA", "s", "date traveling with signal OhA, hopefully!") +say 'conn~message("signal", senderObjectPath, interface, "OhA", "s", "date traveling with signal OhA, hopefully!")' +say "<---***>"~copies(7) + +call testSimpleTypes conn, busName, objectPath + +/* +*/ +call testSimpleArrayTypes conn, busName, objectPath +call test2dimensionalArrayTypes conn, busName, objectPath +call test3dimensionalArrayTypes conn, busName, objectPath + +call testByteArrays conn, busName, objectPath +call testMapType conn, busName, objectPath +call testStructTypes1 conn, busName, objectPath + +call testVariantTypes1 conn, busName, objectPath +say "/*\ "~copies(10) +call testVariantTypes2 conn, busName, objectPath + +/* +*/ + +say "--*-- "~copies(10) +say "activating makeReplySlotDir and reissuing message call:" +conn~makeReplySlotDir=.true +res=conn~message("call", busName, objectPath, interface, "nixinoxi", "s", "s", "hi") +say 'res=conn~message("call", busName, objectPath, interface, "nixinoxi", "s", "s", "hi":' pp2(res) +call dump2 res, "roundtrip, 'res'-content" +say +call dump2 res[res~last], "roundtrip, 'res["res~last"]'-content" +say + +say "DbusVersion():" dbusVersion() +call dumpConnectionStatistics conn +say "DbusVersion():" dbusVersion() +exit + +halt: -- stop the message loop thread + say " ... ctl-c was pressed ..." + call dumpConnectionStatistics conn + exit -1 + +syntax: + cond=condition('o') + say "exception occurred, showing dumpCondition2(condition('o'))..." + say ppCondition2(cond) + say + arr=cond~additional + call dump2 arr, "additional" + say + call dump2 arr[arr~last], "additional[last]" -- error slotDir + call dumpConnectionStatistics conn + exit -2 + + +::requires "dbus.cls" -- get DBus support for ooRexx +::requires "rgf_util2.rex" -- get access to the rgf2 utilities +::requires "testDumpStats.rex" + + + +::class testServiceObject +::method unknown -- this method will service all invocations + use arg methName, methArgs + + title=pp2(self)": methName="pp2(methName) "methArgs="pp2(methArgs) + say title + + call dump2 methArgs, title "methArgs" + + if methArgs~size>0 then + call dump2 methArgs[methArgs~items], title "slotDir" + + -- TODO: process arguments, create reply (return) value, by using the same arguments (without slotDir argument) with the same signature + + say "---/\--- "~copies(5) + say + + +::routine testSimpleTypes + use strict arg conn, busName, objectPath, interface="", methodName="someMethodName" +say center(" testSimpleTypes ", 50, "-") + + + say "conn="pp2(conn) "busName="pp2(busName) "objectPath="pp2(objectPath) + say "interface="pp2(interface) "methodName="pp2(methodName) + + + if conn~query("typecode", "h") then -- does the connection support UNIX_FD's ? + order=.array~of("s","g","o","y","b","n","q","i","h","u","x","t","d") + else + order=.array~of("s","g","o","y","b","n","q","i","u","x","t","d") + + typeName=.directory~new + typeName["s"]="STRING" + typeName["g"]="SIGNATURE" + typeName["o"]="OBJECTPATH" + typeName["y"]="BYTE" + typeName["b"]="BOOLEAN" + typeName["n"]="INT16" + typeName["q"]="UINT16" + typeName["i"]="INT32" + typeName["h"]="UNIX_FD" + typeName["u"]="UINT32" + typeName["x"]="INT64" + typeName["t"]="UINT64" + typeName["d"]="DOUBLE" + +numeric digits 20 + values=.directory~new + -- UTF-8: must not contain 8-Bit-characters or + values["s"]=.array~of("", "hi", "aha", , .nil, "anton", "ueber", "berta") + -- values["s"]=.array~of("", "hi", "aha", , .nil, "anton", string.to.utf8("\xFCber"), "berta") + values["g"]=.array~of("", "s", "g", "o", "oas", , .nil, "ay") + values["o"]=.array~of("/", "/Aha", "/org/Aha", , .nil, "/org/aha/soso/Aha") + + -- values["y"]=.array~of(" ", "a", "A", , .nil, "U") -- byte + values["y"]=.array~of(" ", "a", "A", , .nil, "\xDC") -- byte + + values["b"]=.array~of(.true, .false, , .nil, 0, 1) -- boolean + -- values["n"]=.array~of(0, -1, , .nil, 1) -- int16 + values["n"]=.array~of(0, -1, , .nil, 1, -32768, 32767) -- int16 + values["q"]=.array~of(0, , .nil, 1, 65535) -- uint16 + + values["i"]=.array~of(0, -1, , .nil, 1, -2147483648, 2147483647) -- int32 + values["h"]=.array~of(0, , .nil, 1) -- uint32: UNIX_FD: dbus does alter value + values["u"]=.array~of(0, , .nil, 1, 4294967295) -- uint32: tests o.k. + + values["x"]=.array~of(0, , .nil, 1, -9223372036854775808, 9223372036854775807) -- int64 + + values["t"]=.array~of(0, , .nil, 1, 18446744073709551615) -- uint64 + + values["d"]=.array~of(0, -1, , .nil, 1) -- double + + width=30 + yyy=4 -- 4=byte + do k=1 to order~size -- yyy -- order~size -- items -- type over order +-- do k=yyy to yyy -- order~size -- yyy -- order~size -- items -- type over order + type=order[k] + say center("" type"/"typeName[type] "", width, "-") + arr=values[type] -- get values to send + size=arr~size -- items + len=size~length + do i=1 to arr~size + val=arr[i] +-- say "***" i~right(len)"/"size~right(len)":" pp2(val) pp2(val~string~c2x) + res=conn~message("call", busName, objectPath, interface, methodName"_"type, type, type, val) + + say "===" i~right(len)"/"size~right(len)":" pp2(val) "<--?-->" "res="pp2(res) "|" pp2(val~string~c2x) "<--?-->" pp2(res~string~c2x) + end + say "-"~copies(width) + end + + say "-"~copies(79) + + +::routine testSimpleArrayTypes + use strict arg conn, busName, objectPath, interface="", methodName="someMethodName" + +say center(" testSimpleArrayTypes ", 50, "-") + + if conn~query("typecode", "h") then -- does the connection support UNIX_FD's ? + order=.array~of("s","g","o","y","b","n","q","i","h","u","x","t","d") + else + order=.array~of("s","g","o","y","b","n","q","i","u","x","t","d") + + typeName=.directory~new + typeName["s"]="STRING" + typeName["g"]="SIGNATURE" + typeName["o"]="OBJECTPATH" + typeName["y"]="BYTE" + typeName["b"]="BOOLEAN" + typeName["n"]="INT16" + typeName["q"]="UINT16" + typeName["i"]="INT32" + typeName["h"]="UNIX_FD" + typeName["u"]="UINT32" + typeName["x"]="INT64" + typeName["t"]="UINT64" + typeName["d"]="DOUBLE" + +numeric digits 20 + values=.directory~new + -- UTF-8: must not contain 8-Bit-characters or + -- values["s"]=.array~of("", "hi", "aha", , .nil, "anton", string.to.utf8("\xFCber"), "berta") + values["s"]=.array~of("hi", "aha", "", , .nil, "anton", "ueber", "berta") + values["g"]=.array~of("", "s", "g", "o", "oas", , .nil, "ay") + values["o"]=.array~of("/", "/Aha", "/org/Aha", , .nil, "/org/aha/soso/Aha") + + -- values["y"]=.array~of(" ", "a", "A", , .nil, "U") -- byte + -- values["y"]=.array~of(" ", "a", "A", , .nil, "\xDC") -- byte + -- values["y"]=.array~of(" ", "a", "A", , .nil, "U") -- byte + + values["y"]=.array~of(" ", , "a", "A", .nil, "U") -- byte + -- values["y"]=" aA U" -- byte + + values["b"]=.array~of(.true, .false, , .nil, 0, 1) -- boolean + -- values["n"]=.array~of(0, -1, , .nil, 1) -- int16 + values["n"]=.array~of(0, -1, , .nil, 1, -32768, 32767) -- int16 + values["q"]=.array~of(0, , .nil, 1, 65535) -- uint16 + + values["i"]=.array~of(0, -1, , .nil, 1, -2147483648, 2147483647) -- int32 + values["h"]=.array~of(0, , .nil, 1) -- uint32: UNIX_FD: dbus does alter value + values["u"]=.array~of(0, , .nil, 1, 4294967295) -- uint32: tests o.k. + + values["x"]=.array~of(0, , .nil, 1, -9223372036854775808, 9223372036854775807) -- int64 + + values["t"]=.array~of(0, , .nil, 1, 18446744073709551615) -- uint64 + + values["d"]=.array~of(0, -1, , .nil, 1) -- double + + conn~makeReplySlotDir=.true + + say "testing with empty single-dimensioned arrays ..." + width=30 + arr=.array~new + yyy=4 -- 4=byte + do k=1 to order~size -- yyy -- order~size -- items -- type over order + -- do k=yyy to yyy --- order~size -- yyy -- order~size -- items -- type over order + type=order[k] + say center("" type"/"typeName[type] "", width, "-") + -- arr=values[type] -- get values to send + + signature="a"type + if arr~isA(.array) then + oriValue= pp2(serializeArray(arr)) -- arr~makeString("L",",")) + else + oriValue= pp2(arr) + + say "---" oriValue "signature="pp2(signature) + + resRaw=conn~message("call", busName, objectPath, interface, methodName"_"signature, signature, signature, arr) + res=resRaw[1] -- result value + slotDir=resRaw[2] + call dump2 slotDir "reply's slotDir for" pp2(signature) + + + if \res~isA(.array) then + say "===" oriValue "<--?-->" "res="pp2(res) "(did not return an array!)" + else + say "===" oriValue "<--?-->" "res="pp2(serializeArray(res)) -- res~makeString("L",",")) + + say "~"~copies(10) + + end + + + say "---" +/* +say "hit enter to continue..." +parse pull key +*/ + + say "now testing with single-dimensioned arrays with values..." + conn~makeReplySlotDir=.true -- return an array with two elements: arr[1]=result, arr[2]=slotDir + + width=30 + yyy=4 -- 4=byte + do k=1 to order~size -- yyy -- order~size -- items -- type over order + -- do k=yyy to yyy --- order~size -- yyy -- order~size -- items -- type over order + type=order[k] + say center("" type"/"typeName[type] "", width, "-") + arr=values[type] -- get values to send + + signature="a"type + if arr~isA(.array) then + oriValue= pp2(serializeArray(arr)) -- arr~makeString("L",",")) + else + oriValue= pp2(arr) + + + say "---" oriValue "signature="pp2(signature) + + + resRaw=conn~message("call", busName, objectPath, interface, methodName"_"signature, signature, signature, arr) + res=resRaw[1] -- result value + slotDir=resRaw[2] + call dump2 slotDir "reply's slotDir for" pp2(signature) + + + if \res~isA(.array) then + say "===" oriValue "<--?-->" "res="pp2(res) "(did not return an array!)" + else + say "===" oriValue "<--?-->" "res="pp2(serializeArray(res)) -- res~makeString("L",",")) + + say "~"~copies(10) + + end + + say "-"~copies(79) + + +::routine test2dimensionalArrayTypes + use strict arg conn, busName, objectPath, interface="", methodName="someMethodName" + + + say center(" test2dimensionalArrayTypes ", 50, "-") + + if conn~query("typecode", "h") then -- does the connection support UNIX_FD's ? + order=.array~of("s","g","o","y","b","n","q","i","h","u","x","t","d") + else + order=.array~of("s","g","o","y","b","n","q","i","u","x","t","d") + + typeName=.directory~new + typeName["s"]="STRING" + typeName["g"]="SIGNATURE" + typeName["o"]="OBJECTPATH" + typeName["y"]="BYTE" + typeName["b"]="BOOLEAN" + typeName["n"]="INT16" + typeName["q"]="UINT16" + typeName["i"]="INT32" + typeName["h"]="UNIX_FD" + typeName["u"]="UINT32" + typeName["x"]="INT64" + typeName["t"]="UINT64" + typeName["d"]="DOUBLE" + +numeric digits 20 + values=.directory~new + -- UTF-8: must not contain 8-Bit-characters or + + arr1=.array~new + arr1[1,1]="/OneOne" -- attention: needs to be also a syntactical correct object path! + arr1[3,2]="/ThreeTwo" -- attention: needs to be also a syntactical correct object path! + values["s"]=arr1 -- string + + arr2=.array~new + arr2[1,1]="s" + arr2[3,2]="s" + values["g"]=arr2 -- signature + + values["o"]=arr1 -- objectpath + + arr3=.array~new -- byte + arr3[1,1]=1 + arr3[3,2]=1 + values["y"]=arr3 + + values["b"]=arr3 -- boolean + values["n"]=arr3 -- int16 + values["q"]=arr3 -- uint16 + + values["i"]=arr3 -- int32 + values["h"]=arr3 -- uint32: UNIX_FD: dbus does alter value + values["u"]=arr3 -- uint32: tests o.k. + + values["x"]=arr3 -- int64 + + values["t"]=arr3 -- uint64 + + values["d"]=arr3 -- double + + conn~makeReplySlotDir=.true -- return an array with two elements: arr[1]=result, arr[2]=slotDir + + width=30 + yyy=4 -- 4=byte + do k=1 to order~size -- yyy -- order~size -- items -- type over order + -- do k=yyy to yyy --- order~size -- yyy -- order~size -- items -- type over order + type=order[k] + say center("" type"/"typeName[type] "", width, "-") + arr=values[type] -- get values to send + + signature="aa"type + if arr~isA(.array) then + oriValue= pp2(arr~makeString("L",",")) "d="arr~dimension"/i="arr~items"/s="arr~size + else + oriValue= pp2(arr) + + say "---" oriValue "signature="pp2(signature) + + resRaw=conn~message("call", busName, objectPath, interface, methodName"_"signature, signature, signature, arr) + res=resRaw[1] -- result value + slotDir=resRaw[2] + call dump2 slotDir "reply's slotDir for" pp2(signature) + + + if \res~isA(.array) then + say "===" oriValue "<--?-->" "res="pp2(res) "(did not return an array!)" + else + do + say "===" oriValue "<--?-->" "res="pp2(res~makeString("L",",")) "d="arr~dimension"/i="arr~items"/s="arr~size + say "original array arr:" + call dump2dArray arr + say "res-array:" + call dump2dArray res + say "-- after dump2darray res." + end + + say "~"~copies(10) + end + say "-"~copies(79) + return + + +dump2dArray: procedure + use arg arr +say "---> debug dump2dArray(): arr~dimension="arr~dimension "arr~items="arr~items + + -- idx=.array~new(arr~dimension) + width=15 + do i=1 to arr~dimension(1) + do k=1 to arr~dimension(2) + .output~~charout(i","k": ")~~charout(arr[i,k]~string~left(width))~~charout( " | " ) + end + say + end + return + + + + +::routine test3dimensionalArrayTypes + use strict arg conn, busName, objectPath, interface="", methodName="someMethodName" + + say center(" test3dimensionalArrayTypes ", 50, "-") + + if conn~query("typecode", "h") then -- does the connection support UNIX_FD's ? + order=.array~of("s","g","o","y","b","n","q","i","h","u","x","t","d") + else + order=.array~of("s","g","o","y","b","n","q","i","u","x","t","d") + + typeName=.directory~new + typeName["s"]="STRING" + typeName["g"]="SIGNATURE" + typeName["o"]="OBJECTPATH" + typeName["y"]="BYTE" + typeName["b"]="BOOLEAN" + typeName["n"]="INT16" + typeName["q"]="UINT16" + typeName["i"]="INT32" + typeName["h"]="UNIX_FD" + typeName["u"]="UINT32" + typeName["x"]="INT64" + typeName["t"]="UINT64" + typeName["d"]="DOUBLE" + +numeric digits 20 + values=.directory~new + -- UTF-8: must not contain 8-Bit-characters or + + arr1=.array~new + arr1[1,1,1]="/OneOneOne" -- attention: needs to be also a syntactical correct object path! + arr1[2,2,2]="/TwoTwoTwoe" -- attention: needs to be also a syntactical correct object path! + arr1[3,2,3]="/ThreeTwoThree" -- attention: needs to be also a syntactical correct object path! + arr1[3,3,3]="/ThreeThreeThree" -- attention: needs to be also a syntactical correct object path! + values["s"]=arr1 -- string + + arr2=.array~new + arr2[1,1,1]="s" + arr2[2,2,2]="s" + arr2[3,2,3]="s" + arr2[3,3,3]="s" + values["g"]=arr2 -- signature + + values["o"]=arr1 -- objectpath + + arr3=.array~new -- byte + arr3[1,1,1]=1 + arr3[2,2,2]=1 + arr3[3,2,3]=1 + arr3[3,3,3]=1 + values["y"]=arr3 + + values["b"]=arr3 -- boolean + values["n"]=arr3 -- int16 + values["q"]=arr3 -- uint16 + + values["i"]=arr3 -- int32 + values["h"]=arr3 -- uint32: UNIX_FD: dbus does alter value + values["u"]=arr3 -- uint32: tests o.k. + + values["x"]=arr3 -- int64 + + values["t"]=arr3 -- uint64 + + values["d"]=arr3 -- double + + conn~makeReplySlotDir=.true -- return an array with two elements: arr[1]=result, arr[2]=slotDir + + + width=30 + yyy=4 -- 4=byte + do k=1 to order~size -- yyy -- order~size -- items -- type over order + -- do k=yyy to yyy --- order~size -- yyy -- order~size -- items -- type over order + type=order[k] + say center("" type"/"typeName[type] "", width, "-") + arr=values[type] -- get values to send + + signature="aaa"type + if arr~isA(.array) then + oriValue= pp2(arr~makeString("L",",")) "d="arr~dimension"/i="arr~items"/s="arr~size + else + oriValue= pp2(arr) + + say "---" oriValue "signature="pp2(signature) + + resRaw=conn~message("call", busName, objectPath, interface, methodName"_"signature, signature, signature, arr) + res=resRaw[1] -- result value + slotDir=resRaw[2] + call dump2 slotDir "reply's slotDir for" pp2(signature) "res:" pp2(res) + + + if \res~isA(.array) then + say "===" oriValue "<--?-->" "res="pp2(res) "(did not return an array!)" + else + do + say "===" oriValue "<--?-->" "res="pp2(res~makeString("L",",")) "d="arr~dimension"/i="arr~items"/s="arr~size + say "original:" + say + call dump3dArray arr + say + say "returned:" + say + call dump3dArray res + end + + say "~"~copies(10) + end + say "-"~copies(79) + return + + +dump3dArray: procedure + use arg arr + +say "---> debug dump3dArray(): arr~dimension="arr~dimension "arr~items="arr~items + -- idx=.array~new(arr~dimension) + width=15 + do i=1 to arr~dimension(1) + do k=1 to arr~dimension(2) + do m=1 to arr~dimension(3) + .output~~charout(i","k","m": ")~~charout(arr[i,k,m]~string~left(width))~~charout( " | " ) + end + say + end + say + end + return + +/* +dump3dArray: procedure + use arg arr + + supp=arr~supplier + do while supp~available + say supp~index~makestring("L",",")":" supp~item + supp~next + end + return +*/ + + +::routine testMapType -- i.e. .directory + + use strict arg conn, busName, objectPath, interface="", methodName="someMethodName" +say center(" testMapTypes ", 50, "-") + + + say "conn="pp2(conn) "busName="pp2(busName) "objectPath="pp2(objectPath) + say "interface="pp2(interface) "methodName="pp2(methodName) +/* +say center('conn~query("typecode", "h")='pp2(conn~query("typecode", "h")), 100, '*') +say "supported typecodes:" pp2(conn~query("typecode")) +say "hit enter" +parse pull x +*/ + + if conn~query("typecode", "h") then -- does the connection support UNIX_FD's ? + order=.array~of("s","g","o","y","b","n","q","i","h","u","x","t","d") + else + order=.array~of("s","g","o","y","b","n","q","i","u","x","t","d") + + typeName=.directory~new + typeName["s"]="STRING" + typeName["g"]="SIGNATURE" + typeName["o"]="OBJECTPATH" + typeName["y"]="BYTE" + typeName["b"]="BOOLEAN" + typeName["n"]="INT16" + typeName["q"]="UINT16" + typeName["i"]="INT32" + typeName["h"]="UNIX_FD" + typeName["u"]="UINT32" + typeName["x"]="INT64" + typeName["t"]="UINT64" + typeName["d"]="DOUBLE" + +numeric digits 20 + values=.directory~new + -- UTF-8: must not contain 8-Bit-characters or + values["s"]=.array~of("", "hi", "aha", "anton", "ueber", "berta") + values["g"]=.array~of("s", "g", "o", "oas", "ay") + values["o"]=.array~of("/", "/Aha", "/org/Aha", "/org/aha/soso/Aha") + + values["y"]=.array~of(" ", "a", "A", "\xDC") -- byte + + values["b"]=.array~of(.true, .false, 0, 1) -- boolean + values["n"]=.array~of(0, -1, , .nil, 1, -32768, 32767) -- int16 + values["q"]=.array~of(0, 1, 65535) -- uint16 + + values["i"]=.array~of(0, -1, , .nil, 1, -2147483648, 2147483647) -- int32 + values["h"]=.array~of(0, 1) -- uint32: UNIX_FD: dbus does alter value + values["u"]=.array~of(0, 1, 4294967295) -- uint32: tests o.k. + + values["x"]=.array~of(0, 1, -9223372036854775808, 9223372036854775807) -- int64 + + values["t"]=.array~of(0, 1, 18446744073709551615) -- uint64 + + values["d"]=.array~of(0, -1, 1) -- double + + indices=.array~of("idx1", "idx2", "idx3", "idx4", "idx5", "idx6", "idx7", "idx8") + + conn~makeReplySlotDir=.true -- return an array with two elements: arr[1]=result, arr[2]=slotDir + + width=30 + yyy=2 + do k=1 to order~size -- yyy -- order~size -- items -- type over order +-- do k=yyy to yyy -- order~size -- items -- type over order + + type="a{s"order[k]"}" -- map type + + typeByOrder=order[k] + + say center("" type"/"typeName[typeByOrder] "", width, "-") + + arr=values[typeByOrder] -- get values to send + val=.directory~new + + size=arr~size -- items + len=size~length + do i=1 to arr~size + val[indices[i]]=arr[i] -- assign entries + end + + say "arr~items:" arr~items "== dir~items:" val~items "?" + +-- call dump2 val, "original map" + +-- say "***" i~right(len)"/"size~right(len)":" pp2(val) pp2(val~string~c2x) + tmpMethName=methodName"_dict_s"typeByOrder + -- res=conn~message("call", busName, objectPath, interface, '"'methodName"_"type'"', type, type, val) + res=conn~message("call", busName, objectPath, interface, tmpMethName, type, type, val) + + call dump2 val, "original map" + call dump2 res[1], "resulting map" + -- say "===" i~right(len)"/"size~right(len)":" pp2(val) "<--?-->" "res="pp2(res) "|" pp2(val~string~c2x) "<--?-->" pp2(res~string~c2x) + + say "-"~copies(width) + end + + say "-"~copies(79) + return + + + +::routine testStructTypes1 -- i.e. .directory + + use strict arg conn, busName, objectPath, interface="", methodName="someMethodName" +say center(" testStructTypes1 ", 50, "-") + + + say "conn="pp2(conn) "busName="pp2(busName) "objectPath="pp2(objectPath) + say "interface="pp2(interface) "methodName="pp2(methodName) + + signatures1=.array~of( "(s)", - -- #1 - 1 argument (an array) + "(ss)") -- #2 - 1 argument (an array) + + signatures3=.array~of( "s(s)s", - -- #3 - 3 arguments (string, array, string) + "s(ss)s", - -- #4 - 3 arguments (string, array, string) + "s(s(s)s)s", - -- #5 - 3 arguments (string, array, string) + "s(ss(ss)ss)s") -- #6 - 3 arguments (string, array, string) + + values1=.array~of( .array~of("hi"), - -- #1 + .array~of("abc","def")) -- #2 + + -- make sure only three elements in first array ! + values3=.array~of( .array~of("abc", .array~of("mno"), "def"), - -- #3 + .array~of("abc", .array~of("mno", "pqr"), "def"), - -- #4 + .array~of("abc", .array~of("mno", .array~of("uvw"), "pqr"), "def"), - -- #5 + .array~of("abc", .array~of("mno", "123", .array~of("uvw", "xyz"), "pqr", "456"), "def") - -- #6 + ) + + conn~makeReplySlotDir=.true -- return an array with two elements: arr[1]=result, arr[2]=slotDir + + width=30 + yyy=99 + -- do k=yyy to signatures1~size -- yyy -- order~size -- items -- type over order + do k=1 to signatures1~size -- yyy -- order~size -- items -- type over order + -- do k=yyy to yyy -- yyy -- order~size -- items -- type over order + + type=signatures1[k] + val =values1[k] + + say center("" type "", width, "-") + + tmpMethName=methodName"_"k + + res=conn~message("call", busName, objectPath, interface, tmpMethName, type, type, val) + + call dump2 val, "original struct" + call dump2 res[1], "resulting struct" + + say "-"~copies(width) + end + +say center(" testStructTypes1 with three args ", 50, "-") + do k=1 to signatures3~size -- yyy -- order~size -- items -- type over order + -- yyy=4 + -- do k=yyy to yyy -- yyy -- order~size -- items -- type over order + + type=signatures3[k] + val =values3[k] + + say center("" type "", width, "-") + + tmpMethName=methodName"_"k + + res=conn~message("call", busName, objectPath, interface, tmpMethName, type, type, val[1], val[2], val[3]) + + call dump2 val, "original struct" + call dump2 res[1], "resulting struct" + + say "-"~copies(width) + end + + + say "-"~copies(79) + + + return + + + +::routine testVariantTypes1 -- i.e. .directory + + use strict arg conn, busName, objectPath, interface="", methodName="someMethodName" +say center(" testVariantTypes1 ", 50, "-") + + + say "conn="pp2(conn) "busName="pp2(busName) "objectPath="pp2(objectPath) + say "interface="pp2(interface) "methodName="pp2(methodName) + + signatures1=.array~of( "v") -- #1 - 1 argument (an array) + values1=.array~of( "hi") -- #1 + + + signatures2=.array~of( "vv", - -- # 1 - 2 argument (an array) + "vv", - -- # 2 - 2 argument (an array) + "vv") -- # 3 - 2 argument (an array) + + arr3=.array~new + arr3[1,1,1]="/OneOneOne" -- attention: needs to be also a syntactical correct object path! + arr3[2,2,2]="/TwoTwoTwoe" -- attention: needs to be also a syntactical correct object path! + arr3[3,2,3]="/ThreeTwoThree" -- attention: needs to be also a syntactical correct object path! + arr3[3,3,3]="/ThreeThreeThree" -- attention: needs to be also a syntactical correct object path! + + values2=.array~of( .array~of("abc","def"), - -- #1 + .array~of("abc", .array~of("def", "ghi")), - -- #2 + .array~of(.array~of("def", "ghi"), arr3)) -- #3 + + + width=30 + +-- + type="v" + val ="hi" + + say center("" type "", width, "-") + + tmpMethName=methodName"_"type + + res=conn~message("call", busName, objectPath, interface, tmpMethName, type, type, val) + + call dump2 val, "original variant" + call dump2 res, "resulting variant" + + say "-"~copies(width) + say + +--- + conn~makeReplySlotDir=.false -- return an array with two elements: arr[1]=result, arr[2]=slotDir +say center(" testVariantTypes1 with two args ", 50, "-") + do k=1 to signatures2~size -- yyy -- order~size -- items -- type over order + -- yyy=4 + -- do k=yyy to yyy -- yyy -- order~size -- items -- type over order + + type=signatures2[k] + val =values2[k] +-- call dump2 val, "original variant" + + say center("" type "", width, "-") + + tmpMethName=methodName"_"k + + res=conn~message("call", busName, objectPath, interface, tmpMethName, type, type, val[1], val[2]) + + call dump2 val, "original variant" + call dump2 res, "resulting variant" + + say "-"~copies(width) + end + say + +-- + type="v" + val=.directory~new + val["eins"]="One" + val~zwei="Two" + + say center("" type "", width, "-") + + tmpMethName=methodName"_"type + + res=conn~message("call", busName, objectPath, interface, tmpMethName, type, type, val) + + call dump2 val, "original variant" + call dump2 res, "resulting variant" + + say "-"~copies(width) + + + + say "-"~copies(79) + + + return + + + +::routine testVariantTypes2 -- i.e. .directory, 2011-07-29: test new variantSignatures ! + + use strict arg conn, busName, objectPath, interface="", methodName="someMethodName" +say center(" testVariantTypes2 ('useThisSignature=') / dbus.box(...) ", 79, "-") + + + say "conn="pp2(conn) "busName="pp2(busName) "objectPath="pp2(objectPath) + say "interface="pp2(interface) "methodName="pp2(methodName) + + signatures1=.array~of( "v") -- #1 - 1 argument (an array) + values1=.array~of( "hi") -- #1 + + + signatures2=.array~of( "vv", - -- # 1 - 2 argument (an array) + "vv", - -- # 2 - 2 argument (an array) + "vv") -- # 3 - 2 argument (an array) + + arr3=.array~new + arr3[1,1,1]="/OneOneOne" -- attention: needs to be also a syntactical correct object path! + arr3[2,2,2]="/TwoTwoTwoe" -- attention: needs to be also a syntactical correct object path! + arr3[3,2,3]="/ThreeTwoThree" -- attention: needs to be also a syntactical correct object path! + arr3[3,3,3]="/ThreeThreeThree" -- attention: needs to be also a syntactical correct object path! + + values2=.array~of( .array~of("abc","def"), - -- #1 + .array~of("abc", .array~of("/def", "/ghi")), - -- #2 + .array~of(.array~of("def", "ghi"), arr3)) -- #3 + +/* + values2_new= .array~of( - + .array~of( .array~of("useThisSignature=s", "abc"), - -- #1 + .array~of("useThisSignature=o", "/def")), - + .array~of( - -- #2 + .array~of("useThisSignature=s", "abc"), - + .array~of("useThisSignature=ao", .array~of("/def", "/ghi"))), - + .array~of( - -- #3 + .array~of("useThisSignature=as", .array~of("def", "ghi")), - + .array~of("useThisSignature=aaas", arr3)) - + ) +*/ + values2_new= .array~of( - + .array~of( dbus.box("s", "abc"), - -- #1 + dbus.box("o", "/def")), - + .array~of( - -- #2 + dbus.box("s", "abc"), - + dbus.box("ao", .array~of("/def", "/ghi"))), - + .array~of( - -- #3 + dbus.box("as", .array~of("def", "ghi")), - + dbus.box("aaas", arr3)) - + ) + + -- alternatively (easier, more ledgible): + values2_new= .array~of( - + .array~of( dbus.box("s", "abc"), dbus.box("o", "/def")), - -- #1 + .array~of( dbus.box("s", "abc"), dbus.box("ao", .array~of("/def", "/ghi"))), - -- #2 + .array~of( dbus.box("as",.array~of("def", "ghi")), dbus.box("aaas", arr3)) - -- #3 - + ) + + width=30 + +-- + type="v" + val ="hi" + + say center("" type "", width, "-") + + tmpMethName=methodName"_"type + + -- val_new=.array~of("useThisSignature=s",val) + val_new=dbus.box("s",val) + res=conn~message("call", busName, objectPath, interface, tmpMethName, type, type, val_new) + + call dump2 val, "original variant" + call dump2 res, "resulting variant" + say "---" + + say "-"~copies(width) + say + + +--- + conn~makeReplySlotDir=.false -- return an array with two elements: arr[1]=result, arr[2]=slotDir +say center(" testVariantTypes2 with two args ", 50, "-") + do k=1 to signatures2~size -- yyy -- order~size -- items -- type over order + -- yyy=4 + -- do k=yyy to yyy -- yyy -- order~size -- items -- type over order + + type=signatures2[k] + val =values2[k] +-- call dump2 val, "original variant" + + say center("" type "", width, "-") + + tmpMethName=methodName"_"k + + res=conn~message("call", busName, objectPath, interface, tmpMethName, type, type, val[1], val[2]) + + call dump2 val, "original variant ('val')" + call dump2 res, "resulting variant" + + say "---" -- now the same with explicit variantSignatures + val_new=values2_new[k] + res=conn~message("call", busName, objectPath, interface, tmpMethName, type, type, val_new[1], val_new[2]) + call dump2 val_new, "original variant ('val_new')" + call dump2 res, "resulting variant" + + say "-"~copies(width) + end + say + +-- + type="v" + val=.directory~new + val["eins"]="One" + val~zwei="/Two" + + say center("" type "", width, "-") + + tmpMethName=methodName"_"type + + res=conn~message("call", busName, objectPath, interface, tmpMethName, type, type, val) + + call dump2 val, "original variant" + call dump2 res, "resulting variant" + + say "-"~copies(width) + + say "---" -- now the same with explicit variantSignatures + + tmpDir=.directory~new + -- tmpDir["eins"]=.array~of("variantSignature=s", "One") + tmpDir["eins"]="One" + -- tmpDir~zwei =.array~of("useThisSignature=o", "/Two") -- define variant signature explicitly + tmpDir~zwei =dbus.box("o", "/Two") -- define variant signature explicitly + + -- new_val=.array~of("useThisSignature=a{sv}", tmpDir) -- create argument with explicit variant signature + new_val=dbus.box("a{sv}", tmpDir) -- create argument with explicit variant signature + res=conn~message("call", busName, objectPath, interface, tmpMethName, type, type, new_val) + + call dump2 val, "original variant ('val_new')" + call dump2 res, "resulting variant" + + + say "-"~copies(79) + + + return + + + +::routine testByteArrays -- i.e. .directory + + use strict arg conn, busName, objectPath, interface="", methodName="someMethodName" +say center(" testByteArrays ", 50, "-") + + conn~makeReplySlotDir=.false -- just return the result value + + width=60 + +/* +*/ + -- first "ay" + arr1=.array~of("H", "e", "l", "l", "o", " ", "W", "o", "r", "l", "d", "!", "tsk") + val1="Hello, World!" + + type="ay" + -- tmpMethName=methodName"_"type +/* +*/ + say center("" type "(return as string) ", width, "-") "hence returned type:" pp2("s") + -- supplying an array of bytes + conn~unmarshalByteArrayAsString=.true -- return as string + res=conn~message("call", busName, objectPath, interface, tmpMethName"_"type, type, type, arr1) + say "ori:" pp2(arr1~makeString('C')) "<--> res:" pp2(res) + say "="~copies(width) + say + + say center("" type "(return as array) ", width, "-") + conn~unmarshalByteArrayAsString=.false -- return as an array of bytes! + res=conn~message("call", busName, objectPath, interface, tmpMethName"_"type, type, type, arr1) + call dump2 arr1, "original arr1-array" + say + call dump2 res, "res-array (requested as array)" + say "="~copies(width) + say + + -- supplying a string to be transported as byte array + say center("" type "(return as string) ", width, "-") "hence returned type:" pp2("s") + conn~unmarshalByteArrayAsString=.true -- return as string + res=conn~message("call", busName, objectPath, interface, tmpMethName"_"type, type, type, val1) + say "ori:" pp2(val1) "<--> res:" pp2(res) + say "="~copies(width) + say + + say center("" type "(return as array) ", width, "-") + conn~unmarshalByteArrayAsString=.false -- return as an array of bytes! + res=conn~message("call", busName, objectPath, interface, tmpMethName"_"type, type, type, val1) + call dump2 val1, "original val1-string" + say + call dump2 res, "res-array (requested as array)" + say + say "="~copies(width) + say + + + -- 'aay' + type='aaay' + + arr1=.array~of("a", "b", "c") + arr3=.array~new + call fill3dArray arr3, arr1 -- create and fill a 3-d-array object + + say center("" type "(return as string) ", width, "-") "hence returned type:" pp2("aas") + conn~unmarshalByteArrayAsString=.true -- return as string + res=conn~message("call", busName, objectPath, interface, tmpMethName"_"type, type, type, arr3) + say "arr3-ori:" + call dump3dArray arr3 + say + say "res:" + if res~dimension=2 then + do + call dump2dArray res +say "---> rgf-debug:" +s=res~supplier +do while s~available + say " " pp2(s~index~makeString('L',','))": "pp2(s~item) + s~next +end + + end + else + call dump3dArray res + say "="~copies(width) + say +/* +*/ + + + say center("" type "(return as array) ", width, "-") + conn~unmarshalByteArrayAsString=.false -- return as array + res=conn~message("call", busName, objectPath, interface, tmpMethName"_"type, type, type, arr3) + say "arr3-ori:" + call dump3dArray arr3 + say + say "res:" + if res~dimension=2 then + call dump2dArray res + else + call dump3dArray res + say "="~copies(width) + say +/* +*/ + + + say "="~copies(79) + return + +fill3dArray: procedure + use arg arr, - -- 3-dimensional array object + arrArg -- single dimensioned array + + do idx over .list~of(.array~of(1,1), .array~of(2,2)) + x=idx[1] + y=idx[2] + do z=1 to arrArg~size + arr[x,y,z]=arrArg[z] + end + end + return + + + + + +dump2dArray: procedure + use arg arr +say "---> debug dump2dArray(): arr~dimension="arr~dimension "arr~items="arr~items + + -- idx=.array~new(arr~dimension) + width=20 + do i=1 to arr~dimension(1) + do k=1 to arr~dimension(2) + .output~~charout(i","k": ")~~charout(arr[i,k]~string~left(width))~~charout( " | " ) + end + say + end + return + + +dump3dArray: procedure + use arg arr + +say "---> debug dump3dArray(): arr~dimension="arr~dimension "arr~items="arr~items + -- idx=.array~new(arr~dimension) + width=20 + do i=1 to arr~dimension(1) + do k=1 to arr~dimension(2) + do m=1 to arr~dimension(3) + .output~~charout(i","k","m": ")~~charout(arr[i,k,m]~string~left(width))~~charout( " | " ) + end + say + end + say + end + return + + + +::routine serializeArray + use arg arr + + if arr~dimension>1 then return arr~makeString('L',',') "<hint: does not show empty slots>!" + + tmpStr="" + deli="," + bFirst=.true + do k=1 to arr~size + if arr~hasIndex(k) then val=arr[k] + else val="" + if bFirst=.true then + do + tmpStr=val + bFirst=.false + end + else + tmpStr=tmpStr || deli || val + end + + return tmpStr + Property changes on: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClient.rex ___________________________________________________________________ Added: svn:executable + * Added: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServer.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServer.rex (rev 0) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServer.rex 2011-08-24 15:52:05 UTC (rev 41) @@ -0,0 +1,248 @@ +#!/usr/bin/rexx +/* + author: Rony G. Flatscher, (c) 2011 + name: testPrivateServerPong.rex + date: 2011-08-07, 2011-08-24 + purpose: + - test private DBus connection + - test marshalling and unmarshalling; will unmarshal received arguments and + marshal them for the reply using the same signature + - if invoked will create a private DBUS server and register a service object + and listener object, and wait for call messages to reply + - this receives (unmarshals) arguments from testPrivatePingClient.rex and + returns (marshalled) them exactly as received + - all DBus-methods directly (not taking advanatage of the class + DBusServiceObject + + usage: testPrivateServerPong.rex + + hint: derived almost 1:1 from testRawServerPong.rex, only the initialization (main) + part of the program got changed + + dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> (as of 2011-07-14) + + license: AL 2.0 + ------------------------ Apache Version 2.0 license ------------------------- + Copyright 2011 Rony G. Flatscher + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ----------------------------------------------------------------------------- +*/ + +say "DbusVersion() ="pp2(DbusVersion()) + +address1="unix:path=/tmp/dbus-test" +address2="tcp:host=localhost,port=23000,family=ipv4;" -- socket lingers after shutdown +address3="tcp:host=localhost,port=23000,family=ipv4;unix:path=/tmp/dbus-test;" + +parse arg otherAddress . +if otherAddress<>"" then + address=otherAddress +else + address=address3 + +say "commandline: arg(1)="pp2(arg(1)) + +defaultService =.testServiceObject~new +defaultListener=.testSignalObject~new +say "starting up server, listening for connections on:" pp2(address) +server =.DBUSServer~new(address,defaultService,defaultListener) +server~allowAnonymous=.true +server~startup +say "server~active (after startup):" pp2(server~active) "cself="pp2(server~cself) +say "server~serverId: " pp2(server~serverId) +say "server~address: " pp2(server~address) +say "server~serverAddress: " pp2(server~serverAddress) + + +signal on syntax +signal on halt + +say "DbusVersion()="pp2(DbusVersion()) +say "Private server listens at address:" pp2(server~address) +say "Hit enter to end program ..." +parse pull x + +say "showing statistics on each served connection:" +do conn over server~connections + call dumpConnectionStatistics conn +end + +say "about to do a server~shutdown..." +server~shutdown +say "server~active (after shutdown): " pp2(server~active) -- "server2:" pp2(server2~active) +say "DbusVersion() ="pp2(DbusVersion()) + +exit + +halt: -- stop the message loop thread + say " ... ctl-c was pressed ..." + say "showing statistics on each served connection, if any active:" + do conn over server~connections + call dumpConnectionStatistics conn + end + say "about to do a server~shutdown..." + if server~active=.true then + server~shutdown + say "server~active (after shutdown): " pp2(server~active) + + say "DbusVersion() ="pp2(DbusVersion()) + exit -1 + + + +syntax: -- stop the message loop thread ! + say "... server, arrived in syntax-condition ..." + co=condition('o') + say "about to do a server~shutdown..." + if server~active=.true then + server~shutdown + say "server~active (after shutdown): " pp2(server~active) + + say ":-( "~copies(10) + say "a SYNTAX error has occurred, stopping the message loop ..." + say "the Rexx condition object contains the following information:" + say ppCondition2(co) + say ":-( "~copies(10) + + say "DbusVersion() ="pp2(DbusVersion()) + exit -2 + + + +::requires "dbus.cls" -- get DBus support for ooRexx +::requires "rgf_util2.rex" -- get access to the rgf2 utilities +::requires "testDumpStats.rex" + + + +::class testServiceObject +::method init class + expose counter + counter=0 +::attribute counter class +::method increaseCounter class + expose counter + counter +=1 + return counter + +::method unknown -- this method will service all invocations + use arg methName, methArgs + +-- signal on syntax + + slotDir=methArgs[methArgs~last] + +-- say center(" PONG::unknown, methName:" pp2(methName) "args:" pp2(methArgs) pp2(methArgs~items) "", 100, "*") + title=pp2(methName) "args:" pp2(methArgs) pp2(methArgs~items) "signature:" pp2(slotDir~signature) + say "METHOD_CALL" (self~class~increaseCounter~right(7))":" title + +-- say "*** PONG::unknown, slotDir:" pp2(slotDir) "slotDir~class:" pp2(slotDir~class) "methArgs~items="pp2(methArgs~items) +/* + title=pp2(self)": methName="pp2(methName) "methArgs="pp2(methArgs) "methArgs[1]="pp2(methArgs[1]) "value:" pp2(methArgs[1]~string~c2x) pp2(slotdir~signature) + say "PONG::"title + + call dump2 methArgs, title "methArgs" + + do i=1 to methArgs~size - 1 + call dump2 methArgs[i], "argument #" i + say + end + + call dump2 slotDir, title "slotDir" + + say " --> --> --> now creating return value ---" +*/ + +/* + -- process arguments, create reply (return) value, by using the same arguments (without slotDir argument) with the same signature + resArr=.array~new~~append("useThisSignature="slotDir~signature) -- first element a key word followed by signature + do i=1 to methArgs~size-1 -- append all other arguments in the order received + resArr~append(methArgs[i]) + end +*/ + +-- say "PONG: about to create a section, methArgs~size-1:" methArgs~size-1", useThisSignature="slotDir~signature + +/* + resArr=.array~of("useThisSignature="slotDir~signature) + resArr~append(methArgs~section(1,methArgs~size-1)) -- leave out the supplemental slotDir argument + + +/* + if methArgs~items>2 then -- two or more args + resArr~append(methArgs~section(1,methArgs~size-1)) -- leave out the supplemental slotDir argument + else -- one or no arg + resArr~append(methArgs[1]) +*/ + +/* +call dump2 resArr, "PONG - resArr:" +say "PONG --> now returning ..." + + say "---/\--- "~copies(5) + say +*/ + return resArr +*/ + + return dbus.box(slotDir~signature, methArgs~section(1,methArgs~size-1)) + + + +syntax: + co=condition('o') + say "*** PONG PONG PONG syntax ERROR!" + call dump2 co, "syntax condition PONG" + -- say dumpCondition2(co) + + +::class testSignalObject +::method init class + expose counter + counter=0 +::attribute counter class +::method increaseCounter class + expose counter + counter +=1 + return counter + +::method unknown -- this method will service all invocations + use arg methName, methArgs + + slotDir=methArgs[methArgs~items] + title="methName="pp2(methName) "methArgs="pp2(methArgs) "methArgs[1]="pp2(methArgs[1]) pp2(slotdir~signature) + say "SIGNAL " (self~class~increaseCounter~right(7))":" title + +/* + call dump2 methArgs, title "methArgs" + + if methArgs~items>0 then + call dump2 slotDir, title "slotDir" + + -- TODO: process arguments, create reply (return) value, by using the same arguments (without slotDir argument) with the same signature + + say "--\/==\/-- "~copies(5) + say + +-- return methArgs[1] -- will return as a string +-- return .array~of(slotDir~signature, methArgs[1]) -- will return a string +*/ + +::method NameOwnerChanged -- demo how to directly intercept a signal + use arg one, two, three, slotDir + -- say "==>" pp2(slotDir~messageTypeName) pp2(slotDir~interface) pp2(slotDir~member) pp2(slotDir~dateTime)":" pp2(one)"," pp2(two)"," pp2(three) + say "SIGNAL " (self~class~increaseCounter~right(7))":" pp2(slotDir~messageTypeName) pp2(slotDir~interface) pp2(slotDir~member) pp2(slotDir~dateTime)":" pp2(one)"," pp2(two)"," pp2(three) + + + Property changes on: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServer.rex ___________________________________________________________________ Added: svn:executable + * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2011-08-26 14:12:37
|
Revision: 43 http://bsf4oorexx.svn.sourceforge.net/bsf4oorexx/?rev=43&view=rev Author: orexx Date: 2011-08-26 14:12:30 +0000 (Fri, 26 Aug 2011) Log Message: ----------- 20110826 Adding connection to slotDir (allows listeners, services to distinguish them), making sure that all connections get closed upon Halt. Starting documentation, explaining DBus and the binding. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc sandbox/rgf/misc/dbusoorexx/tests/repeat.rex Added Paths: ----------- sandbox/rgf/misc/dbusoorexx/doc/ sandbox/rgf/misc/dbusoorexx/doc/DBusProcesses.odg sandbox/rgf/misc/dbusoorexx/doc/code/ sandbox/rgf/misc/dbusoorexx/doc/code/Documentation-for-Notifications.png sandbox/rgf/misc/dbusoorexx/doc/code/HelloWorld.png sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld1.rex sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld2.rex sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld3.rex sandbox/rgf/misc/dbusoorexx/doc/dbusoorexx-rgf-20110825.odt Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-24 17:16:17 UTC (rev 42) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-26 14:12:30 UTC (rev 43) @@ -65,6 +65,7 @@ - added attribute "haltAllThreadsOnUnexpectedError" to "DBus": if .true and an unexpected Rexx condition is raised while servicing a request, then all Rexx threads will get halted (intended to stop/abend program) + - 2011-08-26, rgf: close all connections if in the DBusServer watchLoop a halt-condition arises (via native code) license: Apache License 2.0 @@ -164,16 +165,24 @@ dataTypes["v"]="variant" -- container -- dataTypes["e"]="dict" -- container: not directly used, rather "a{xy}" -- dataTypes["r"]="struct" -- container: not directly used, rather "(abc)" -.dbus.dir~dataTypes=dataTypes -- save the data type defs +.dbus.dir~dataTypes=dataTypes -- save the data type defs +-- try to require BSF4ooRexx dynamically +call dynamicRequiresBSF4ooRexx ::requires "dbusoorexx" LIBRARY -- get access to the native routines and methods --- ::requires "BSF.CLS" -- BSF4ooRexx: needed need for UTF-8 conversion routines ::requires "rgf_util2.rex" -- installed with the BSF4ooRexx package +::routine dynamicRequiresBSF4ooRexx -- BSF4ooRexx: needed need for UTF-8 conversion routines + signal on any + .context~package~loadPackage("BSF.CLS") -- if not found a syntax condition is raised and + -- control transferred to (immediately following) "ANY:" label +any: + return + /* =============================================================================== */ /* Define the DBus class, which allows connecting, getting objects to talk to, adding own servers on the bus. @@ -1913,6 +1922,7 @@ -- say "... ... probing" pp2(conn) "sleepTime:" pp2(sleepTime) "..." + signal on halt do forever while connections~items>0 -- as long as client connections, probe them call sysSleep sleepTime -- sleep guard on @@ -1932,9 +1942,17 @@ guard off return +halt: -- a HALT condition, make sure all known connections get closed + guard off -- make sure guard is off +say "... DEBUG..." self": HALT in watchConnections, closing all known connections (and thereby their messageloops)..." + do conn over connections + conn~close + end + return + ::method nativeStartServerTimeoutLoop private external "LIBRARY dbusoorexx DbusServerTimeoutLoop" ::method timerLoop unguarded -- "START" or "STOP" expose timeoutLoopActive @@ -1956,10 +1974,12 @@ use strict arg action, timeoutDataPointer -- say "... timeoutDataPointer:" pp2(timeoutDataPointer) copies("<-/\",10) reply -- create a new thread + self~nativeStartServerTimeoutLoop(timeoutDataPointer) -- start the timeout loop, pass (*data) via Rexx to native function + ::method nativeServerShutdown private external "LIBRARY dbusoorexx DbusNativeServerDisconnect" ::method shutdown unguarded -- shutdown server expose connections cself watchLoopActive Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2011-08-24 17:16:17 UTC (rev 42) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2011-08-26 14:12:30 UTC (rev 43) @@ -31,8 +31,10 @@ 2011-08-22, rgf: - add ability to check whether type code is supported on the connection - make the message, server and timeout loop aware of Rexx conditions; if a condition is active, leave the loop setting the loop control variable to .false to reflect this fact in ooRexx code as well + 2011-08-25, rgf: - add entry "CONNECTION" to slotDir; this allows service and listener objects + to distinguish the connections they got registered with - version: 099.20110823 + version: 099.20110826 license: Apache License 2.0 ------------------------ Apache Version 2.0 license ------------------------- @@ -114,11 +116,11 @@ #ifdef DBUSOOREXX_32 - #define DBUS_REXXVERSION "099.20110823 32-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110826 32-bit" // version: "MajorNumber"."YYYYMMDD" #elif defined (DBUSOOREXX_64) - #define DBUS_REXXVERSION "099.20110823 64-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110826 64-bit" // version: "MajorNumber"."YYYYMMDD" #else - #define DBUS_REXXVERSION "099.20110823 n/a-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110826 n/a-bit" // version: "MajorNumber"."YYYYMMDD" #endif #ifndef TID @@ -2182,7 +2184,7 @@ pmarsh->errorPosInSignature=pmarsh->cursor; // memorize cursor, in case we get an error #ifdef DEBUG_MARSHALLING_2 - fprintf(stderr, " marshal() - before switch, typeCode=[%c], bRopIsNull=[%d]\n", typeCode, (int) bRopIsNull); + fprintf(stderr, " marshal() - before switch, typeCode=[%c], bRopIsNull=[%d], rop=[%p]\n", typeCode, (int) bRopIsNull, rop); #endif switch (typeCode) @@ -2581,15 +2583,15 @@ #ifdef DEBUG_ARRAY { - fprintf(stderr, "*** marshal(...): *** ARRAY - begin, IsArray(rop)=[%d], rop=[%p], rop~string=[%s] ", - (int) pmarsh->context->IsArray(rop), + fprintf(stderr, "*** marshal(...): *** ARRAY - begin, IsArray(rop)=[%d], rop=[%p], rop~string=[%s] ", + (bRopIsNull==1 ? 0 : (int) pmarsh->context->IsArray(rop) ), rop, - (rop==NULL ? NULL : pmarsh->context->ObjectToStringValue(rop) ) + (bRopIsNull==1 ? "<NULL>" : pmarsh->context->ObjectToStringValue(rop) ) ); fflush(stderr); // assume array object was supplied for marshalling - if (pmarsh->context->IsArray(rop)) + if (bRopIsNull!=1 && pmarsh->context->IsArray(rop)) { RexxArrayObject tmpRao= ( rop==NULL ? NULL : (RexxArrayObject) rop ); if (tmpRao!=NULL) @@ -2601,9 +2603,8 @@ (unsigned long) pmarsh->context->ArrayItems(tmpRao) ); } - - fprintf(stderr, "\n"); } + fprintf(stderr, "\n"); } #endif @@ -2686,7 +2687,7 @@ if (bRopIsNull) // o.k. Rexx argument not available, supply another empty Rexx array as argument array { #ifdef DEBUG_ARRAY - fprintf(stderr, " marshal(...), 'a': bRopIsNull"); + fprintf(stderr, " marshal(...), 'a': bRopIsNull, *pmarsh->elementStart=[%c]",*pmarsh->elementStart); #endif if (*pmarsh->elementStart!='{') // make sure not a DICT expected! { @@ -2968,9 +2969,11 @@ (unsigned long) (pmarsh->elementEnd - pmarsh->signature) ); #endif + DBusMessageIter iter_array; RexxArrayObject rao=NULL; - if (pmarsh->context->IsArray(anyRop)) // an array object (could be a MapCollection for processing a DICT + + if (anyRop != NULL && pmarsh->context->IsArray(anyRop)) // an array object (could be a MapCollection for processing a DICT { rao=(RexxArrayObject) anyRop; } @@ -4040,7 +4043,7 @@ // ----------------------------------------------------------------------- // adds some information about the message -void helperCreateSlotDirEntries(RexxThreadContext *context, RexxDirectoryObject slotDir, DBusMessage *dbusMsg) +void helperCreateSlotDirEntries(RexxThreadContext *context, RexxDirectoryObject slotDir, DBusMessage *dbusMsg, RexxObjectPtr conn) { const char *str=NULL; RexxObjectPtr rop=NULL; @@ -4048,6 +4051,9 @@ context->SendMessage2(slotDir, "SETENTRY", context->CString("AUTOSTART"), (dbus_message_get_auto_start(dbusMsg) == TRUE ? context->True() : context->False()) ); + context->SendMessage2(slotDir, "SETENTRY", context->CString("CONNECTION"), conn ); + + str=dbus_message_get_destination(dbusMsg); rop=(str==NULL ? context->NullString() : context->CString(str)); context->SendMessage2(slotDir, "SETENTRY", context->CString("DESTINATION"), rop ); @@ -4338,7 +4344,7 @@ if ( bMakeSlotDir || bCollectStatistics) // should we create a slotDir-argument containing message related information? { slotDir=context->NewDirectory(); - helperCreateSlotDirEntries(context->threadContext, slotDir, dbusMsg); // adds some information about the message + helperCreateSlotDirEntries(context->threadContext, slotDir, dbusMsg, self); // adds some information about the message } // unmarshal arguments @@ -4508,7 +4514,7 @@ context->SetGuardOn(); // update statistics on send signal RexxDirectoryObject rdo=(RexxDirectoryObject) context->GetObjectVariable("STATISTICS"); RexxDirectoryObject slotDir=context->NewDirectory(); - helperCreateSlotDirEntries(context->threadContext, slotDir, errReply); // setup slotDir + helperCreateSlotDirEntries(context->threadContext, slotDir, errReply, self); // setup slotDir CSTRING errName=dbus_message_get_error_name(errReply); if (errName!=NULL) { @@ -4583,7 +4589,7 @@ context->SetGuardOn(); // update statistics on call method RexxDirectoryObject rdo=(RexxDirectoryObject) context->GetObjectVariable("STATISTICS"); RexxDirectoryObject slotDir=context->NewDirectory(); - helperCreateSlotDirEntries(context->threadContext, slotDir, returnMsg); // setup slotDir + helperCreateSlotDirEntries(context->threadContext, slotDir, returnMsg, self); // setup slotDir CSTRING sentKind ="SENT"; CSTRING kind ="LASTSENTMESSAGE"; @@ -4689,7 +4695,7 @@ context->SetGuardOn(); // update statistics on send signal RexxDirectoryObject rdo=(RexxDirectoryObject) context->GetObjectVariable("STATISTICS"); RexxDirectoryObject slotDir=context->NewDirectory(); - helperCreateSlotDirEntries(context->threadContext, slotDir, errReply); // setup slotDir + helperCreateSlotDirEntries(context->threadContext, slotDir, errReply, self); // setup slotDir CSTRING errName=dbus_message_get_error_name(errReply); if (errName!=NULL) { @@ -4760,7 +4766,7 @@ context->SetGuardOn(); // update statistics on send signal RexxDirectoryObject rdo=(RexxDirectoryObject) context->GetObjectVariable("STATISTICS"); RexxDirectoryObject slotDir=context->NewDirectory(); - helperCreateSlotDirEntries(context->threadContext, slotDir, errReply); // setup slotDir + helperCreateSlotDirEntries(context->threadContext, slotDir, errReply, self); // setup slotDir CSTRING errName=dbus_message_get_error_name(errReply); if (errName!=NULL) { @@ -5087,7 +5093,7 @@ context->SetGuardOn(); // update statistics on send signal RexxDirectoryObject rdo=(RexxDirectoryObject) context->GetObjectVariable("STATISTICS"); RexxDirectoryObject slotDir=context->NewDirectory(); - helperCreateSlotDirEntries(context->threadContext, slotDir, errReply); // setup slotDir + helperCreateSlotDirEntries(context->threadContext, slotDir, errReply, self); // setup slotDir CSTRING errName=dbus_message_get_error_name(errReply); if (errName!=NULL) { @@ -5159,12 +5165,13 @@ // ----------------------------------------------------------------------------------------------------- // ============================================================================= // // send a signal message over the bus (a broadcast message) -RexxMethod6(RexxObjectPtr, DbusBusSignalMessage, CSTRING, senderObjectPath, +RexxMethod7(RexxObjectPtr, DbusBusSignalMessage, CSTRING, senderObjectPath, CSTRING, signalInterfaceName, CSTRING, signalName, CSTRING, signature, RexxArrayObject, rexxArgs, - CSELF, connPtr) + CSELF, connPtr, + OSELF, self) { // check Rexx arguments first size_t items = (rexxArgs==NULLOBJECT ? 0 : context->ArraySize(rexxArgs)) ; @@ -5253,9 +5260,12 @@ dbusMsg = dbus_message_new_signal(senderObjectPath, // object name of the signal signalInterfaceName, // interfaceName name of the signal signalName ); // name of the signal -fprintf(stderr, "... sending DbusBusSignalMessage(): dbusMsg=[%p] - [%s], [%s], [%s] ... \n", - dbusMsg, senderObjectPath, signalInterfaceName, signalName); +#if defined (DEBUG_METHODS) + fprintf(stderr, "... DBusSignalMessage(): sending DbusBusSignalMessage(): dbusMsg=[%p] - [%s], [%s], [%s] ... \n", + dbusMsg, senderObjectPath, signalInterfaceName, signalName); +#endif + if (NULL == dbusMsg) { char msg[1024]=""; // buffer for error message @@ -5303,7 +5313,7 @@ { RexxDirectoryObject rdo=(RexxDirectoryObject) context->GetObjectVariable("STATISTICS"); RexxDirectoryObject slotDir=context->NewDirectory(); - helperCreateSlotDirEntries(context->threadContext, slotDir, dbusMsg); // setup slotDir + helperCreateSlotDirEntries(context->threadContext, slotDir, dbusMsg, self); // setup slotDir CSTRING sentKind ="SENT"; CSTRING kind ="LASTSENTSIGNAL"; @@ -5327,14 +5337,15 @@ // ============================================================================= // // call a method // use strict arg nixi, busName, receiverObjectPath, interfaceName="", methodName, signature="", ... -RexxMethod8(RexxObjectPtr, DbusBusCallMessage, CSTRING, busName, +RexxMethod9(RexxObjectPtr, DbusBusCallMessage, CSTRING, busName, CSTRING, targetObjectPath, CSTRING, callInterfaceName, CSTRING, callMemberName, CSTRING, replySignature, // if empty/NULL, do not wait on reply (ignore it) CSTRING, argSignature, RexxArrayObject, rexxArgs, - CSELF, connPtr) + CSELF, connPtr, + OSELF, self) { // check Rexx arguments first @@ -5509,7 +5520,7 @@ context->SetGuardOn(); // update statistics on call method RexxDirectoryObject rdo=(RexxDirectoryObject) context->GetObjectVariable("STATISTICS"); RexxDirectoryObject slotDir=context->NewDirectory(); - helperCreateSlotDirEntries(context->threadContext, slotDir, dbusMsg); // setup slotDir + helperCreateSlotDirEntries(context->threadContext, slotDir, dbusMsg, self); // setup slotDir CSTRING sentKind ="SENT"; CSTRING kind ="LASTSENTMESSAGE"; @@ -5563,7 +5574,7 @@ context->SetGuardOn(); // update statistics on call method RexxDirectoryObject rdo=(RexxDirectoryObject) context->GetObjectVariable("STATISTICS"); RexxDirectoryObject slotDir=context->NewDirectory(); - helperCreateSlotDirEntries(context->threadContext, slotDir, dbusMsg); // setup slotDir + helperCreateSlotDirEntries(context->threadContext, slotDir, dbusMsg, self); // setup slotDir CSTRING sentKind ="SENT"; CSTRING kind ="LASTSENTMESSAGE"; @@ -5624,7 +5635,7 @@ ) // should we create a slotDir-argument containing message related information? { slotDir=context->NewDirectory(); - helperCreateSlotDirEntries(context->threadContext, slotDir, replyMsg); // adds some information about the message + helperCreateSlotDirEntries(context->threadContext, slotDir, replyMsg, self); // adds some information about the message } if (msgType==DBUS_MESSAGE_TYPE_ERROR) // reply was an error message, raise condition in caller and inform him ! Added: sandbox/rgf/misc/dbusoorexx/doc/DBusProcesses.odg =================================================================== (Binary files differ) Property changes on: sandbox/rgf/misc/dbusoorexx/doc/DBusProcesses.odg ___________________________________________________________________ Added: svn:executable + * Added: svn:mime-type + application/octet-stream Added: sandbox/rgf/misc/dbusoorexx/doc/code/Documentation-for-Notifications.png =================================================================== (Binary files differ) Property changes on: sandbox/rgf/misc/dbusoorexx/doc/code/Documentation-for-Notifications.png ___________________________________________________________________ Added: svn:executable + * Added: svn:mime-type + application/octet-stream Added: sandbox/rgf/misc/dbusoorexx/doc/code/HelloWorld.png =================================================================== (Binary files differ) Property changes on: sandbox/rgf/misc/dbusoorexx/doc/code/HelloWorld.png ___________________________________________________________________ Added: svn:executable + * Added: svn:mime-type + application/octet-stream Added: sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld1.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld1.rex (rev 0) +++ sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld1.rex 2011-08-26 14:12:30 UTC (rev 43) @@ -0,0 +1,15 @@ +conn=.dbus~session /* get connection to session dbus */ + + /* define message arguments */ +busName ="org.freedesktop.Notifications" +objectName ="/org/freedesktop/Notifications" +interfaceName ="org.freedesktop.Notifications" +memberName ="Notify" +replySignature="u" /* uint32 */ +callSignature ="susssasa{sv}i" /* string,uint32,string,string,string,array of string,dict,int32 */ + +id=conn~message("call",busName,objectName,interfaceName,memberName,replySignature,callSignature, - + "An ooRexx App", , "oorexx", "ooRexx Demo", "Hello, my beloved world!", , , -1) + +::requires "dbus.cls" /* get DBus support */ + Property changes on: sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld1.rex ___________________________________________________________________ Added: svn:executable + * Added: sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld2.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld2.rex (rev 0) +++ sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld2.rex 2011-08-26 14:12:30 UTC (rev 43) @@ -0,0 +1,7 @@ + /* get access to remote object */ +o=.dbus~session~getObject("org.freedesktop.Notifications","/org/freedesktop/Notifications") + +id=o~notify("An ooRexx App", , "oorexx", "ooRexx Demo", "Hello, my beloved world!", , , -1) + +::requires "dbus.cls" /* get DBus support */ + Property changes on: sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld2.rex ___________________________________________________________________ Added: svn:executable + * Added: sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld3.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld3.rex (rev 0) +++ sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld3.rex 2011-08-26 14:12:30 UTC (rev 43) @@ -0,0 +1,8 @@ + /* get access to remote object */ +o=.dbus~session~getObject("org.freedesktop.Notifications","/org/freedesktop/Notifications") + +id=o~org.freedesktop.Notifications.Notify("An ooRexx App", , "oorexx", "ooRexx Demo", - + "Hello, my beloved world!", , , -1) + +::requires "dbus.cls" /* get DBus support */ + Property changes on: sandbox/rgf/misc/dbusoorexx/doc/code/helloWorld3.rex ___________________________________________________________________ Added: svn:executable + * Added: sandbox/rgf/misc/dbusoorexx/doc/dbusoorexx-rgf-20110825.odt =================================================================== (Binary files differ) Property changes on: sandbox/rgf/misc/dbusoorexx/doc/dbusoorexx-rgf-20110825.odt ___________________________________________________________________ Added: svn:executable + * Added: svn:mime-type + application/octet-stream Modified: sandbox/rgf/misc/dbusoorexx/tests/repeat.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/repeat.rex 2011-08-24 17:16:17 UTC (rev 42) +++ sandbox/rgf/misc/dbusoorexx/tests/repeat.rex 2011-08-26 14:12:30 UTC (rev 43) @@ -55,7 +55,7 @@ end ended=.dateTime~new -say "started:" started", ended:" ended", duration:" ended-started +say "started:" started", ended:" ended", duration:" ended-started"/"repetitions"="||(ended-started)/repetitions exit 0 usage: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2011-08-29 21:09:57
|
Revision: 46 http://bsf4oorexx.svn.sourceforge.net/bsf4oorexx/?rev=46&view=rev Author: orexx Date: 2011-08-29 21:09:50 +0000 (Mon, 29 Aug 2011) Log Message: ----------- 20110829 Finished first draft of documentation. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/doc/code/client.rex sandbox/rgf/misc/dbusoorexx/doc/code/service.rex sandbox/rgf/misc/dbusoorexx/doc/code/signalListener.rex sandbox/rgf/misc/dbusoorexx/doc/dbusoorexx-rgf-20110825.odt sandbox/rgf/misc/dbusoorexx/examples/demoHelloService2.rex sandbox/rgf/misc/dbusoorexx/examples/demoHelloService3.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesServerPong.rex sandbox/rgf/misc/dbusoorexx/tests/testErroneousServer.rex sandbox/rgf/misc/dbusoorexx/tests/testPropertiesServerPong.rex Added Paths: ----------- sandbox/rgf/misc/dbusoorexx/doc/code/privateClient.rex sandbox/rgf/misc/dbusoorexx/doc/code/privateService.rex sandbox/rgf/misc/dbusoorexx/doc/code/service2.rex sandbox/rgf/misc/dbusoorexx/doc/dbusoorexx-rgf-20110825.pdf Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-28 17:47:50 UTC (rev 45) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-29 21:09:50 UTC (rev 46) @@ -13,7 +13,7 @@ cf.: dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> (as of 2011-07-14) - version: 099.20110823 + version: 099.20110829 changes: - 2011-07-20, rgf; DBusProxyObject: - added proxy.dispatch(methodName[,args...])-method to send messages that @@ -66,6 +66,7 @@ Rexx condition is raised while servicing a request, then all Rexx threads will get halted (intended to stop/abend program) - 2011-08-26, rgf: close all connections if in the DBusServer watchLoop a halt-condition arises (via native code) + - 2011-08--29, rgf: change sequence of init-args for DBusServiceObject to reflect importance by usage pattern license: Apache License 2.0 @@ -94,7 +95,7 @@ */ .local~dbus.dir=.directory~new -.dbus.dir~version="099.20110823" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' +.dbus.dir~version="099.20110829" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' .dbus.dir~DBUS_SERVICE_DBUS ="org.freedesktop.DBus" -- "The bus name used to talk to the bus itself." .dbus.dir~DBUS_PATH_DBUS ="/org/freedesktop/DBus" -- "The object path used to talk to the bus itself." @@ -1234,9 +1235,9 @@ */ ::class "DbusServiceObject" mixinclass object public -::method init -- service.connection, service.objectPath and introData may be supplied later, using the respective methods +::method init -- intorData, service.connection, service.objectPath; introData may be supplied later, using the respective methods expose service.connection service.objectPath service.introspectRootNode service.methods - use strict arg service.connection=.nil, service.objectPath=.nil, introData=.nil + use strict arg introData=.nil, service.connection=.nil, service.objectPath=.nil service.methods=.nil Modified: sandbox/rgf/misc/dbusoorexx/doc/code/client.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/doc/code/client.rex 2011-08-28 17:47:50 UTC (rev 45) +++ sandbox/rgf/misc/dbusoorexx/doc/code/client.rex 2011-08-29 21:09:50 UTC (rev 46) @@ -1,13 +1,11 @@ -conn=.dbus~connect("session") -- connect to the "session" bus +conn=.dbus~connect("session") -- connect to the "session" bus objectPath ="/org/rexxla/oorexx/demo/Hello" busName ="org.rexxla.oorexx.demo.Hello" -interface ="org.rexxla.oorexx.demo.Hello" -o=conn~getObject(busName, objectPath) -- get the DBus object +o=conn~getObject(busName, objectPath) -- get the DBus object num1=12.345 num2=10.01 -say num1"*"num2"="o~multiply(num1,num2) -- use the multiply method +say num1"*"num2"="o~multiply(num1,num2) -- use the multiply method ::requires "dbus.cls" -- get dbus support for ooRexx -::requires "rgf_util2.rex" -- installed with the BSF4ooRexx package Added: sandbox/rgf/misc/dbusoorexx/doc/code/privateClient.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/doc/code/privateClient.rex (rev 0) +++ sandbox/rgf/misc/dbusoorexx/doc/code/privateClient.rex 2011-08-29 21:09:50 UTC (rev 46) @@ -0,0 +1,12 @@ +address="tcp:host=localhost,port=23000,family=ipv4;" +conn=.dbus~connect(address) -- connect to given address + +objectPath ="/org/rexxla/oorexx/demo/Hello" +busName ="org.rexxla.oorexx.demo.Hello" +o=conn~getObject(busName, objectPath) -- get the DBus object + +num1=12.345 +num2=10.01 +say num1"*"num2"="o~multiply(num1,num2) -- use the multiply method + +::requires "dbus.cls" -- get dbus support for ooRexx Property changes on: sandbox/rgf/misc/dbusoorexx/doc/code/privateClient.rex ___________________________________________________________________ Added: svn:executable + * Added: sandbox/rgf/misc/dbusoorexx/doc/code/privateService.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/doc/code/privateService.rex (rev 0) +++ sandbox/rgf/misc/dbusoorexx/doc/code/privateService.rex 2011-08-29 21:09:50 UTC (rev 46) @@ -0,0 +1,47 @@ + -- set up address and define default service to be added to client connections +address="tcp:host=localhost,port=23000,family=ipv4;" +defaultService =.HelloRexxService~new +server =.DBUSServer~new(address,.HelloRexxService~new) +server~startup -- start up the private server + +say "server~serverAddress:" pp2(server~serverAddress) + +signal on halt -- intercept ctl-c (jump to label "halt:") + +say "Hit enter to stop server..." +parse pull answer + +halt: -- a ctl-c causes a jump to this label + say "shutdown server, closing all connections to clients..." + server~shutdown -- close connection, stops message loop + + +::requires "dbus.cls" -- get dbus support for ooRexx + +::class HelloRexxService subclass DBusServiceObject + +::method init -- constructor + -- define introspect data; instead one could supply the full path to an introspect file + idata= '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"' - + '"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> ' - + '<node> ' - + ' <interface name="org.freedesktop.DBus.Introspectable"> ' - + ' <method name="Introspect"> ' - + ' <arg name="data" direction="out" type="s"/> ' - + ' </method> ' - + ' </interface> ' - + ' <interface name="org.rexxla.oorexx.demo.Hello"> ' - + ' <method name="Multiply"> ' - + ' <arg name="number1" direction="in" type="d"/> ' - + ' <arg name="number2" direction="in" type="d"/> ' - + ' <arg name="result" direction="out" type="d"/> ' - + ' </method> ' - + ' </interface> ' - + '</node> ' + self~init:super(idata) -- let superclass (DBusServiceObject) initialize + +::method Multiply -- implementation of "orx.rexxla.oorexx.demo.Hello.Multiply" + use arg number1, number2, slotDir + say "Multply-request received: sender-bus=["slotDir~sender"]" "at=["slotDir~dateTime"]" + return number1*number2 + Property changes on: sandbox/rgf/misc/dbusoorexx/doc/code/privateService.rex ___________________________________________________________________ Added: svn:executable + * Modified: sandbox/rgf/misc/dbusoorexx/doc/code/service.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/doc/code/service.rex 2011-08-28 17:47:50 UTC (rev 45) +++ sandbox/rgf/misc/dbusoorexx/doc/code/service.rex 2011-08-29 21:09:50 UTC (rev 46) @@ -1,6 +1,5 @@ objectPath ="/org/rexxla/oorexx/demo/Hello" busName ="org.rexxla.oorexx.demo.Hello" -interface ="org.rexxla.oorexx.demo.Hello" conn=.dbus~session -- get the session bus @@ -19,8 +18,9 @@ say "Hit enter to stop server..." parse pull answer -halt: -- a ctl-c causes a jump to this label - conn~messageLoop("stop") -- stop message loop +halt: -- a ctl-c causes a jump to this label + say "closing connection." + conn~close -- close connection, stops message loop ::requires "dbus.cls" -- get dbus support for ooRexx @@ -45,8 +45,8 @@ ' </interface> ' - '</node> ' -::method Multiply +::method Multiply -- implementation of "orx.rexxla.oorexx.demo.Hello.Multiply" use arg number1, number2, slotDir - say "Multply-request received: sender-bus="slotDir~sender "at="slotDir~dateTime + say "Multply-request received: sender-bus=["slotDir~sender"]" "at=["slotDir~dateTime"]" return number1*number2 Added: sandbox/rgf/misc/dbusoorexx/doc/code/service2.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/doc/code/service2.rex (rev 0) +++ sandbox/rgf/misc/dbusoorexx/doc/code/service2.rex 2011-08-29 21:09:50 UTC (rev 46) @@ -0,0 +1,56 @@ +objectPath ="/org/rexxla/oorexx/demo/Hello" +busName ="org.rexxla.oorexx.demo.Hello" + +conn=.dbus~session -- get the session bus + +signal on halt -- intercept ctl-c (jump to label "halt:") + +res=conn~busName("request", busName) -- request a bus name +if res<>.dbus.dir~primaryOwner & res<>.dbus.dir~alreadyOwner then -- o.k., wait for clients? +do + say "res="res "problem with requesting the bus name" busName", aborting ..." + exit -1 +end + +service=.HelloRexxService~new -- create an instance of the Rexx service +conn~serviceObject("add", objectPath, service) -- add service object to connection + +.IDBusPathMaker~publishAllServiceObjects(conn) -- allow discovery of serviced object paths + +say "Hit enter to stop server..." +parse pull answer + +halt: -- a ctl-c causes a jump to this label + say "closing connection." + conn~close -- close connection, stops message loop + + +::requires "dbus.cls" -- get dbus support for ooRexx + +::class HelloRexxService subclass DBusServiceObject + +::method init -- constructor + -- define introspect data; instead one could supply the full path to an introspect file + idata= '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"' - + '"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> ' - + '<node> ' - + ' <interface name="org.freedesktop.DBus.Introspectable"> ' - + ' <method name="Introspect"> ' - + ' <arg name="data" direction="out" type="s"/> ' - + ' </method> ' - + ' </interface> ' - + ' <interface name="org.rexxla.oorexx.demo.Hello"> ' - + ' <method name="Multiply"> ' - + ' <arg name="number1" direction="in" type="d"/> ' - + ' <arg name="number2" direction="in" type="d"/> ' - + ' <arg name="result" direction="out" type="d"/> ' - + ' </method> ' - + ' </interface> ' - + '</node> ' + self~init:super(idata) -- let superclass (DBusServiceObject) initialize + +::method Multiply -- implementation of "orx.rexxla.oorexx.demo.Hello.Multiply" + use arg number1, number2, slotDir + say "Multply-request received: sender-bus=["slotDir~sender"]" "at=["slotDir~dateTime"]" + return number1*number2 + Property changes on: sandbox/rgf/misc/dbusoorexx/doc/code/service2.rex ___________________________________________________________________ Added: svn:executable + * Modified: sandbox/rgf/misc/dbusoorexx/doc/code/signalListener.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/doc/code/signalListener.rex 2011-08-28 17:47:50 UTC (rev 45) +++ sandbox/rgf/misc/dbusoorexx/doc/code/signalListener.rex 2011-08-29 21:09:50 UTC (rev 46) @@ -1,64 +1,39 @@ -#!/usr/bin/rexx -/* - author: Rony G. Flatscher (c) 2011 - name: demoSignalListener.rex - usage: rexx demoHelloListener.rex - purpose: - demonstrate how to listen for any dbus signal with a Rexx object - date: 2011-07-29 (2011-07-17) - license: AL 2.0 (Apache License 2.0) - - ------------------------ Apache Version 2.0 license ------------------------- - Copyright 2011 Rony G. Flatscher - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ----------------------------------------------------------------------------- -*/ - signal on halt -- intercept ctl-c (jump to label 'halt:' below) conn=.dbus~session -- get the "session" connection conn~listener("add", .rexxSignalListener~new) -- add the Rexx listener object -conn~match("add", "type='signal'", .true) -- ask for any signal on the bus, blocking mode +conn~match("add", "type='signal'", .true) -- ask for any signal message say "Hit enter to stop listener..." parse pull answer -halt: -- a ctl-c causes a jump to this label - say "stopping message loop." - conn~messageLoop("stop")-- stop message loop +halt: -- a ctl-c causes a jump to this label + say "closing connection." + conn~close -- close connection, stops message loop +::requires "dbus.cls" -- get dbus support for ooRexx - -::requires "dbus.cls" -- get dbus support for ooRexx -::requires "rgf_util2.rex" -- installed with the BSF4ooRexx package - - -::class RexxSignalListener -- just dump all signals/events we receive -::method unknown -- this method will service all invocations +::class RexxSignalListener -- just dump all signals/events we receive +::method unknown -- this method will service all invocations use arg methName, methArgs slotDir=methArgs[methArgs~items] -- last argument is slotDir - say "==>" pp2(slotDir~messageTypeName) pp2(slotDir~interface) pp2(slotDir~member) pp2(slotDir~dateTime)": nrArgs="methArgs~items-1 + say "-->" pp(slotDir~messageTypeName) pp(slotDir~interface) - + pp(slotDir~member)", nrArgs="methArgs~items-1 - call dump2 slotDir, "accompanying slotDir" if methArgs~items>1 then do - call dump2 methArgs~section(1, methArgs~items-1), "signal's arguments" + do i=1 to methArgs~items-1 + say " argument #" i":" pp(methArgs[i]) + end end say "-"~copies(79) - ::method NameOwnerChanged -- demo how to directly intercept a signal - use arg name, oldOwner, newOwner, slotDir - say "==> NameOwnerChanged:" "Name:" pp2(name)", OldOwner:" pp2(oldOwner)", NewOwner:" pp2(newOwner) + use arg name, old, new, slotDir + say "==> NameOwnerChanged:" "Name:" pp(name)", OldOwner:" pp(old)", NewOwner:" pp(new) + say "-"~copies(79) +::routine pp -- "pretty print": enclose string value with square brackets + parse arg value + return "["value"]" Modified: sandbox/rgf/misc/dbusoorexx/doc/dbusoorexx-rgf-20110825.odt =================================================================== (Binary files differ) Added: sandbox/rgf/misc/dbusoorexx/doc/dbusoorexx-rgf-20110825.pdf =================================================================== (Binary files differ) Property changes on: sandbox/rgf/misc/dbusoorexx/doc/dbusoorexx-rgf-20110825.pdf ___________________________________________________________________ Added: svn:executable + * Added: svn:mime-type + application/octet-stream Modified: sandbox/rgf/misc/dbusoorexx/examples/demoHelloService2.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/examples/demoHelloService2.rex 2011-08-28 17:47:50 UTC (rev 45) +++ sandbox/rgf/misc/dbusoorexx/examples/demoHelloService2.rex 2011-08-29 21:09:50 UTC (rev 46) @@ -112,7 +112,7 @@ ' </interface> ' - '</node> ' - self~init:super(.nil,.nil,idata) -- let DBusServiceObject initialize + self~init:super(idata) -- let DBusServiceObject initialize ::method serviceName /* the name of this service object */ return "RexxHelloService2" Modified: sandbox/rgf/misc/dbusoorexx/examples/demoHelloService3.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/examples/demoHelloService3.rex 2011-08-28 17:47:50 UTC (rev 45) +++ sandbox/rgf/misc/dbusoorexx/examples/demoHelloService3.rex 2011-08-29 21:09:50 UTC (rev 46) @@ -78,7 +78,7 @@ -- introspection data stored in an external file idata='demoHelloService3.xml' -- filename that contains the introspect.xml data - self~init:super(.nil,.nil,idata) -- let DBusServiceObject initialize + self~init:super(idata) -- let DBusServiceObject initialize ::method serviceName /* the name of this service object */ return "RexxHelloService3" Modified: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesServerPong.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesServerPong.rex 2011-08-28 17:47:50 UTC (rev 45) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesServerPong.rex 2011-08-29 21:09:50 UTC (rev 46) @@ -193,7 +193,7 @@ if~addProperty("Rony3rw", "s", "readwrite") introspectData=node~makeString -- turn definitions into the appropriate xml-string - self~init:super(,,introspectData) -- make sure we define the interface data for the clients (will be returned by Introspect) + self~init:super(introspectData) -- make sure we define the interface data for the clients (will be returned by Introspect) say "init: created on the fly the following introspect data:" say introspectData Modified: sandbox/rgf/misc/dbusoorexx/tests/testErroneousServer.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/testErroneousServer.rex 2011-08-28 17:47:50 UTC (rev 45) +++ sandbox/rgf/misc/dbusoorexx/tests/testErroneousServer.rex 2011-08-29 21:09:50 UTC (rev 46) @@ -140,7 +140,7 @@ ' </interface> ' - '</node> ' - self~init:super(.nil,.nil,idata) -- let DBusServiceObject initialize + self~init:super(idata) -- let DBusServiceObject initialize ::method serviceName /* the name of this service object */ return "RexxHelloService2" Modified: sandbox/rgf/misc/dbusoorexx/tests/testPropertiesServerPong.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/testPropertiesServerPong.rex 2011-08-28 17:47:50 UTC (rev 45) +++ sandbox/rgf/misc/dbusoorexx/tests/testPropertiesServerPong.rex 2011-08-29 21:09:50 UTC (rev 46) @@ -158,7 +158,7 @@ if~addProperty("Rony3rw", "s", "readwrite") introspectData=node~makeString -- turn definitions into the appropriate xml-string - self~init:super(,,introspectData) -- make sure we define the interface data for the clients (will be returned by Introspect) + self~init:super(introspectData) -- make sure we define the interface data for the clients (will be returned by Introspect) say "init: created on the fly the following introspect data:" say introspectData This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2011-09-12 22:22:19
|
Revision: 47 http://bsf4oorexx.svn.sourceforge.net/bsf4oorexx/?rev=47&view=rev Author: orexx Date: 2011-09-12 22:22:12 +0000 (Mon, 12 Sep 2011) Log Message: ----------- 20110912 Various changes that should make using service objects independent of a certain D-Bus connection. Streamlining arguments for signal messages in DBusServiceObject to match DBus'. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc sandbox/rgf/misc/dbusoorexx/doc/DBusProcesses.odg sandbox/rgf/misc/dbusoorexx/examples/demoHelloService2.rex sandbox/rgf/misc/dbusoorexx/examples/demoHelloService3.rex sandbox/rgf/misc/dbusoorexx/tests/testErroneousServer.rex Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-08-29 21:09:50 UTC (rev 46) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2011-09-12 22:22:12 UTC (rev 47) @@ -13,7 +13,7 @@ cf.: dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> (as of 2011-07-14) - version: 099.20110829 + version: 099.20110912 changes: - 2011-07-20, rgf; DBusProxyObject: - added proxy.dispatch(methodName[,args...])-method to send messages that @@ -66,9 +66,15 @@ Rexx condition is raised while servicing a request, then all Rexx threads will get halted (intended to stop/abend program) - 2011-08-26, rgf: close all connections if in the DBusServer watchLoop a halt-condition arises (via native code) - - 2011-08--29, rgf: change sequence of init-args for DBusServiceObject to reflect importance by usage pattern + - 2011-08-29, rgf: change sequence of init-args for DBusServiceObject to reflect importance by usage pattern + - 2011-09-12, rgf: - DBus.close(): setting "cself=.nil", so cannot be used anymore + - DBus.message(...): raise error, if connection is closed + - DBus.listener() & DBus.serviceObject(): if no listeners and service objects, stop message loop + - DBusServiceObject: replaced "service.connection" with "service.connections" (a set); + removed "service.objectPath"; changed method "service.signal" to + accept the arguments in the following order "objectPath,interface,member, ...args...", + a signal is sent to all connections the service object is registered with - license: Apache License 2.0 ------------------------ Apache Version 2.0 license ------------------------- @@ -95,7 +101,7 @@ */ .local~dbus.dir=.directory~new -.dbus.dir~version="099.20110829" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' +.dbus.dir~version="099.20110912" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' .dbus.dir~DBUS_SERVICE_DBUS ="org.freedesktop.DBus" -- "The bus name used to talk to the bus itself." .dbus.dir~DBUS_PATH_DBUS ="/org/freedesktop/DBus" -- "The object path used to talk to the bus itself." @@ -443,7 +449,7 @@ ::method nativeCloseConnection private EXTERNAL "LIBRARY dbusoorexx DbusNativeConnectionClose" ::method close -- close (private) connection - expose busType server statistics + expose busType statistics cself self~messageLoop("stop") -- stop message loop, independent of the connection's type statistics~closed=.dateTime~new -- remember time of closing @@ -455,7 +461,9 @@ self~nativeCloseConnection -- say self ":" "! ---> NATIVE CLOSE CONNECTION GOT CARRIED OUT <--- !" "busType:" pp2(busType) "self:" pp2(self) "server:" pp2(server) end + cself=.nil -- from now on this instance of a connection is not usable anymore + /* Fold functions/methods that query the state or abilities of a connection. "Authenticated" or "IsAuthenticated" are synonyms: returns .true, if the connection was authenticated, .false else "O" or "C" or "IsO" or "IsC" are synonyms: return .true, if the connection is open, .false else @@ -599,10 +607,8 @@ guard on -- how many listener and service objects are there ? nr=internalSignalListeners~items+internalRegisteredServiceObjects~items guard off -/* ??? RGF 2011-08-13 if nr=0 then -- no registered listener & server objects, make sure message loop is stopped self~messageLoop("stop") -*/ return count end @@ -650,8 +656,11 @@ if rexxObject~isA(.DBusServiceObject) then do + rexxObject~service.connections~put(self) -- add this connection to the serviceObject connection set +/* rexxObject~service.connection=self -- set connection in DBusServiceObject rexxObject~service.objectPath=objectPath -- save desired object-Path +*/ end guard on @@ -696,10 +705,9 @@ nr=internalSignalListeners~items+internalRegisteredServiceObjects~items guard off -/* ??? RGF 2011-08-13 if nr=0 then -- no registered listener & server objects, make sure message loop is stopped self~messageLoop("stop") -*/ + return count end @@ -836,9 +844,14 @@ /* folding methods of the "message" group into one parametrized method */ ::method message -- send message to service object + expose cself use strict arg function, ... signal on syntax + + if cself=.nil then -- connection got closed, cannot use it anymore + raise syntax 93.900 array ('Connection is closed, hence cannot be used anymore') + firstLetter=function~strip~left(1)~upper if pos(firstLetter,"CS")=0 then raise syntax 88.916 array ('"function"', '"C[all]", "S[ignal]"', function) @@ -1236,10 +1249,13 @@ ::class "DbusServiceObject" mixinclass object public ::method init -- intorData, service.connection, service.objectPath; introData may be supplied later, using the respective methods - expose service.connection service.objectPath service.introspectRootNode service.methods - use strict arg introData=.nil, service.connection=.nil, service.objectPath=.nil + expose service.connections service.introspectRootNode service.methods +-- expose service.connection service.objectPath service.introspectRootNode service.methods +-- use strict arg introData=.nil, service.connection=.nil, service.objectPath=.nil + use strict arg introData=.nil service.methods=.nil + service.connections=.set~new -- set of connections in which this service object gets used signal on syntax self~service.parseIntrospectData(introData) @@ -1295,8 +1311,15 @@ expose service.introspectData return dbus.box("s", service.introspectData) -::attribute service.connection /* object's connection to use */ +::attribute service.connections /* object's connection to use */ +/* +::attribute service.connections get /* object's connection to use */ + expose service.connections + return service.connections~copy /* return a copy of the current set of connections this service object services */ +*/ + +/* ::attribute service.objectPath get /* object's path on the dbus */ ::attribute service.objectPath set /* object's path on the dbus */ expose service.objectPath service.connection @@ -1316,6 +1339,7 @@ service.objectPath=oPath return syntax: raise propagate +*/ ::attribute service.introspectRootNode get /* make introspection parse tree available */ @@ -1331,7 +1355,7 @@ ::attribute service.methods get /* make introspection parse tree available */ -::attribute service.replySignature get +::attribute service.replySignature get /* returns the reply signature for the given member or .nil */ expose service.methods service.objectPath use arg member, interface="" @@ -1348,11 +1372,16 @@ return .nil -- no signature/member found -::method service.sendSignal -- utility method to ease emitting signals from the service object - expose service.methods service.connection service.objectPath - use strict arg member, interface, ... +::method service.sendSignal -- utility method to ease emitting signals from the service object; + -- will emit the signal to all connections this service object is registered with + expose service.methods service.connections +-- expose service.methods service.connection service.objectPath + use strict arg objectPath=.nil, interface="", member, ... - signature="" + signature="" -- default to no arguments + -- canonize (empty,left-out) values + if interface=.nil then interface="" + if objectPath="" then objectPath=.nil if service.methods<>.nil then do @@ -1370,16 +1399,56 @@ end -- build arguments for "self~message": - args=.array~of("signal", service.objectPath, interface, member, signature) - do i=3 to arg() -- append arguments to the signal, if any + -- args=.array~of("signal", service.objectPath, interface, member, signature) + args=.array~of("signal", objectPath, interface, member, signature) + do i=4 to arg() -- append arguments to the signal, if any args~append(arg(i)) end signal on syntax - service.connection~sendWith("message", args) -- send the message +-- service.connection~sendWith("message", args) -- send the message + + do conn over service.connections -- send signal to all connections this service object is being used + if conn~cself=.nil then -- connection closed? + service.connections~remove(conn) -- remove connection from set + else + do + if objectPath=.nil then -- no object path supplied, find an object path for this service object on the connection + do + opath=.nil + s=conn~serviceObject("GetRegisteredServiceObjects")~supplier + do while s~available -- loop over all index/item pairs + if s~item=self then + do + if s~index~left(1)="/" then -- found an object path index entry + do + opath=s~index -- use this as object path, leave supplier loop + leave + end + else if s~index="default" then -- service object is a default entry + do + opath="/" -- supply a root path value as the default value + end + end + s~next -- get next index/item pair + end + + if opath=.nil then -- service object is not registered with connection anymore, remove connection from service object as well + do + service.connections~remove(conn) + iterate + end + + args[2]=opath -- set object path in signal message + end + + conn~sendWith("message", args) -- send the signal message + end + end return syntax:raise propagate + /* service requests */ ::method unknown expose service.methods @@ -1945,7 +2014,7 @@ halt: -- a HALT condition, make sure all known connections get closed guard off -- make sure guard is off -say "... DEBUG..." self": HALT in watchConnections, closing all known connections (and thereby their messageloops)..." +-- say "... DEBUG..." self": HALT in watchConnections, closing all known connections (and thereby their messageloops)..." do conn over connections conn~close end Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2011-08-29 21:09:50 UTC (rev 46) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2011-09-12 22:22:12 UTC (rev 47) @@ -34,7 +34,7 @@ 2011-08-25, rgf: - add entry "CONNECTION" to slotDir; this allows service and listener objects to distinguish the connections they got registered with - version: 099.20110826 + version: 099.20110912 license: Apache License 2.0 ------------------------ Apache Version 2.0 license ------------------------- @@ -116,11 +116,11 @@ #ifdef DBUSOOREXX_32 - #define DBUS_REXXVERSION "099.20110826 32-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110912 32-bit" // version: "MajorNumber"."YYYYMMDD" #elif defined (DBUSOOREXX_64) - #define DBUS_REXXVERSION "099.20110826 64-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110912 64-bit" // version: "MajorNumber"."YYYYMMDD" #else - #define DBUS_REXXVERSION "099.20110826 n/a-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "099.20110912 n/a-bit" // version: "MajorNumber"."YYYYMMDD" #endif #ifndef TID @@ -134,6 +134,14 @@ #define REXX_LOADER // needed for dbus_threads_init_default(), cf. <http://dbus.freedesktop.org/doc/api/html/group__DBusThreads.html#ga33b6cf3b8f1e41bad5508f84758818a7> + // if defined, then a "Disconnected" signal on a private server's client connection will + // cause a "disconnect" message to be sent to the private server automatically + // as of 2011-09-12 (DBus 1.5.7) the "Disconnected" signal is not sent on private server connections; + // to test stalled connections the Rexx code checks for that and disconnects, if the connection is not open anymore, + // hence the following def is not really needed +// #define REXX_AUTO_DISCONNECT_FROM_PRIVATE_SERVER + + // #define DEBUG_RGF // for temporary debug output @@ -4125,10 +4133,12 @@ RexxObjectPtr rxFalse=context->False(); RexxObjectPtr rxNil =context->Nil(); + +#if defined (REXX_AUTO_DISCONNECT_FROM_PRIVATE_SERVER) // if auto-disconnect from private server // determine, whether this is a connection to a private Rexx server running in this instance RexxObjectPtr tmpRop=context->GetObjectVariable("server"); bool bClientForPrivateRexxServer= (tmpRop!=NULL && tmpRop!=rxNil); - +#endif // Rexx objects that work as servers on the bus RexxDirectoryObject serviceObjects = (RexxDirectoryObject) context->GetObjectVariable("internalRegisteredServiceObjects"); @@ -4209,7 +4219,7 @@ int msgType=dbus_message_get_type(dbusMsg); -#if defined (DEBUG_RGF) // show all messages we receive on this connection, look for the "Disconnected" signal +#if defined (DEBUG_RGF) // show all messages we receive on this connection, look for the "Disconnected" signal // ---> fprintf(stderr, "/// ==//==>>> ... message: type=[%d] (%s), path=[%s], interface=[%s], member=[%s] | signature=[%s] <===//===\\\\\\.......\n", msgType, @@ -4280,6 +4290,8 @@ // a signal, but we have no listeners, ignore if (msgType==DBUS_MESSAGE_TYPE_SIGNAL ) { + +#if defined (REXX_AUTO_DISCONNECT_FROM_PRIVATE_SERVER) // if auto-disconnect from private server // if a Disconnect signal on a server client connection, then send a "disconnect" // message to the server supplying this connection as an argument (shuts down client connection in Rexx) if (bClientForPrivateRexxServer) // if so, check for the "Disconnect" signal and handle it @@ -4302,6 +4314,7 @@ continue; } } +#endif // check whether Rexx listeners are registered, if not discard signal and go ahead if (context->ArrayItems(signalListeners)==0) @@ -4442,6 +4455,7 @@ context->SetGuardOff(); // release exclusive access to object variables/attributes +#if defined (REXX_AUTO_DISCONNECT_FROM_PRIVATE_SERVER) // if auto-disconnect from private server // if a Disconnect signal on a server client connection, then send a "disconnect" // message to the server supplying this connection as an argument if (bClientForPrivateRexxServer) @@ -4461,6 +4475,7 @@ context->SendMessage1(context->SendMessage0(self, "SERVER"), "DISCONNECT", self); } } +#endif } // a message call, then invoke the message on the service object Modified: sandbox/rgf/misc/dbusoorexx/doc/DBusProcesses.odg =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/examples/demoHelloService2.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/examples/demoHelloService2.rex 2011-08-29 21:09:50 UTC (rev 46) +++ sandbox/rgf/misc/dbusoorexx/examples/demoHelloService2.rex 2011-09-12 22:22:12 UTC (rev 47) @@ -9,7 +9,7 @@ introspection data - the program demonstrates emitting signals needs: - ooRexx dbus support package - date: 2011-08-04 + date: 2011-08-04, 2011-09-12 specs: dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> (as of 2011-07-14) license: AL 2.0 (Apache License 2.0) @@ -52,13 +52,13 @@ conn~serviceObject("add", objectPath, o) say "o="pp2(o) say "-- ** -- "~copies(5) -o~service.sendSignal("Start", "", "started at:" .dateTime~new~string) +o~service.sendSignal(objectPath, interface, "Start", "started at:" .dateTime~new~string) say "sleeping" timeout "secs ..." call syssleep timeout halt: - o~service.sendSignal("Exit", "", "exited at:" .dateTime~new~string) + o~service.sendSignal(objectPath, interface, "Exit", "exited at:" .dateTime~new~string) conn~messageLoop("stop")-- stop message loop say "after stopping message loop..." exit -1 Modified: sandbox/rgf/misc/dbusoorexx/examples/demoHelloService3.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/examples/demoHelloService3.rex 2011-08-29 21:09:50 UTC (rev 46) +++ sandbox/rgf/misc/dbusoorexx/examples/demoHelloService3.rex 2011-09-12 22:22:12 UTC (rev 47) @@ -53,12 +53,12 @@ say "o="pp2(o) say "-- ** -- "~copies(5) -o~service.sendSignal("Start", "", "started at:" .dateTime~new~string) +o~service.sendSignal(objectPath, interface, "Start", "started at:" .dateTime~new~string) say "sleeping" timeout "secs ..." call syssleep timeout halt: - o~service.sendSignal("Exit", "", "exited at:" .dateTime~new~string) + o~service.sendSignal(objectPath, interface, "Exit", "exited at:" .dateTime~new~string) conn~messageLoop("stop")-- stop message loop say "after stopping message loop..." exit -1 Modified: sandbox/rgf/misc/dbusoorexx/tests/testErroneousServer.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/testErroneousServer.rex 2011-08-29 21:09:50 UTC (rev 46) +++ sandbox/rgf/misc/dbusoorexx/tests/testErroneousServer.rex 2011-09-12 22:22:12 UTC (rev 47) @@ -6,7 +6,7 @@ purpose: - demonstrate a dbus Rexx service object with its introspection data defined within this program (cf. init-method) needs: - ooRexx dbus support package - date: 2011-07-29 (2011-07-17) + date: 2011-07-29 (2011-07-17, 2011-09-12) specs: dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> (as of 2011-07-14) license: AL 2.0 (Apache License 2.0) @@ -62,7 +62,7 @@ /* /* -o~service.sendSignal("Start", "", "started at:" .dateTime~new~string) +o~service.sendSignal(objectPath, interface, "Start", "started at:" .dateTime~new~string) say "sleeping" timeout "secs ..." call syssleep timeout say "press return to end" @@ -70,7 +70,7 @@ */ halt: - o~service.sendSignal("Exit", "", "exited at:" .dateTime~new~string) + o~service.sendSignal(objectPath, interface, "Exit", "exited at:" .dateTime~new~string) conn~messageLoop("stop")-- stop message loop say "after stopping message loop..." exit -1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2011-09-18 16:41:32
|
Revision: 49 http://bsf4oorexx.svn.sourceforge.net/bsf4oorexx/?rev=49&view=rev Author: orexx Date: 2011-09-18 16:41:26 +0000 (Sun, 18 Sep 2011) Log Message: ----------- 20110918 Also make a universal library available for MacOSX. This way if a MacOSX user has D-Bus installed or created with macports.org, then she can test the ooRexx language binding on MacOSX immediatley. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/tests/runtest-mac.sh Added Paths: ----------- sandbox/rgf/misc/dbusoorexx/libdbusoorexx.dylib Added: sandbox/rgf/misc/dbusoorexx/libdbusoorexx.dylib =================================================================== (Binary files differ) Property changes on: sandbox/rgf/misc/dbusoorexx/libdbusoorexx.dylib ___________________________________________________________________ Added: svn:executable + * Added: svn:mime-type + application/octet-stream Modified: sandbox/rgf/misc/dbusoorexx/tests/runtest-mac.sh =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/runtest-mac.sh 2011-09-12 22:25:34 UTC (rev 48) +++ sandbox/rgf/misc/dbusoorexx/tests/runtest-mac.sh 2011-09-18 16:41:26 UTC (rev 49) @@ -5,4 +5,4 @@ DBUSLIB=$HOME/dev/bsf4oorexx/sandbox/rgf/misc/dbusoorexx/dev DBUSPATH=$HOME/dev/bsf4oorexx/sandbox/rgf/misc/dbusoorexx echo $0 running "DYLD_LIBRARY_PATH=$DBUSLIB PATH=$DBUSPATH rexx $1" -DYLD_LIBRARY_PATH=$DBUSLIB PATH=$DBUSPATH:$PATH rexx $1 +DYLD_LIBRARY_PATH=$DBUSLIB PATH=$DBUSPATH:$PATH rexx $* This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2014-07-30 18:01:42
|
Revision: 227 http://sourceforge.net/p/bsf4oorexx/code/227 Author: orexx Date: 2014-07-30 18:01:28 +0000 (Wed, 30 Jul 2014) Log Message: ----------- 20140730 Changed dbusoorexx totally to reflect the information that libdbus is not threadsafe; the dbus messages must be exchanged in the thread that established the connection otherwise dbus may be erroneous; this implementation caters for this information received after the first implementation. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc sandbox/rgf/misc/dbusoorexx/dev/linuxMakefile32 sandbox/rgf/misc/dbusoorexx/examples/demoHelloClient.rex sandbox/rgf/misc/dbusoorexx/examples/demoHelloService1.rex sandbox/rgf/misc/dbusoorexx/examples/demoHelloService2.rex sandbox/rgf/misc/dbusoorexx/examples/demoHelloService3.rex sandbox/rgf/misc/dbusoorexx/examples/helloWorld.rex sandbox/rgf/misc/dbusoorexx/examples/margiolKate.rex sandbox/rgf/misc/dbusoorexx/examples/margiolVLC.rex sandbox/rgf/misc/dbusoorexx/examples/signalListener.rex sandbox/rgf/misc/dbusoorexx/tests/org.rexxla.oorexx.dbus.test.pong.properties.service sandbox/rgf/misc/dbusoorexx/tests/testDBusMisc.rex sandbox/rgf/misc/dbusoorexx/tests/testGetObjectPaths.rex sandbox/rgf/misc/dbusoorexx/tests/testHelloWorld.rex sandbox/rgf/misc/dbusoorexx/tests/testMultipleConnections.rex sandbox/rgf/misc/dbusoorexx/tests/testProxy1.rex sandbox/rgf/misc/dbusoorexx/tests/testProxy2.rex Added Paths: ----------- sandbox/rgf/misc/dbusoorexx/tests/a_PropertiesClientPing.rex sandbox/rgf/misc/dbusoorexx/tests/a_PropertiesServerPong.rex sandbox/rgf/misc/dbusoorexx/tests/b_RawPingClient.rex sandbox/rgf/misc/dbusoorexx/tests/b_RawPongServer.rex sandbox/rgf/misc/dbusoorexx/tests/c_ErroneousClient.rex sandbox/rgf/misc/dbusoorexx/tests/c_ErroneousService.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/a_PrivateClient.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/a_PrivateServer.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateClientPing.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateClientPingSimple.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPong.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPongDoingOtherStuff.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/c_PrivatePropertiesClientPing.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/c_PrivatePropertiesServerPong.rex Removed Paths: ------------- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClient.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPing.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateClientPingSimple.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesClientPing.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivatePropertiesServerPong.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServer.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServerPong.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/testPrivateServerPongDoingOtherStuff.rex sandbox/rgf/misc/dbusoorexx/tests/testErroneousClient.rex sandbox/rgf/misc/dbusoorexx/tests/testErroneousServer.rex sandbox/rgf/misc/dbusoorexx/tests/testPropertiesClientPing.rex sandbox/rgf/misc/dbusoorexx/tests/testPropertiesServerPong.rex sandbox/rgf/misc/dbusoorexx/tests/testRawPingClient.rex sandbox/rgf/misc/dbusoorexx/tests/testRawPongServer.rex Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-07-16 16:11:39 UTC (rev 226) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-07-30 18:01:28 UTC (rev 227) @@ -13,7 +13,7 @@ cf.: dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> (as of 2011-07-14) - version: 099.20110912 + version: 100.20140730 changes: - 2011-07-20, rgf; DBusProxyObject: - added proxy.dispatch(methodName[,args...])-method to send messages that @@ -74,11 +74,23 @@ removed "service.objectPath"; changed method "service.signal" to accept the arguments in the following order "objectPath,interface,member, ...args...", a signal is sent to all connections the service object is registered with + - 2014-07, rgf: - rework in order to cater for libdbus-limitation "interaction only in thread + that created the connection": making sure that all interaction with + DBus occurs in the thread that established the connection to DBus; reshuffled + and changed strategies in DBUS.CLS and oorexxdbus.cc (both are closely interwined) + - Added mixin class Worker and WorkerMessage + - make sure that all connection related interactions with DBus occurs + only in the thread that was used to connect to DBus; this implies that + stopping a message loop causes that connection to be not usable from + ooRexx anymore! + - if an error condition is raised in the message loop thread, it will get + re-raised on the blocked thread upon return + license: Apache License 2.0 ------------------------ Apache Version 2.0 license ------------------------- - Copyright 2011 Rony G. Flatscher + Copyright 2011-2014 Rony G. Flatscher Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -101,8 +113,11 @@ */ .local~dbus.dir=.directory~new -.dbus.dir~version="099.20110912" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' +.dbus.dir~bDebug=.false -- .true +.dbus.dir~bDebugServer=.false -- .true +.dbus.dir~version="100.20140730" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' + .dbus.dir~DBUS_SERVICE_DBUS ="org.freedesktop.DBus" -- "The bus name used to talk to the bus itself." .dbus.dir~DBUS_PATH_DBUS ="/org/freedesktop/DBus" -- "The object path used to talk to the bus itself." -- same definition, but without category and C-style "_" between names: @@ -174,9 +189,12 @@ -- dataTypes["r"]="struct" -- container: not directly used, rather "(abc)" .dbus.dir~dataTypes=dataTypes -- save the data type defs +-- TODO: do we want BSF4ooRexx loaded automatically or on request ? -- try to require BSF4ooRexx dynamically -call dynamicRequiresBSF4ooRexx +call dynamicRequiresBSF4ooRexx -- requires BSF.CLS +-- TODO: 2014-07-26, rgf: determine whether we need an "::OPTIONS DIGITS 20" (if that influences int64 and double conversions in native code) + ::requires "dbusoorexx" LIBRARY -- get access to the native routines and methods ::requires "rgf_util2.rex" -- installed with the BSF4ooRexx package @@ -194,9 +212,10 @@ /* Define the DBus class, which allows connecting, getting objects to talk to, adding own servers on the bus. */ -::class "DBus" public +::class "DBus" public inherit Worker /* --- class methods ------ */ +-- TODO: 201407 rgf ::method init class expose system session system=.nil @@ -211,35 +230,56 @@ /* unique id for the computer */ ::method machineID class external "LIBRARY dbusoorexx DbusGetUniqueMachineId" +-- TODO: 201407 rgf ::method system class /* returns the shared system bus connection */ expose system +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "arg(1):" pp(arg(1)) + + if arg(1)="CLEAR", arg(2)=system then -- remove cached connection to force a new one to be created + do +-- say "... clearing system cache..." + system=.nil + return + end + if system=.nil then /* if not available yet, get and rember it */ - system=self~connect("system") + system=self~new("system") return system +-- TODO: 201407 rgf ::method session class /* returns the shared session bus connection */ expose session +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "arg(1):" pp(arg(1)) + + if arg(1)="CLEAR", arg(2)=session then -- remove cached connection to force a new one to be created + do +-- say "... clearing session cache ..." + session=.nil + return + end + + if session=.nil then /* if not available yet, get and rember it */ - session=self~connect("session") + session=self~new("session") return session -::method getSystemBus class private external "LIBRARY dbusoorexx DbusNativeGetSystemBus" -::method getSessionBus class private external "LIBRARY dbusoorexx DbusNativeGetSessionBus" - ::method connect class /* connect to an existing dbus connection */ -- use strict arg address -- "address" can also be "system", "session" - forward message ("NEW") +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + forward message ("NEW") -- let our version of NEW handle this -/* Creates a new bus instance. */ -::method nativeConnectPrivate private external "LIBRARY dbusoorexx DbusNativeConnectionOpenPrivate" - +-- TODO: 201407 rgf ::method new class expose system session use strict arg address +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + + bus=self~new:.class -- return barely initialized + signal on syntax lcAddress=address~strip~lower if wordpos(lcAddress, "session system")>0 then @@ -249,7 +289,8 @@ if system<>.nil then /* shared message bus already cached, use it */ return system - bus=self~getSystemBus(self~new:.class) + -- self~getSystemBus(bus) + bus~connectToAddress(lcaddress) -- will start message loop system=bus end else @@ -257,30 +298,133 @@ if session<>.nil then /* shared message bus already cached, use it */ return session - bus=self~getSessionBus(self~new:.class) + bus~connectToAddress(lcaddress) -- will start message loop session=bus end end else -- address was given do - bus=self~new:.class -- return barely initialized bus~busType="private" -- rest will be initialized from native code - if address<>"native" then - do - bus~nativeConnectPrivate(address) -- create a private connection to the address - end + -- "native" sent by native code which will initialize the connection after + -- receiving the new dbus object + if address<>"native" then + do + -- bus~nativeConnectPrivate(address) -- create a private connection to the address +-- TODO: 201407 - o.k. to do that here? If so, how about the "native" connection (probably from DBusServer's native peer) + -- bus~startupMessageLoop + bus~connectToAddress(address) -- use address verbatimly + end end return bus syntax: raise propagate -- raise in caller +::attribute address get + +::attribute pseudoAddress set -- 20140728, rgf: allows private server to set a pseudo address for each connected client + expose address + use strict arg address -- just assign whatever we receive + /* --- instance methods --- */ -/* ::method init: everything is implemented in native code, including setting attributes - 'address', 'uniqueBusName' and 'wellKnownBusName', if given +/* much is implemented in native code, including setting attributes 'address', + 'uniqueBusName' and 'wellKnownBusName', if given */ +::method init + expose cself busType address makeSlotDir makeReplySlotDir active - + internalRegisteredServiceObjects internalSignalListeners - + unmarshalByteArrayAsString - + collectStatistics statistics server sendEmptyReply - + haltAllThreadsOnUnexpectedError +if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) + + cself=.nil /* will be set by a native method */ + busType=.nil /* will be set by native method */ + address=.nil + server=.nil /* if a client connection to a private Rexx server this will be set by the native method */ + makeSlotDir=.true /* by default create and pass slotDir as last argument on received signals or method calls */ + makeReplySlotDir=.false /* by default do not create a slotDir for a regular message reply; if set to .true + the return value, if it is not an array will be placed as the first value + into a newly created array; the slotDir value will be appended to the array */ + active=.nil /* native code: sets to .true, if connection is being listened to, .false, if message loop is not available */ + stopLoop=.false /* native code: message loop will stop, when set to .true */ + + internalRegisteredServiceObjects=.directory~new + internalSignalListeners =.array~new + unmarshalByteArrayAsString =.false /* if .true, then return 'ay' as strings */ + + sendEmptyReply =.true /* if .true, then sends an empty reply upon a message call */ + + haltAllThreadsOnUnexpectedError=.false -- set to .true when all running threads should be halted, if the + -- there is an unexpected Rexx condition while servicing a request + + collectStatistics =.true /* if .true, simple statistics are gathered and stored in 'statistics' */ + statistics =.directory~new + statistics~started=.dateTime~new -- remember this connection's creation time, define initial counter values + statistics~countSentErrors =0 + statistics~countSentMessages =0 + statistics~countSentSignals =0 + statistics~countReceivedErrors =0 + statistics~countReceivedMessages=0 + statistics~countReceivedSignals =0 + + forward class (super) -- let superclass initialize (Worker class) + +/** Allows read access, returns <code>.true</code> if the connection's message loop thread is running, +* <code>.false</code> else. +* @since 2014-07-24 +*/ +::attribute active get + +/* Creates or gets a new bus instance. */ +::method nativeConnectPrivate private external "LIBRARY dbusoorexx DbusNativeConnectionOpenPrivate" +::method nativeGetSystemBus private external "LIBRARY dbusoorexx DbusNativeGetSystemBus" +::method nativeGetSessionBus private external "LIBRARY dbusoorexx DbusNativeGetSessionBus" + + +::method connectToAddress -- unguarded + expose active +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + forward message (connectToAddress"_worker") continue + guard on when active=.true -- block (wait) until message queue is running, otherwise we get lock-ups + +/** This method will connect to DBus in an own thread which then remains active for the connection's +* message loop. This way the problems with libdbus (not fully multithreading safe) should be fixed. +*/ +::method connectToAddress_worker -- rgf, 20140722 + expose active address +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + if active=.true then return -- message loop already up and running + + reply -- start a new thread which will start the message loop and block +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "after reply" + + use arg address -- get desired address + if address="session" then + do + self~nativeGetSessionBus(self) + end + else if address="system" then + do + self~nativeGetSystemBus(self) + end + else if address="native" then -- this comes from native code in the context of a privat Server, + do + NOP + end + else + do +say " -> self~nativeConnectPrivate(address)" pp(address) "-->" + self~nativeConnectPrivate(address) -- create a private connection to the address +say " <- self~nativeConnectPrivate(address)" + end + + self~startMessageLoop -- will start message loop in its own thread + + + /* controls whether a received message call without defined return value will return an empty message reply */ ::attribute sendEmptyReply get ::attribute sendEmptyReply set -- default: .true (append slotDir as last argument) @@ -316,7 +460,7 @@ /* attribute controls whether the arguments from a reply (result of calling a message on a remote DBUS object) will get appended with a slotDir-directory supplying possibly - useful information about the DBUS message; default: .false + useful information about the DBUS message; default: .true */ ::attribute makeReplySlotDir get ::attribute makeReplySlotDir set -- default: .false (do not append slotDir to result of a message call (turning result into an array object) @@ -336,7 +480,7 @@ Rexx string instead of a Rexx array with individual bytes */ ::attribute unmarshalByteArrayAsString get -::attribute unmarshalByteArrayAsString set -- default: .false (do not append slotDir to result of a message call (turning result into an array object) +::attribute unmarshalByteArrayAsString set -- default: .true (append slotDir to result of a message call (turning result into an array object) expose unmarshalByteArrayAsString use strict arg argUnmarshalByteArrayAsString=.true @@ -353,64 +497,113 @@ ::attribute statistics -- a directory ::attribute haltAllThreadsOnUnexpectedError -- if set to .true, then an unexpected Rexx condition will cause all Rexx threads to be halted -::method init - expose cself busType makeSlotDir makeReplySlotDir active - - internalRegisteredServiceObjects internalSignalListeners - - unmarshalByteArrayAsString - - collectStatistics statistics server sendEmptyReply - - haltAllThreadsOnUnexpectedError - cself=.nil /* will be set by a native method */ - busType=.nil /* will be set by native method */ - server=.nil /* if a client connection to a private Rexx server this will be set by the native method */ - makeSlotDir=.true /* by default create and pass slotDir as last argument on received signals or method calls */ - makeReplySlotDir=.false /* by default do not create a slotDir for a regular message reply; if set to .true - the return value, if it is not an array will be placed as the first value - into a newly created array; the slotDir value will be appended to the array */ - active=.nil /* native code: sets to .true, if connection is being listened to, .false, if connection got closed */ - internalRegisteredServiceObjects=.directory~new - internalSignalListeners =.array~new - unmarshalByteArrayAsString =.false /* if .true, then return 'ay' as strings */ +/** Method blocks until connection got closed and message loop thread stopped, turning attribute +* <code>active</code> to <code>.false</code>. +*/ +::method waitOnConnectionClosed unguarded + expose active + guard on when active=.false - sendEmptyReply =.true /* if .true, then sends an empty reply upon a message call */ +/* +::method waitOnMessageLoop private unguarded -- block invocation until message loop stopped + expose active + use arg value=.false - haltAllThreadsOnUnexpectedError=.false -- set to .true when all running threads should be halted, if the - -- there is an unexpected Rexx condition while servicing a request + guard on when active=value -- resume, once the attribute gets the received Boolean value +*/ - collectStatistics =.true /* if .true, simple statistics are gathered and stored in 'statistics' */ - statistics =.directory~new - statistics~started=.dateTime~new -- remember this connection's creation time, define initial counter values - statistics~countSentErrors =0 - statistics~countSentMessages =0 - statistics~countSentSignals =0 - statistics~countReceivedErrors =0 - statistics~countReceivedMessages=0 - statistics~countReceivedSignals =0 +::method nativeStartMessageLoop private external "LIBRARY dbusoorexx DbusMessageLoop" +-- DEPRECATED, FUNCTION REMOVED, raising a condition hinting of what to use instead ! -::method nativeStartMessageLoop private external "LIBRARY dbusoorexx DbusMessageLoop" +-- TODO: rgf, 20140728 - temporarily allow for everyone to use this method (for server connections) +-- ::method startMessageLoop unguarded private +::method startMessageLoop unguarded + expose active stopLoop address busType + -- expose stopLoop address busType +if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "arrived" -::method waitOnMessageLoop private unguarded -- block invocation until message loop stopped - expose active - use arg value + signal on syntax +-- TODO: rgf, 20140728: if public then raise an error, if attempting to start a running messageLoop + if active=.true then + do + info="(bustype='"||bustype"'" + if var("ADDRESS") then info=info", address='"address"'" + info=info")" + raise syntax 98.900 array ("Message loop for this connection" info "already active (running)") + -- raise syntax 98.900 array ("Message loop for this connection (address='"address"', busType='"||busType"') got stopped already, cannot re-start it") + end - guard on when active=value -- resume, once the attribute gets the received Boolean value + if stopLoop=.true then -- message loop got already stopped, we do not allow to restart it, a new conncection needs to be established + do + info="(bustype='"||bustype"'" + if var("ADDRESS") then info=info", address='"address"'" + info=info")" + raise syntax 98.900 array ("Message loop for this connection" info "got stopped, cannot use it anymore") + -- raise syntax 98.900 array ("Message loop for this connection (address='"address"', busType='"||busType"') got stopped already, cannot re-start it") + end + reply -- start a new thread and start message loop +if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "BEFORE: self~nativeStartMessageLoop" + self~nativeStartMessageLoop -- start message loop +if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "AFTER : self~nativeStartMessageLoop" + return + +syntax: raise propagate + + +-- 2014-07-23: do not allow to start message loop by third parties! ::method messageLoop unguarded -- query, start, stop messageLoop, waitUntilStopped - expose active + expose active stopLoop bustype parse upper arg action . --- say "self="pp2(self) "self~active="pp2(active) +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "action:" pp(action) + msg="Method [messageLoop] not available anymore! 'start' is done at connection creation time," + msg=msg"'stop' is done in new method 'close', 'active' is replaced by the get attribute named 'active'," + msg=msg"'wait' is replaced by method 'waitOnConnectionClosed'." + + signal on syntax + -- raise syntax 88.900 array ('Argument "start" not "stop" not available anymore, use method "close" instead"'value'"') + raise syntax 88.900 array (msg) + +/* + if active=.true then + do + guard on + stopLoop=.true -- stop message loop, independent of the conncection's type + -- remove session or system bus object from cache (this will cause a new connection to be created) + if wordpos(busType,"session system")>0 then + self~class~send(busType,"CLEAR", self) -- if cached, remove this shared connection + guard off + end + return + end + return + +syntax: raise propagate + + + act=action~left(1) if pos(act,"AW")=0 then act=action~left(3) -- "STA", "STO" + pos=wordpos(act, "A W") +-- pos=wordpos(act, "A STO W") + + if pos=0 then + raise syntax 88.916 array ('"action"', '"A[ctive]", "W[aitUntilStopped]"', action) +-- raise syntax 88.916 array ('"action"', '"Sto[p]", "A[ctive]", "W[aitUntilStopped]"', action) + +/* pos=wordpos(act, "A STA STO W") if pos=0 then - raise syntax 88.916 array ('"action"', '"Sta[rt]", "Sto[p]", "A[ctive]", "W[ait]"', action) + raise syntax 88.916 array ('"action"', '"Sta[rt]", "Sto[p]", "A[ctive]", "W[aitUntilStopped]"', action) +*/ if act="A" then return active -- messageLoop active/running? can be .true, .false @@ -426,53 +619,130 @@ if act="STO" then -- stop message loop do + raise syntax 88.900 array ('Argument "stop" not available anymore, use method "close" instead"'value'"') +/* if active=.true then do guard on - active=.false + stopLoop=.true -- stop message loop, independent of the conncection's type + -- remove session or system bus object from cache (this will cause a new connection to be created) + if wordpos(busType,"session system")>0 then + self~class~send(busType,"CLEAR", self) -- if cached, remove this shared connection guard off end return +*/ end - - if active=.true then return -- already running - - -- start message loop - reply -- start a new thread and start message loop - signal on syntax - -- attribute "active" must be .false at this time, will be set to .true in native code ! - self~nativeStartMessageLoop -- start message loop return +*/ syntax: raise propagate + +-- TODO: 201407, rgf: do we still need this or let us remove it ? +/** Block until connection (message loop) gets closed (attribute <code>active</code> turns <code>.false</code>. */ +::method waitUntilClosed unguarded + expose active + guard on when active=.false + + ::method nativeCloseConnection private EXTERNAL "LIBRARY dbusoorexx DbusNativeConnectionClose" -::method close -- close (private) connection - expose busType statistics cself - self~messageLoop("stop") -- stop message loop, independent of the connection's type +::method close -- unguarded -- close (private) connection + expose busType address statistics active stopLoop + +if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) + + -- TODO: ?if stopLoop=.true, then already closed, raise syntax error? + if active=.false then return -- nothing to close anymo + + signal on syntax + + -- close connection by shutting down message loop thread (which must be used for communication) + stopLoop=.true -- stop message loop, independent of the conncection's type +-- guard off -- allow message loop to guard +-- say "::close #2 - about to do a guard on" pp2(self) pp(bustype) pp(address) + guard on when active=.false -- wait until message loop is stopped (attribute will be set there in native code) statistics~closed=.dateTime~new -- remember time of closing + if busType="private" then -- if a private connection, then truly close it do --- send the "Disconnected" signal to the server, doesn't work :( --- self~message("signal", "/org/freedesktop/DBus/Local", "org.freedesktop.DBus.Local", "Disconnected", "") - self~nativeCloseConnection --- say self ":" "! ---> NATIVE CLOSE CONNECTION GOT CARRIED OUT <--- !" "busType:" pp2(busType) "self:" pp2(self) "server:" pp2(server) +if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "==> busType="pp(busType) "address="pp(address) "about to close connection!" + + self~nativeCloseConnection -- close the connection for good, will set CSELF to .nil end - cself=.nil -- from now on this instance of a connection is not usable anymore + return +syntax: raise propagate + + + + +-- keep these private so to not blow up the amount of methods one needs to be aware of +::method nativeIsConnected private external "LIBRARY dbusoorexx DbusConnectionIsConnected" +::method nativeIsAuthenticated private external "LIBRARY dbusoorexx DbusConnectionIsAuthenticated" +::method nativeCanSendType private external "LIBRARY dbusoorexx DbusConnectionCanSendType" + +::method query unguarded -- reroute invocation through message loop thread + expose active stopLoop address bustype + if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + + signal on syntax + parse upper arg option +1 1 option3 +3 . -- get first char and first three chars in uppercase + + optionPos=pos(option, "ACOT") + if optionPos=0 then -- option not identified just as of yet + do + option3Pos=wordPos(option3, "ISA ISC ISO") + if option3Pos>0 then + do + option="AOO"~subChar(option3Pos) -- set option + end + else + do + raise syntax 88.916 array ('"option"', '"A[uthenticated]" or "IsA[uthenticated]", "O[pen]" or "IsO[pen]" or "C[onnected]" or "IsC[onnected]", "T[ypecode]"', arg(1)) + end + end + else + do + if option="C" then option="O" -- test "Open" functionality + end + + if option="O" then -- this (is connection open/connected) we can determine without using the connection + do + guard on -- make sure that no one can change the values in the middle of the following tests + return active + end + + if stopLoop=.true then -- message loop got already stopped, we do not allow to restart it, a new conncection needs to be established + do + signal on syntax + info="(bustype='"||bustype"'" + if var("ADDRESS") then info=info", address='"address"'" + info=info")" + raise syntax 98.900 array ("Message loop for this connection" info "got stopped, cannot use it anymore to query connection properties") + end + + -- add "_worker" to message name, submit any received arguments, dispatch via Worker's infrastructure + forward message ("POSTMESSAGE") array (.Message~new(self, .context~name"_worker", 'A', arg(1, "Array"))) + +syntax: raise propagate + + + /* Fold functions/methods that query the state or abilities of a connection. "Authenticated" or "IsAuthenticated" are synonyms: returns .true, if the connection was authenticated, .false else "O" or "C" or "IsO" or "IsC" are synonyms: return .true, if the connection is open, .false else "Supports" or "TypeCode" are synonyms: if no second argument, returns all supported type codes; if second argument given, returns .true, if all type codes are supported, .false if any one is not supported */ -::method query +::method query_worker parse upper arg option +1 1 option3 +3 . -- get first char and first three chars in uppercase + signal on syntax optionPos=pos(option, "ACOT") if optionPos=0 then -- option not identified just as of yet do @@ -499,22 +769,10 @@ use strict arg nix, char -- fetch arguments return self~canSendTypeCode(char) -- test whether given type codes are supported +syntax: raise propagate -::method nativeIsConnected private external "LIBRARY dbusoorexx DbusConnectionIsConnected" -::method nativeIsAuthenticated private external "LIBRARY dbusoorexx DbusConnectionIsAuthenticated" -/* -::method isOpen -- returns .true if connected (open), .false else; synonym for "isConnected" - return self~nativeIsConnected -::method isConnected -- returns .true if connected (open), .false else - return self~nativeIsConnected - -::method isAuthenticated - return self~nativeIsAuthenticated -*/ - --- keep these private so to not blow up the amount of methods one needs to be aware of -::method nativeCanSendType private external "LIBRARY dbusoorexx DbusConnectionCanSendType" +-- TODO: 201407 rgf - assuming o.k. in any thread /* supports() ... return "typeCodes={a,...,x}" ... returns string denoting available types supports("T[ypecode]", typecode) ... returns .false/.true; typecode can be a string: only returns .true then, if all characters are supported type codes @@ -538,11 +796,6 @@ use strict arg char -- fetch arguments -/* - if kind~strip~left(1)~upper<>"T" then - raise syntax 88.916 array ('"kind"', '"T[ypecode]"', action) -*/ - do i=1 to char~length -- iterate over characters if self~nativeCanSendType(char~subChar(i))=.false then return .false end @@ -550,15 +803,19 @@ -::method uninit - expose busType cself +::method uninit -- make sure we stop the message loop thread, if necessary + expose busType active --- say self"::UNINIT ! cself="pp2(cself) "busType="pp2(busType) "self:" pp2(self) +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "#1 (kick off loop)" - if cself<>.nil then -- a DBUS connection pointer in hand ? + -- if cself<>.nil then -- a DBUS connection pointer in hand ? + if active=.true then -- is the message loop still active for this connection ? + do self~close -- make sure connection gets closed + end + /* add listener object, syntax: - a[dd] | r[emove], object [,[interface] [,signalname]] - g[etListeners] */ @@ -579,11 +836,13 @@ else o=.DBUSSignalListener~new(object, interface, signalName) - guard on + guard on -- accessing attributes internalSignalListeners~append(o) guard off - self~messageLoop("start") -- start message loop +-- TODO: really to start/stop message loop ? No - message loop is connection-related, not instance related +-- TODO: 201407 rgf +-- self~messageLoop("start") -- start message loop return .true end @@ -592,6 +851,7 @@ do use strict arg action, object=.nil, interface=.nil, signalName=.nil count=0 + guard on -- accessing attributes do i=internalSignalListeners~size to 1 by -1 o=internalSignalListeners~at(i) @@ -603,13 +863,19 @@ count += 1 end end + guard off +-- TODO: really to start/stop message loop ? +-- TODO: 201407 rgf +/* guard on -- how many listener and service objects are there ? nr=internalSignalListeners~items+internalRegisteredServiceObjects~items guard off - if nr=0 then -- no registered listener & server objects, make sure message loop is stopped - self~messageLoop("stop") + if nr=0 then -- no registered listener & server objects, make sure message loop is stopped + self~messageLoop("stop") +*/ + return count end @@ -625,6 +891,7 @@ +-- TODO: 201407 rgf /* add service Rexx object, syntax: - a[dd], objectPath, rexxObject - r[emove], objectPath - g[etRegisteredServiceObjects] @@ -668,7 +935,9 @@ internalRegisteredServiceObjects[objectPath]=rexxObject guard off - self~messageLoop("start") -- start message loop +-- TODO: really to start/stop message loop ? +-- TODO: 201407, rgf, do not think so, we now have one connection-based message loop only! +-- self~messageLoop("start") -- start message loop return oldValue end @@ -701,12 +970,16 @@ guard off end +-- TODO: really to start/stop message loop ? +-- TODO: 201407, rgf, no, we use the connection message loop now +/* guard on -- how many listener and service objects are there ? nr=internalSignalListeners~items+internalRegisteredServiceObjects~items guard off if nr=0 then -- no registered listener & server objects, make sure message loop is stopped self~messageLoop("stop") +*/ return count end @@ -726,27 +999,72 @@ ::attribute cself /* native's representation of this dbus object, set in native code */ -::attribute busType /* bustype for the dbus conneciton, if any; +::attribute busType /* bustype for the dbus connection, if any; DBusBusType defines types that will be named "session", "system", "starter" and maybe "private" in Rexx*/ ::attribute server /* if set, connection belongs to a DBusServer (i.e. a client connection) */ +-- TODO: 201407 rgf /* unique id for the bus */ ::method nativeUniqueBusID private external "LIBRARY dbusoorexx DbusGetUniqueBusId" ::method uniqueBusID + expose stopLoop address bustype + if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + + if stopLoop=.true then -- message loop got already stopped, we do not allow to restart it, a new conncection needs to be established + do + signal on syntax + info="(bustype='"||bustype"'" + if var("ADDRESS") then info=info", address='"address"'" + info=info")" + raise syntax 98.900 array ("Message loop for this connection" info "got stopped, cannot use it anymore") + end + + guard off -- from now on unguarded to not block anything + + -- add "_worker" to message name, submit any received arguments, dispatch via Worker's infrastructure + forward message ("POSTMESSAGE") array (.Message~new(self, .context~name"_worker", 'A', arg(1, "Array"))) + +syntax: raise propagate + +::method uniqueBusID_worker unguarded expose bustype if bustype="private" then return "private:rexx:"self~identityHash return self~nativeUniqueBusID + + +-- TODO: 201407 rgf -- folding into a method busName( "request" | {"release"| "yield"} | "hasOwner" | "uniqueName", name [, flags] ) /* unique bus name for the dbus connection */ -::method nativeUniqueBusName private unguarded external "LIBRARY dbusoorexx DbusGetUniqueBusName" +::method nativeUniqueBusName private external "LIBRARY dbusoorexx DbusGetUniqueBusName" +::method nativeRequestBusName private external "LIBRARY dbusoorexx DbusBusNameRequest" +::method nativeBusNameHasOwner private external "LIBRARY dbusoorexx DbusBusNameHasOwner" -- deprecated! +::method nativeReleaseBusName private external "LIBRARY dbusoorexx DbusBusNameRelease" -::method nativeRequestBusName private unguarded external "LIBRARY dbusoorexx DbusBusNameRequest" -::method nativeBusNameHasOwner private unguarded external "LIBRARY dbusoorexx DbusBusNameHasOwner" -- deprecated! -::method nativeReleaseBusName private unguarded external "LIBRARY dbusoorexx DbusBusNameRelease" +::method busName -- route invocation through the message loop thread + expose stopLoop address bustype + if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + + if stopLoop=.true then -- message loop got already stopped, we do not allow to restart it, a new conncection needs to be established + do + signal on syntax + info="(bustype='"||bustype"'" + if var("ADDRESS") then info=info", address='"address"'" + info=info")" + raise syntax 98.900 array ("Message loop for this connection" info "got stopped, cannot use it anymore") + end + + guard off -- from now on unguarded to not block anything + + -- add "_worker" to message name, submit any received arguments, dispatch via Worker's infrastructure + forward message ("POSTMESSAGE") array (.Message~new(self, .context~name"_worker", 'A', arg(1, "Array"))) + +syntax: raise propagate + + /* folding methods of the "busName" group into one parametrized method, cf <http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-names> @@ -764,7 +1082,7 @@ -> constants directly available via .dbus.dir */ -::method busName unguarded +::method busName_worker unguarded parse upper arg function . signal on syntax @@ -815,8 +1133,30 @@ ::method nativeAddMatch private external "LIBRARY dbusoorexx DbusBusAddMatch" ::method nativeRemoveMatch private external "LIBRARY dbusoorexx DbusBusRemoveMatch" +/** Delegate invocation to message loop thread using the Worker's class infrastructure. This way + invoking DBUs-connection related invocations take place in the thread, that +*/ +::method match -- reroute invocation through message loop thread + expose stopLoop address bustype + if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "/// arg(5):" pp(arg(5)) + + if stopLoop=.true then -- message loop got already stopped, we do not allow to restart it, a new conncection needs to be established + do + signal on syntax + info="(bustype='"||bustype"'" + if var("ADDRESS") then info=info", address='"address"'" + info=info")" + raise syntax 98.900 array ("Message loop for this connection" info "got stopped, cannot use it anymore") + end + + guard off -- from now on unguarded to not block anything + -- add "_worker" to message name, submit any received arguments, dispatch via Worker's infrastructure + forward message ("POSTMESSAGE") array (.Message~new(self, .context~name"_worker", 'A', arg(1, "Array"))) + +syntax: raise propagate + /* folding methods of the "match" group into one parametrized method */ -::method match +::method match_worker use strict arg action, filter, block=.false signal on syntax @@ -834,24 +1174,51 @@ else self~nativeRemoveMatch(filter, block) return -syntax: - raise propagate +syntax: raise propagate +-- o.k. the following two native messages will be invoked in the message loop, cf. method "message" ::method nativeSignalMessage private external "LIBRARY dbusoorexx DbusBusSignalMessage" ::method nativeCallMessage private external "LIBRARY dbusoorexx DbusBusCallMessage" + /* folding methods of the "message" group into one parametrized method */ -::method message -- send message to service object - expose cself +::method message -- send message to service object; reroute invocation through message loop thread + expose stopLoop address bustype + if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "/// arg(5):" pp(arg(5)) + + if stopLoop=.true then -- message loop got already stopped, we do not allow to restart it, a new conncection needs to be established + do + signal on syntax + info="(bustype='"||bustype"'" + if var("ADDRESS") then info=info", address='"address"'" + info=info")" + raise syntax 98.900 array ("Message loop for this connection" info "got stopped, cannot use it anymore") + end + + guard off -- from now on unguarded to not block anything + + -- add "_worker" to message name, submit any received arguments, dispatch via Worker's infrastructure + forward message ("POSTMESSAGE") array (.Message~new(self, .context~name"_worker", 'A', arg(1, "Array"))) + +syntax: raise propagate + + +::method message_worker -- send message to service object + expose cself active use strict arg function, ... + if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + signal on syntax if cself=.nil then -- connection got closed, cannot use it anymore raise syntax 93.900 array ('Connection is closed, hence cannot be used anymore') + if active=.false then -- connection got closed, cannot use it anymore + raise syntax 93.900 array ('Message loop for connection is not active (not running yet/anymore)') + firstLetter=function~strip~left(1)~upper if pos(firstLetter,"CS")=0 then raise syntax 88.916 array ('"function"', '"C[all]", "S[ignal]"', function) @@ -909,7 +1276,7 @@ -::method getObject -- request remote object, return a Rexx proxy object to allow interaction with it +::method getObject unguarded -- request remote object, return a Rexx proxy object to allow interaction with it use strict arg busName, objectPath signal on syntax @@ -928,7 +1295,7 @@ -::method getObjectPaths -- return an array of object paths for the supplied bus name / service name +::method getObjectPaths unguarded -- return an array of object paths for the supplied bus name / service name use strict arg busName objectPathList=.array~new @@ -943,7 +1310,7 @@ -::method workerGetObjectPaths private -- interrogates service possessing bus/service name for object paths (if that service supports that) +::method workerGetObjectPaths unguarded private -- interrogates service possessing bus/service name for object paths (if that service supports that) use arg objPath, busName, objectPathList signal on syntax @@ -988,6 +1355,7 @@ +-- TODO: 201407 rgf /* ---------------------------------------------------------------------------------------- */ /* as of 2011-07-05 ooRexx from trunk does not support UTF-8, hence depending on BSF4ooRexx */ ::routine stringToUtf8 public -- needs BSF4ooRexx @@ -1021,6 +1389,7 @@ return out +-- TODO: 201407 rgf /* ---------------------------------------------------------------------------------------- */ ::routine utf8ToString public -- needs BSF4ooRexx parse arg str @@ -1033,12 +1402,12 @@ signal on syntax - res=dbusDataType(signature,"s") + res=dbusDataType(signature,"s") -- check whether valid DBus signature if res<>.true then raise syntax 93.900 array("'signature':" res) - return .array~of("useThisSignature="signature,argument) + return .array~of("useThisSignature="signature,argument) -- native code looks for "useThisSignature=" -- return .array~of("variantSignature="signature,argument) syntax: raise propagate @@ -1064,6 +1433,7 @@ expose proxy.busname proxy.connection proxy.objectPath proxy.methods proxy.introspectData use strict arg proxy.connection, proxy.busname, proxy.objectPath +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) proxy.introspectRootNode=.nil proxy.introspectData ="" @@ -1104,6 +1474,7 @@ ::method proxy.parseIntrospectData -- parse introspect data, memorize introspectData and introspectFileName, if any expose proxy.introspectData proxy.introspectFileName use strict arg introData +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) signal on syntax .ArgUtil~validateClass("introspectData", introData, .string) -- check for correct type @@ -1134,6 +1505,7 @@ ::METHOD proxy.dispatch -- allow sending messages that would be intercepted on the Rexx side (e.g. by .Object) parse arg methodName +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) -- create UNKNOWN format (first argument is unknown method name) self~unknown(methodName, arg(2, 'A')) if var('RESULT') then return result -- if a return value given, return it @@ -1143,6 +1515,7 @@ ::method unknown -- implements sending message calls to remote object expose proxy.busname proxy.connection proxy.objectPath proxy.methods use arg msgName, msgArgs +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) signal on syntax interface="" @@ -1231,15 +1604,16 @@ ::method init expose listenerObject interface signalName +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg listenerObject, interface=.nil, signalName=.nil ::attribute listenerObject ::attribute interface ::attribute signalName +-- TODO: 201407: Sebastian Margiol suggested to add an UNKNOWN method; but then programmers might not realize what else they get? - /* =============================================================================== */ /* Allows an ooRexx object to serve DBus method invocations in an easy manner, by adding the ability to e.g. dynamically determine replySignatures from the introspect @@ -1250,6 +1624,7 @@ ::method init -- intorData, service.connection, service.objectPath; introData may be supplied later, using the respective methods expose service.connections service.introspectRootNode service.methods +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) -- expose service.connection service.objectPath service.introspectRootNode service.methods -- use strict arg introData=.nil, service.connection=.nil, service.objectPath=.nil use strict arg introData=.nil @@ -1275,6 +1650,7 @@ ::method service.parseIntrospectData -- parse introspect data, memorize introspectData and introspectFileName, if any expose service.introspectData service.introspectFileName +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg introData signal on syntax @@ -1309,6 +1685,7 @@ ::method Introspect -- return introspection data to client expose service.introspectData +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) return dbus.box("s", service.introspectData) ::attribute service.connections /* object's connection to use */ @@ -1375,6 +1752,7 @@ ::method service.sendSignal -- utility method to ease emitting signals from the service object; -- will emit the signal to all connections this service object is registered with expose service.methods service.connections +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) -- expose service.methods service.connection service.objectPath use strict arg objectPath=.nil, interface="", member, ... @@ -1452,14 +1830,20 @@ /* service requests */ ::method unknown expose service.methods +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use arg msgName, msgArgs +-- call dump2 msgArgs, pp2(self)"::UNKNOWN" pp(msgName) - errorText='Object "'self'" does not understand message "'msgName'"' + errorText='Object"' self '"does not understand message "'msgName'"' slotDir=.nil if msgArgs~isA(.array), msgArgs~size>0 then + do slotDir=msgArgs[msgArgs~last] /* contains useful information about method invocation, like method name, method type, signature, etc. */ + if \slotDir~isA(.directory) then + slotDir=.nil + end /* if an org.freedesktop.DBus.Properties Get() or Set() invocation, reroute them to the respective Rexx attribute get/set */ @@ -1572,6 +1956,7 @@ */ ::routine DbusDataType public -- check or determine whether dbus datatype parse arg value, type . +if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax @@ -1872,16 +2257,19 @@ raise propagate -- raise in caller - +-- TODO: 201407: still .true ??? /* as of 2011-07-29: not yet implemented in full in native code, hence not operational */ /* =============================== DBusServer ====================================================== */ +-- TODO: 20140722 - which message loop to spawn and to control, just one, or multiples ? /* ------------------------------ class definition ------------------------------ */ ::class "DBusServer" public ::method init expose cself address allowAnonymous defaultService defaultListener connections - watchLoopActive watchlist timeoutLoopActive watchConnections +if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) + use strict arg address, defaultService=.nil, defaultListener=.nil, allowAnonymous=.false .ArgUtil~validateClass("address", address, .string) @@ -1901,19 +2289,24 @@ ::attribute cself /* native's representation of this dbus object, set in native code */ ::attribute address get -- address of the server + ::attribute allowAnonymous -- allow anonymous clients to connect ::attribute defaultService -- default Rexx service object, used, if no matching entry found in internalRegisteredServiceObjects ::attribute defaultListener -- default Rexx listener object, used, if internalSignalListeners is empty ::attribute connections get -- list of established connections expose connections +if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) return connections~copy -- return a copy of the current connections ::attribute watchLoopActive get -- indicates whether the server message loop is active or not ::method newConnection -- new connection to this server received (from native code) expose defaultService defaultListener connections watchConnections +if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg conn + conn~startMessageLoop -- TODO: rgf, 20140728 + -- signal on syntax -- say pp2(self)"::newConnection - just received a new connection conn="pp2(conn) "..." "defaultService~class="pp2(defaultService~class) @@ -1923,8 +2316,8 @@ if defaultService~isA(.DBusServiceObject) then do aCopy=defaultService~copy -- each DBusServiceObject keeps its own connection to its client - aCopy~service.connection=conn -- assign this connection - aCopy~service.objectpath=.nil -- make sure no object path + aCopy~service.connections~put(conn) -- assign this connection + -- aCopy~service.objectpath=.nil -- make sure no object path conn~serviceObject("add", "default", aCopy) -- will start message loop automatically end else -- plain object @@ -1938,10 +2331,12 @@ conn~listener("add", defaultListener) -- will start message loop automatically end + -- TODO: rgf, temporarily disable, 28.7.2014 if watchConnections=.false then -- start the watchConnections thread self~watchConnections -- say pp2(self)"::newConnection - conn~messageLoop('active'):" pp2(conn~messageLoop('active')) +-- say pp2(self)"::newConnection - conn~messageLoop('active'):" pp2(conn~active) -- say pp2(self)"::newConnection -" pp2(conn) "about to leave." return @@ -1953,63 +2348,85 @@ */ +-- TODO: really to start/stop message loop ? ::method disconnect -- invoked from native code (not reliably invoked all the time as of 1.6.4 on Ubuntu) expose connections +if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg conn -- say "..." self"::disconnect, 'conn'="pp2(conn) - conn~messageLoop("stop") -- stop the connection's message loop +-- conn~messageLoop("stop") -- stop the connection's message loop + conn~close -- make sure we cannot use it anymore (it wouldn't work) res=connections~removeItem(conn) -- remove the disconnected connection from the client - conn~close -- make sure we cannot use it anymore (it wouldn't work) -::method nativeStartServerWatchLoop private external "LIBRARY dbusoorexx DbusServerWatchLoop" -::method nativeServerStartup private external "LIBRARY dbusoorexx DbusNativeServerStartup" +::method nativeServerWatchLoop private external "LIBRARY dbusoorexx DbusServerWatchLoop" +::method nativeServerStartup private external "LIBRARY dbusoorexx DbusNativeServerStartup" ::method startup unguarded -- startup server expose allowAnonymous cself address +if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) if cself<>.nil then raise syntax 93.900 array (self": server was already started") -- return self~nativeServerID -- say "address:" pp2(address) "cself="pp2(cself) +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "about to: self~nativeServerStartup" self~nativeServerStartup(address) -- create server listening on given address reply -- create a new thread - self~nativeStartServerWatchLoop -- start the server message loop on the new thread +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "BEFORE: self~nativeServerWatchLoop" + self~nativeServerWatchLoop -- start the server message loop on the new thread +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "AFTER : self~nativeServerWatchLoop" -- as of DBus 1.4.14, the private server does not receive a "Disconnected" signal ::method watchConnections unguarded -- check whether client connections are available, if not disconnect the stalled connecition expose connections watchConnections +if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg sleepTime=.1 -- check every 1/10 second +-- TODO: rgf, make sleepTime higher to not disturb debug output +sleepTime=1 -- try every second + + guard on watchConnections=.true -- indicate that the watch Connections thread is started guard off +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "before reply" reply -- say "... ... probing" pp2(conn) "sleepTime:" pp2(sleepTime) "..." +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "after reply, BEFORE: entering the loop" signal on halt do forever while connections~items>0 -- as long as client connections, probe them +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(s... [truncated message content] |
From: <or...@us...> - 2014-08-01 14:44:31
|
Revision: 228 http://sourceforge.net/p/bsf4oorexx/code/228 Author: orexx Date: 2014-08-01 14:44:27 +0000 (Fri, 01 Aug 2014) Log Message: ----------- 20140801 Added ReleaseLocalReference()-statements. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc sandbox/rgf/misc/dbusoorexx/examples/demoHelloClient.rex sandbox/rgf/misc/dbusoorexx/examples/demoHelloService1.rex sandbox/rgf/misc/dbusoorexx/examples/demoHelloService2.rex sandbox/rgf/misc/dbusoorexx/examples/demoHelloService3.rex sandbox/rgf/misc/dbusoorexx/examples/helloWorld.rex sandbox/rgf/misc/dbusoorexx/examples/margiolKate.rex sandbox/rgf/misc/dbusoorexx/examples/margiolVLC.rex sandbox/rgf/misc/dbusoorexx/examples/signalListener.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/a_PrivateClient.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/a_PrivateServer.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateClientPingSimple.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPong.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/c_PrivatePropertiesClientPing.rex sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/c_PrivatePropertiesServerPong.rex Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-07-30 18:01:28 UTC (rev 227) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-08-01 14:44:27 UTC (rev 228) @@ -82,9 +82,10 @@ - make sure that all connection related interactions with DBus occurs only in the thread that was used to connect to DBus; this implies that stopping a message loop causes that connection to be not usable from - ooRexx anymore! + ooRexx anymore, hence method messageLoop() gets deprecated! - if an error condition is raised in the message loop thread, it will get re-raised on the blocked thread upon return + - added public routine DBusVersion() which includes the library and this package version license: Apache License 2.0 @@ -113,8 +114,8 @@ */ .local~dbus.dir=.directory~new -.dbus.dir~bDebug=.false -- .true -.dbus.dir~bDebugServer=.false -- .true +.dbus.dir~bDebug=.false -- .true -- .false -- .true +.dbus.dir~bDebugServer=.false -- .true -- .false -- .true .dbus.dir~version="100.20140730" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' @@ -217,7 +218,8 @@ /* --- class methods ------ */ -- TODO: 201407 rgf ::method init class - expose system session + expose system session tid2human + tid2human=.directory~new -- attribute that allows to translate TIDs into human readable form system=.nil session=.nil @@ -226,14 +228,37 @@ -- instead use public routine "DbusVersion()" -- ::method version class external "LIBRARY dbusoorexx DbusGetVersion" + -- will be usually called from native DbusGetTID(), which allows one optional argument indicating the desired formatting +::method formatTID unguarded class -- unguarded (access to tid2human only in here) + expose tid2human + use strict arg tid, option="H" + parse upper var option opt +1 -- "H[uman]", "S[ystem]", "A[ll]" + signal on syntax + if pos(opt,"HSA")=0 then + raise syntax 88.916 array ('"option"', '"H[uman]", "S[ystem]", "A[ll]"', option) + + if \tid2human~hasIndex(tid) then + tid2human[tid]="thread" (tid2human~items+1) -- generate a human readable form and save it + + select + when opt="H" then return tid2human[tid] + when opt="S" then return tid + otherwise return tid2human[tid]"/"tid + end + return + +syntax: raise propagate + + + /* unique id for the computer */ ::method machineID class external "LIBRARY dbusoorexx DbusGetUniqueMachineId" -- TODO: 201407 rgf ::method system class /* returns the shared system bus connection */ expose system -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "arg(1):" pp(arg(1)) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "arg(1):" pp(arg(1)) if arg(1)="CLEAR", arg(2)=system then -- remove cached connection to force a new one to be created do @@ -249,7 +274,7 @@ -- TODO: 201407 rgf ::method session class /* returns the shared session bus connection */ expose session -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "arg(1):" pp(arg(1)) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "arg(1):" pp(arg(1)) if arg(1)="CLEAR", arg(2)=session then -- remove cached connection to force a new one to be created do @@ -267,7 +292,7 @@ ::method connect class /* connect to an existing dbus connection */ -- use strict arg address -- "address" can also be "system", "session" -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) forward message ("NEW") -- let our version of NEW handle this @@ -276,7 +301,7 @@ expose system session use strict arg address -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) bus=self~new:.class -- return barely initialized @@ -338,7 +363,7 @@ collectStatistics statistics server sendEmptyReply - haltAllThreadsOnUnexpectedError -if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) +if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) cself=.nil /* will be set by a native method */ busType=.nil /* will be set by native method */ @@ -386,7 +411,7 @@ ::method connectToAddress -- unguarded expose active -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) forward message (connectToAddress"_worker") continue guard on when active=.true -- block (wait) until message queue is running, otherwise we get lock-ups @@ -395,11 +420,11 @@ */ ::method connectToAddress_worker -- rgf, 20140722 expose active address -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) if active=.true then return -- message loop already up and running reply -- start a new thread which will start the message loop and block -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "after reply" +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "after reply" use arg address -- get desired address if address="session" then @@ -522,7 +547,7 @@ ::method startMessageLoop unguarded expose active stopLoop address busType -- expose stopLoop address busType -if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "arrived" +if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "arrived" signal on syntax -- TODO: rgf, 20140728: if public then raise an error, if attempting to start a running messageLoop @@ -546,9 +571,9 @@ reply -- start a new thread and start message loop -if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "BEFORE: self~nativeStartMessageLoop" +if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "BEFORE: self~nativeStartMessageLoop" self~nativeStartMessageLoop -- start message loop -if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "AFTER : self~nativeStartMessageLoop" +if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "AFTER : self~nativeStartMessageLoop" return syntax: raise propagate @@ -559,7 +584,7 @@ expose active stopLoop bustype parse upper arg action . -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "action:" pp(action) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "action:" pp(action) msg="Method [messageLoop] not available anymore! 'start' is done at connection creation time," msg=msg"'stop' is done in new method 'close', 'active' is replaced by the get attribute named 'active'," @@ -652,7 +677,7 @@ ::method close -- unguarded -- close (private) connection expose busType address statistics active stopLoop -if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) +if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) -- TODO: ?if stopLoop=.true, then already closed, raise syntax error? if active=.false then return -- nothing to close anymo @@ -669,7 +694,7 @@ if busType="private" then -- if a private connection, then truly close it do -if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "==> busType="pp(busType) "address="pp(address) "about to close connection!" +if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "==> busType="pp(busType) "address="pp(address) "about to close connection!" self~nativeCloseConnection -- close the connection for good, will set CSELF to .nil end @@ -688,7 +713,7 @@ ::method query unguarded -- reroute invocation through message loop thread expose active stopLoop address bustype - if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax parse upper arg option +1 1 option3 +3 . -- get first char and first three chars in uppercase @@ -806,7 +831,7 @@ ::method uninit -- make sure we stop the message loop thread, if necessary expose busType active -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "#1 (kick off loop)" +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "#1 (kick off loop)" -- if cself<>.nil then -- a DBUS connection pointer in hand ? if active=.true then -- is the message loop still active for this connection ? @@ -1009,7 +1034,7 @@ ::method nativeUniqueBusID private external "LIBRARY dbusoorexx DbusGetUniqueBusId" ::method uniqueBusID expose stopLoop address bustype - if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) if stopLoop=.true then -- message loop got already stopped, we do not allow to restart it, a new conncection needs to be established do @@ -1046,7 +1071,7 @@ ::method busName -- route invocation through the message loop thread expose stopLoop address bustype - if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) if stopLoop=.true then -- message loop got already stopped, we do not allow to restart it, a new conncection needs to be established do @@ -1138,7 +1163,7 @@ */ ::method match -- reroute invocation through message loop thread expose stopLoop address bustype - if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "/// arg(5):" pp(arg(5)) + if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "/// arg(5):" pp(arg(5)) if stopLoop=.true then -- message loop got already stopped, we do not allow to restart it, a new conncection needs to be established do @@ -1186,7 +1211,7 @@ /* folding methods of the "message" group into one parametrized method */ ::method message -- send message to service object; reroute invocation through message loop thread expose stopLoop address bustype - if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "/// arg(5):" pp(arg(5)) + if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "/// arg(5):" pp(arg(5)) if stopLoop=.true then -- message loop got already stopped, we do not allow to restart it, a new conncection needs to be established do @@ -1209,7 +1234,7 @@ expose cself active use strict arg function, ... - if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax @@ -1425,6 +1450,12 @@ syntax: raise propagate + /* ---------------------------------------------------------------------------------------- */ +/* return the version information that includes the library version and this package's version */ +::routine DBusVersion public + return DBusVersionLibrary()", package dbus.cls=[".dbus.dir~version"]" + + /* =============================================================================== */ /* ooRexx proxy for a DBus object, responsible for processing messages */ ::class "DBusProxyObject" public @@ -1433,7 +1464,7 @@ expose proxy.busname proxy.connection proxy.objectPath proxy.methods proxy.introspectData use strict arg proxy.connection, proxy.busname, proxy.objectPath -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) proxy.introspectRootNode=.nil proxy.introspectData ="" @@ -1474,7 +1505,7 @@ ::method proxy.parseIntrospectData -- parse introspect data, memorize introspectData and introspectFileName, if any expose proxy.introspectData proxy.introspectFileName use strict arg introData -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax .ArgUtil~validateClass("introspectData", introData, .string) -- check for correct type @@ -1505,7 +1536,7 @@ ::METHOD proxy.dispatch -- allow sending messages that would be intercepted on the Rexx side (e.g. by .Object) parse arg methodName -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) -- create UNKNOWN format (first argument is unknown method name) self~unknown(methodName, arg(2, 'A')) if var('RESULT') then return result -- if a return value given, return it @@ -1515,7 +1546,7 @@ ::method unknown -- implements sending message calls to remote object expose proxy.busname proxy.connection proxy.objectPath proxy.methods use arg msgName, msgArgs -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax interface="" @@ -1604,7 +1635,7 @@ ::method init expose listenerObject interface signalName -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg listenerObject, interface=.nil, signalName=.nil ::attribute listenerObject @@ -1624,7 +1655,7 @@ ::method init -- intorData, service.connection, service.objectPath; introData may be supplied later, using the respective methods expose service.connections service.introspectRootNode service.methods -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) -- expose service.connection service.objectPath service.introspectRootNode service.methods -- use strict arg introData=.nil, service.connection=.nil, service.objectPath=.nil use strict arg introData=.nil @@ -1650,7 +1681,7 @@ ::method service.parseIntrospectData -- parse introspect data, memorize introspectData and introspectFileName, if any expose service.introspectData service.introspectFileName -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg introData signal on syntax @@ -1685,7 +1716,7 @@ ::method Introspect -- return introspection data to client expose service.introspectData -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) return dbus.box("s", service.introspectData) ::attribute service.connections /* object's connection to use */ @@ -1752,7 +1783,7 @@ ::method service.sendSignal -- utility method to ease emitting signals from the service object; -- will emit the signal to all connections this service object is registered with expose service.methods service.connections -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) -- expose service.methods service.connection service.objectPath use strict arg objectPath=.nil, interface="", member, ... @@ -1830,7 +1861,7 @@ /* service requests */ ::method unknown expose service.methods -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use arg msgName, msgArgs -- call dump2 msgArgs, pp2(self)"::UNKNOWN" pp(msgName) @@ -1956,7 +1987,7 @@ */ ::routine DbusDataType public -- check or determine whether dbus datatype parse arg value, type . -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) signal on syntax @@ -2268,7 +2299,7 @@ ::method init expose cself address allowAnonymous defaultService defaultListener connections - watchLoopActive watchlist timeoutLoopActive watchConnections -if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg address, defaultService=.nil, defaultListener=.nil, allowAnonymous=.false @@ -2295,14 +2326,14 @@ ::attribute defaultListener -- default Rexx listener object, used, if internalSignalListeners is empty ::attribute connections get -- list of established connections expose connections -if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) return connections~copy -- return a copy of the current connections ::attribute watchLoopActive get -- indicates whether the server message loop is active or not ::method newConnection -- new connection to this server received (from native code) expose defaultService defaultListener connections watchConnections -if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg conn conn~startMessageLoop -- TODO: rgf, 20140728 @@ -2351,7 +2382,7 @@ -- TODO: really to start/stop message loop ? ::method disconnect -- invoked from native code (not reliably invoked all the time as of 1.6.4 on Ubuntu) expose connections -if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg conn -- say "..." self"::disconnect, 'conn'="pp2(conn) @@ -2364,27 +2395,27 @@ ::method nativeServerStartup private external "LIBRARY dbusoorexx DbusNativeServerStartup" ::method startup unguarded -- startup server expose allowAnonymous cself address -if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) if cself<>.nil then raise syntax 93.900 array (self": server was already started") -- return self~nativeServerID -- say "address:" pp2(address) "cself="pp2(cself) -if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "about to: self~nativeServerStartup" +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "about to: self~nativeServerStartup" self~nativeServerStartup(address) -- create server listening on given address reply -- create a new thread -if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "BEFORE: self~nativeServerWatchLoop" +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "BEFORE: self~nativeServerWatchLoop" self~nativeServerWatchLoop -- start the server message loop on the new thread -if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "AFTER : self~nativeServerWatchLoop" +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "AFTER : self~nativeServerWatchLoop" -- as of DBus 1.4.14, the private server does not receive a "Disconnected" signal ::method watchConnections unguarded -- check whether client connections are available, if not disconnect the stalled connecition expose connections watchConnections -if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) use strict arg sleepTime=.1 -- check every 1/10 second -- TODO: rgf, make sleepTime higher to not disturb debug output @@ -2394,39 +2425,39 @@ guard on watchConnections=.true -- indicate that the watch Connections thread is started guard off -if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "before reply" +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "before reply" reply -- say "... ... probing" pp2(conn) "sleepTime:" pp2(sleepTime) "..." -if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "after reply, BEFORE: entering the loop" +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "after reply, BEFORE: entering the loop" signal on halt do forever while connections~items>0 -- as long as client connections, probe them -if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "about to sleep" pp(sleepTime) "secs ..." +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "about to sleep" pp(sleepTime) "secs ..." call sysSleep sleepTime -- sleep -if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "awoke, connections~items="pp2(connections~items) +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "awoke, connections~items="pp2(connections~items) guard on arr=connections~copy -- get a copy of all connections guard off do conn over arr -- iterate over all client connections and probe them -- say "... ... testing" pp2(conn)": conn~isOpen:" pp2(conn~isOpen) "..." -if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "conn~query('open': --> before, conn="pp2(conn) conn~query('open') +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "conn~query('open': --> before, conn="pp2(conn) conn~query('open') if conn~query("open")=.false then do -- say "... ... BINGO! " pp2(conn) "not connected/open anymore, DISCONNECTing connection !" -if .dbus.dir~bDebugServer=.true then say "!!!" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "conn~query('open': --> DISCONNECTING conn="pp2(conn) +if .dbus.dir~bDebugServer=.true then say "!!!" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "conn~query('open': --> DISCONNECTING conn="pp2(conn) self~disconnect(conn) -- disconnect will remove closed conn from connections ! end end end -if .dbus.dir~bDebugServer=.true then say "\\\" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "about to GUARD ON, to prepare to leave ..." +if .dbus.dir~bDebugServer=.true then say "\\\" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "about to GUARD ON, to prepare to leave ..." guard on watchConnections=.false guard off -if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(bsfGetTid()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "AFTER, about to return from method" +if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "AFTER, about to return from method" return halt: -- a HALT condition, make sure all known connections get closed @@ -2443,7 +2474,7 @@ ::method nativeStartServerTimeoutLoop private external "LIBRARY dbusoorexx DbusServerTimeoutLoop" ::method timerLoop unguarded -- "START" or "STOP" expose timeoutLoopActive -if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) parse upper arg action +3 if action="STO" then @@ -2471,7 +2502,7 @@ ::method nativeServerShutdown private external "LIBRARY dbusoorexx DbusNativeServerDisconnect" ::method shutdown unguarded -- shutdown server expose connections cself watchLoopActive -if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) -- say "..." .dateTime~new " arrived in shutdown, cself="pp2(cself) "..." -- say "."~copies(50) @@ -2495,7 +2526,7 @@ ::method nativeServerID private external "LIBRARY dbusoorexx DbusNativeServerGetId" ::method serverID expose cself -if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) if cself=.nil then return .nil return self~nativeServerID @@ -2503,7 +2534,7 @@ ::method nativeActive private external "LIBRARY dbusoorexx DbusNativeServerIsActive" ::method active expose cself -if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) if cself=.nil then return .false return self~nativeActive @@ -2511,7 +2542,7 @@ ::method nativeServerAddress private external "LIBRARY dbusoorexx DbusNativeServerGetAddress" ::method serverAddress expose cself -if .dbus.dir~bDebugServer=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) if cself=.nil then return .nil return self~nativeServerAddress @@ -3395,7 +3426,7 @@ ::method init expose queuedMessages queuedMessages=.queue~new - if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "WORKER" + if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "WORKER" forward class (super) @@ -3406,7 +3437,7 @@ ::method executeQueuedMessages expose queuedMessages --- if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "queuedMessages:" pp(queuedMessages~items) +-- if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "queuedMessages:" pp(queuedMessages~items) signal on any -- trap any error condition to allow us to re-raise any of the trappable conditions in the blocked thread later @@ -3424,7 +3455,7 @@ any: -- say "... executeQueuedMessages, ANY condition:" condition("C") workerMessage~hasError=.true -- indicate an error, unblock waitForDone -if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "queuedMessages:" pp(queuedMessages~items) "SIGNAL ANY received, flagging workerMessage as error in execution..." +if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "queuedMessages:" pp(queuedMessages~items) "SIGNAL ANY received, flagging workerMessage as error in execution..." /** This method aborts all queued messages, setting the attribute <code>isAborted</code> @@ -3432,7 +3463,7 @@ */ ::method abortQueuedMessages expose queuedMessages - if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) do while queuedMessages~items>0 workerMessage=queuedMessages~pull -- pull workerMessage object @@ -3466,7 +3497,7 @@ ::method postMessage unguarded expose queuedMessages use strict arg message - if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) + if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) .ArgUtil~validateClass("message", message, .Message) -- check for correct type workMsg=.WorkerMessage~new(message) @@ -3556,7 +3587,7 @@ ::method init expose cancel hasResult isAborted isDone message hasError use strict arg message - if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "WORKERMESSAGE" + if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "WORKERMESSAGE" .ArgUtil~validateClass("message", message, .Message) -- check for correct type cancel=.false -- allow to cancel sending/processing message isAborted=.false -- message was aborted @@ -3595,10 +3626,10 @@ */ ::method waitForDone unguarded expose cancel isAborted isDone hasError message - if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "before blocking" pp(self~identityHash) + if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "before blocking" pp(self~identityHash) guard on when isDone=.true | cancel=.true | isAborted=.true | hasError=.true - if .dbus.dir~bDebug=.true then say pp(bsfGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "after blocking " pp(self~identityHash) + if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "after blocking " pp(self~identityHash) signal on syntax if isAborted=.true then Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-07-30 18:01:28 UTC (rev 227) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-08-01 14:44:27 UTC (rev 228) @@ -39,10 +39,11 @@ errors (e.g. no results delivered from messages, DBus inable to fetch replies etc.) may occur 2014-07-27, rgf: - marshalling and unmarshalling of dictionaries with multiple entries fixed + 2014-07-31, rgf: - added routine DbusGetTID() to ease debugging - version: 100.20140730 + version: 100.20140801 license: Apache License 2.0 ------------------------ Apache Version 2.0 license ------------------------- @@ -62,7 +63,8 @@ ----------------------------------------------------------------------------- */ -// TODO: 2014-07, rgf: check for need of executing ReleaseLocalReference() ! +// TODO: 2014-07, rgf: - check for need of executing ReleaseLocalReference() ! +// - store ooRexx classes ARRAY, DATETIME, DBUS in global constants instead #ifdef __cplusplus @@ -126,11 +128,11 @@ #ifdef DBUSOOREXX_32 - #define DBUS_REXXVERSION "100.20140730 32-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20140801 32-bit" // version: "MajorNumber"."YYYYMMDD" #elif defined (DBUSOOREXX_64) - #define DBUS_REXXVERSION "100.20140730 64-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20140801 64-bit" // version: "MajorNumber"."YYYYMMDD" #else - #define DBUS_REXXVERSION "100.20140730 n/a-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20140801 n/a-bit" // version: "MajorNumber"."YYYYMMDD" #endif #ifndef TID @@ -144,6 +146,7 @@ #define REXX_LOADER // needed for dbus_threads_init_default(), cf. <http://dbus.freedesktop.org/doc/api/html/group__DBusThreads.html#ga33b6cf3b8f1e41bad5508f84758818a7> +// TODO: 2014-07, rgf: remove auto-disconnect-code! // if defined, then a "Disconnected" signal on a private server's client connection will // cause a "disconnect" message to be sent to the private server automatically // as of 2011-09-12 (DBus 1.5.7) the "Disconnected" signal is not sent on private server connections; @@ -151,7 +154,9 @@ // hence the following def is not really needed // #define REXX_AUTO_DISCONNECT_FROM_PRIVATE_SERVER +#define DEBUG_OOREXX_FIND_CLASS + // #define DEBUG_RGF // for temporary debug output // #define DEBUG_MESSAGELOOP @@ -217,6 +222,8 @@ #define MALLOC_USE_REXX // 2011-06-26: originally defined to trace down a segmentation fault using dbus' malloc, test using Rexx allocations +const size_t RGF_TID_STRING_WIDTH = 80; // allows for hex representation of 2**128 plus two bytes (one for \0, the other for evening) + // structure to ease argument passing while marshalling the Rexx arguments for DBUS typedef struct _STRUCT_MARSHAL { RexxThreadContext *context; // allow interaction with ooRexx @@ -507,7 +514,7 @@ // ******************************************************************** // get and return various version information as a string -RexxRoutine0(RexxStringObject, DbusVersion) +RexxRoutine0(RexxStringObject, DbusVersionLibrary) { #ifdef RGF_INFO fprintf(stderr, "*** RGF_INFO: DbusVersion() 1, version=[%.256s] ...\n", DBUS_REXXVERSION); @@ -518,7 +525,7 @@ dbus_get_version(&major, &minor, µ); char msg[256]=""; // buffer for error message - SNPRINTF(msg, 256, "%s=[%s], compile-time dbus=[%s], runtime dbus=[%d.%d.%d]", + SNPRINTF(msg, 256, "library %s=[%s], compile-time dbus=[%s], runtime dbus=[%d.%d.%d]", DLLNAME, DBUS_REXXVERSION, DBUS_VERSION_STRING, major, minor, micro ); @@ -527,6 +534,38 @@ } + // ---rgf, 2003-08-06: allow Rexx to retrieve its TID (i.e. Java's "JNIEnv" object) +RexxRoutine1(RexxStringObject, DbusGetTID, OPTIONAL_CSTRING, option) // 20090505, ---rgf, only a stub for backward compatibility +{ +#ifdef UNIX + pthread_t +#else // WIN32 + TID +#endif + tid=RgfGetTID(); + + char *strTid=new char[RGF_TID_STRING_WIDTH]; // create buffer + SNPRINTF( strTid, RGF_TID_STRING_WIDTH, "%lu%c", ((unsigned long) tid), 0); // create decimal number + +#ifdef RGF_INFO + fprintf(stderr, "*** RGF_INFO: DbusGetTID() 1, tid=[%lu], %%s=[%s] ...\n", (unsigned long) tid, strTid); + fflush(stderr); +#endif + + RexxStringObject rso=context->String(strTid); + delete[] strTid; // free buffer + + RexxClassObject rco=context->FindContextClass("DBUS"); // get class + RexxStringObject rsoOption=context->String(option==NULL ? "H" : option ); + RexxStringObject rsoFormatted=(RexxStringObject) context->SendMessage2(rco, "FORMATTID", rso, rsoOption); // get DBus (bus connection) object + + + return rsoFormatted; +} + + + + // external Rexx function for validating values; as DBUS 1.4.x only supports validating signatures, // initially only signatures get evaluated // @@ -579,6 +618,10 @@ } + + + + // ******************************************************************** // * --- Methods --- * // ******************************************************************** @@ -1091,6 +1134,10 @@ RexxObjectPtr arg1= context->NewString("L",1); RexxObjectPtr arg2= context->NewString(",",1); RexxObjectPtr rop = context->SendMessage2(arrIdx, "MAKESTRING", arg1, arg2); + + context->ReleaseLocalReference(arg1); + context->ReleaseLocalReference(arg2); + return context->ObjectToStringValue(rop); } @@ -1101,11 +1148,15 @@ { RexxObjectPtr ropLevel=context->Int32ToObject(dimension); + // flag=context->ObjectToStringSize(context->SendMessage1(rao, "DIMENSION", ropLevel), &val); + RexxObjectPtr ropDim=context->SendMessage1(rao, "DIMENSION", ropLevel); + // logical_t flag; size_t val=0; - // logical_t flag; + context->ObjectToStringSize(ropDim, &val); - // flag=context->ObjectToStringSize(context->SendMessage1(rao, "DIMENSION", ropLevel), &val); - context->ObjectToStringSize(context->SendMessage1(rao, "DIMENSION", ropLevel), &val); + context->ReleaseLocalReference(ropLevel); + context->ReleaseLocalReference(ropDim); + return val; } @@ -1157,7 +1208,12 @@ { RexxClassObject dtClz=context->FindClass("DATETIME"); // get the DateTime class RexxObjectPtr dt =context->SendMessage0(dtClz, "NEW"); // get an instance - return context->ObjectToString(dt); // return string rendering + RexxStringObject res=context->ObjectToString(dt); + + context->ReleaseLocalReference(dtClz); + context->ReleaseLocalReference(dt); + + return res; // return string rendering } // -------------------------------------------------------------------------------- @@ -1177,8 +1233,12 @@ if (rop!=NULL) { // flag=context->ObjectToStringSize(context->ArrayAt(arrIdx, index), &val); - context->ObjectToStringSize(context->ArrayAt(arrIdx, index), &val); + RexxObjectPtr ropVal=context->ArrayAt(arrIdx, index); + context->ObjectToStringSize(ropVal, &val); + context->ReleaseLocalReference(ropVal); } + + context->ReleaseLocalReference(rop); return val; } @@ -1186,7 +1246,12 @@ // convenience inline function to set the index array to the desired value inline void SET_ARRAY_IDX(RexxArrayObject arrIdx, size_t idx, size_t numVal, RexxThreadContext *context) { - context->ArrayPut(arrIdx, context->StringSizeToObject(numVal), idx); + // context->ArrayPut(arrIdx, context->StringSizeToObject(numVal), idx); + + RexxObjectPtr rop=context->StringSizeToObject(numVal); + context->ArrayPut(arrIdx, rop, idx); + context->ReleaseLocalReference(rop); + } // -------------------------------------------------------------------------------- @@ -1536,10 +1601,16 @@ for (size_t tmpIdx=1;tmpIdx<=nrDims;tmpIdx++) { - pmarsh->context->ArrayAppend(rxWithArgs, pmarsh->context->ArrayAt(arrIdx, tmpIdx)); + // pmarsh->context->ArrayAppend(rxWithArgs, pmarsh->context->ArrayAt(arrIdx, tmpIdx)); + RexxObjectPtr rop=pmarsh->context->ArrayAt(arrIdx, tmpIdx); + pmarsh->context->ArrayAppend(rxWithArgs, rop); + pmarsh->context->ReleaseLocalReference(rop); } - currRexxObj=pmarsh->context->SendMessage2(pmarsh->arrayClass, "SENDWITH", pmarsh->context->String("NEW"), rxWithArgs); + // currRexxObj=pmarsh->context->SendMessage2(pmarsh->arrayClass, "SENDWITH", pmarsh->context->String("NEW"), rxWithArgs); + RexxStringObject rso=pmarsh->context->String("NEW"); + currRexxObj=pmarsh->context->SendMessage2(pmarsh->arrayClass, "SENDWITH", rso, rxWithArgs); + pmarsh->context->ReleaseLocalReference(rso); #ifdef DEBUG_ARRAY // fprintf(stderr, " unmarshal(...), 'a' - currRexxObj=[%p]~dimension=[%zu]; pmarsh->dimensions=[%zu] - nrDims=[%zu]; | ~size=[%zu], ~items=[%zu]\n", @@ -1589,6 +1660,10 @@ RexxObjectPtr tmpObj=pmarsh->context->ArrayAt((RexxArrayObject)currRexxObj, 1); if (tmpObj!=NULL) // if no entry == NULL, then return currRexxObj { + if (currRexxObj!=NULLOBJECT) + { + pmarsh->context->ReleaseLocalReference(currRexxObj); + } currRexxObj=tmpObj; } @@ -1600,6 +1675,9 @@ #endif } + pmarsh->context->ReleaseLocalReference(arrIdx); + pmarsh->context->ReleaseLocalReference(rxWithArgs); + // move cursor to next char in signature pmarsh->cursor=pmarsh->elementEnd+1; // let us point to the next typeCode if any } @@ -1741,6 +1819,10 @@ ); #endif + + pmarsh->context->ReleaseLocalReference(currRexxObj); + + // check for errors, return with false, if any pmarsh->dbusError=(resDbus==0); // a dbus-error occurred ? pmarsh->rexxError=(orxConvFlag==false); // a Rexx conversion error occurred ? @@ -1861,6 +1943,7 @@ // create an empty directory, append it, return RexxDirectoryObject rdo=pmarsh->context->NewDirectory(); pmarsh->context->SendMessage2(rao, "PUT", rdo, arrIdx); // save "ay" as "s" at its position + pmarsh->context->ReleaseLocalReference(rdo); } @@ -1917,11 +2000,20 @@ // adjust index array (to not have too many dimensions!) if (pmarsh->context->ArraySize(arrIdx)>nrDims) { + // arrIdx=(RexxArrayObject) pmarsh->context->SendMessage2(arrIdx, "SECTION", + // pmarsh->context->String("1"), + // pmarsh->context->StringSizeToObject(nrDims) ); - arrIdx=(RexxArrayObject) pmarsh->context->SendMessage2(arrIdx, "SECTION", - pmarsh->context->String("1"), - pmarsh->context->StringSizeToObject(nrDims) ); + RexxObjectPtr rop1=pmarsh->context->String("1"); + RexxObjectPtr rop2=pmarsh->context->StringSizeToObject(nrDims); + RexxArrayObject tmpRao=(RexxArrayObject) pmarsh->context->SendMessage2(arrIdx, "SECTION", rop1, rop2); + pmarsh->context->ReleaseLocalReference(arrIdx); + arrIdx=tmpRao; + + pmarsh->context->ReleaseLocalReference(rop1); + pmarsh->context->ReleaseLocalReference(rop2); + #ifdef DEBUG_ARRAY // fprintf(stderr, " unmarshalArray(...): must adjust arrIdx (too many indices!), now arrIdx=[%s] as nrDims=[%zu] \n ", fprintf(stderr, " unmarshalArray(...): must adjust arrIdx (too many indices!), now arrIdx=[%s] as nrDims=[%lu] \n ", @@ -1937,10 +2029,16 @@ if (arrCount>0) // byte array was read { + if (tmpObj!=NULLOBJECT) + { + pmarsh->context->ReleaseLocalReference(tmpObj); + } if (pmarsh->is_ay && pmarsh->unmarshal_ay_as_string) // turn byte array into string { tmpObj=pmarsh->context->String(array, arrCount); // turn into Rexx string pmarsh->context->SendMessage2(rao, "PUT", tmpObj, arrIdx); // save "ay" as "s" at its position + pmarsh->context->ReleaseLocalReference(tmpObj); + } else // create a Rexx array with individual bytes { @@ -1953,6 +2051,7 @@ #endif tmpObj=pmarsh->context->String((CSTRING)array+i-1, 1); // extract byte and turn it into a Rexx string pmarsh->context->SendMessage2(rao, "PUT", tmpObj, arrIdx); // save "ay" as "s" at its position + pmarsh->context->ReleaseLocalReference(tmpObj); } } } @@ -2050,6 +2149,7 @@ SET_ARRAY_IDX(arrIdx, level, 1, pmarsh->context); // add 1 to maximum items pmarsh->context->SendMessage2(rao, "PUT", dirRexxObj, arrIdx); + pmarsh->context->ReleaseLocalReference(dirRexxObj); #ifdef DEBUG_ARRAY fprintf(stderr, " /<-- unmarshalArray(): DBUS_TYPE_ARRAY - dirRexxObj=[%p] stored at arrIdx=[%s], branch 'DICT ARRAY', done. \n", @@ -2080,7 +2180,9 @@ fprintf(stderr, "----> Ticker # 7b, about to put value=[%s] at arrIdx=[%s] \n", pmarsh->context->ObjectToStringValue(pmarsh->context->ArrayAt(tmpArr,1)), currArrIdx); #endif - pmarsh->context->SendMessage2(rao, "PUT", pmarsh->context->ArrayAt(tmpArr,1), arrIdx); + // pmarsh->context->SendMessage2(rao, "PUT", pmarsh->context->ArrayAt(tmpArr,1), arrIdx); + RexxObjectPtr rop=pmarsh->context->ArrayAt(tmpArr,1); + pmarsh->context->SendMessage2(rao, "PUT", rop, arrIdx); #ifdef DEBUG_ARRAY fprintf(stderr, "----> Ticker # 7c, stored value [%s] at arrIdx=[%s] \n", @@ -2095,6 +2197,9 @@ (unsigned long) (localM.elementStart - localM.signature) ); #endif + pmarsh->context->ReleaseLocalReference(rop); + pmarsh->context->ReleaseLocalReference(tmpArr); + localM.cursor=localM.signature; // reset cursor } } @@ -2283,13 +2388,29 @@ fflush(stderr); #endif // add to directory - pmarsh->context->SendMessage2(rxMap, "PUT", - (pmarsh->context->ArrayItems(item)==1 ? - pmarsh->context->ArrayAt(item,1) : - item - ), - pmarsh->context->ArrayAt(key,1) - ); +// pmarsh->context->SendMessage2(rxMap, "PUT", +// // (pmarsh->context->ArrayItems(item)==1 ? +// pmarsh->context->ArrayAt(item,1) : +// item +// ), +// pmarsh->context->ArrayAt(key,1) +// ); +// + RexxObjectPtr ropKey=pmarsh->context->ArrayAt(key,1); + if (pmarsh->context->ArrayItems(item)==1) + { + RexxObjectPtr ropItem=pmarsh->context->ArrayAt(item,1); + pmarsh->context->SendMessage2(rxMap, "PUT", ropItem, ropKey); + pmarsh->context->ReleaseLocalReference(ropItem); + } + else + { + pmarsh->context->SendMessage2(rxMap, "PUT", item, ropKey); + } + + pmarsh->context->ReleaseLocalReference(key); + pmarsh->context->ReleaseLocalReference(item); + pmarsh->context->ReleaseLocalReference(ropKey); } #if defined (DEBUG_DICT) && defined (DEBUG_UNMARSHAL) @@ -2979,6 +3100,7 @@ *pmarsh->elementStart=='y'); // type BYTE ? RexxArrayObject rao=NULL; + bool bReleaseLocalReferenceRao=false; if (bRopIsNull) // o.k. Rexx argument not available, supply another empty Rexx array as argument array { @@ -2988,6 +3110,7 @@ if (*pmarsh->elementStart!='{') // make sure not a DICT expected! { rao=pmarsh->context->NewArray(0); + bReleaseLocalReferenceRao=true; #ifdef DEBUG_ARRAY fprintf(stderr, ", creating an empty Array object! \n"); #endif @@ -3007,6 +3130,7 @@ else if (pmarsh->context->IsOfType(rop, "ORDEREDCOLLECTION")) // an orderable collection, if so turn it into an array { rao=(RexxArrayObject) pmarsh->context->SendMessage0(rop, "ALLITEMS"); // get all items as an array + bReleaseLocalReferenceRao=true; } else // raise error { @@ -3089,7 +3213,10 @@ pmarsh->signature, (unsigned long) cursorPos, *(pmarsh->signature+cursorPos)); } #endif - + if (bReleaseLocalReferenceRao==true) + { + pmarsh->context->ReleaseLocalReference(rao); + } } break; @@ -3117,6 +3244,7 @@ pmarsh->elementEnd=tmpCursor-1; // point to last char before closing paren ')' RexxArrayObject rao=NULL; + bool bReleaseLocalReferenceRao=false; if (bRopIsNull) // o.k. Rexx argument not available, supply another empty Rexx array as argument array { @@ -3131,6 +3259,7 @@ else if (pmarsh->context->IsOfType(rop, "ORDEREDCOLLECTION")) // an orderable collection, if so turn it into an array { rao=(RexxArrayObject) pmarsh->context->SendMessage0(rop, "ALLITEMS"); // get all items as an array + bReleaseLocalReferenceRao=true; } else // raise error { @@ -3144,6 +3273,11 @@ // move cursor to next char in signature pmarsh->cursor=pmarsh->elementEnd+2; // let us point to the next typeCode if any + + if (bReleaseLocalReferenceRao==true) + { + pmarsh->context->ReleaseLocalReference(rao); + } } break; @@ -3188,6 +3322,7 @@ pmarsh->elementEnd=tmpCursor-1; // point to last char before closing paren ')' RexxObjectPtr rxMap=NULL; + bool bReleaseLocalReferenceRxMap=false; if (bRopIsNull) // o.k. Rexx argument not available, supply another empty Rexx array as argument array @@ -3196,6 +3331,7 @@ fprintf(stderr, " marshal(): DICT - bRopIsNull, creating an empty Directory !\n"); #endif rxMap=pmarsh->context->NewDirectory(); + bReleaseLocalReferenceRxMap=true; } else { @@ -3219,6 +3355,11 @@ // move cursor to next char in signature pmarsh->cursor=pmarsh->elementEnd+2; // let us point to the next typeCode if any + + if (bReleaseLocalReferenceRxMap==true) + { + pmarsh->context->ReleaseLocalReference(rxMap); + } } break; @@ -3344,6 +3485,8 @@ else if (pmarsh->marshal_ay_as_string) // { RexxStringObject rso=NULL; + bool bReleaseLocalReferenceRso=false; + // if (pmarsh->context->IsString(anyRop)) if (pmarsh->context->IsOfType(anyRop, "STRING")) { @@ -3360,6 +3503,7 @@ else { rso=pmarsh->context->ObjectToString(tmpRop); + bReleaseLocalReferenceRso=true; } } else // rao==NULL ! @@ -3376,6 +3520,11 @@ (unsigned long) stringLength, stringValue); #endif + if (bReleaseLocalReferenceRso==true) + { + pmarsh->context->ReleaseLocalReference(rso); + } + if (!dbus_message_iter_append_fixed_array(&iter_array, DBUS_TYPE_BYTE, &stringValue, stringLength )) { pmarsh->dbusError = true; @@ -3452,7 +3601,6 @@ // get stored value, marshal it RexxObjectPtr rop=pmarsh->context->SendMessage1(rao, "AT", arrIdx); - #ifdef DEBUG_ARRAY fprintf(stderr, " ... ma(...): rao AT - arrIdx=[%s], value=[%s]\n", ARR_AS_STRING( arrIdx , pmarsh->context), @@ -3465,6 +3613,7 @@ *pmarsh->elementStart=='y' ) // type BYTE ? { // make sure "rop" is a "real" String object (and not a "hidden Integer" or "NumberString", such that StringLength() works reliably ! + RexxObjectPtr oriRop=rop; rop=pmarsh->context->ObjectToString(rop); size_t stringLength=pmarsh->context->StringLength((RexxStringObject) rop); // get length of the Rexx string, which may contain... [truncated message content] |
From: <or...@us...> - 2014-08-05 18:35:34
|
Revision: 230 http://sourceforge.net/p/bsf4oorexx/code/230 Author: orexx Date: 2014-08-05 18:35:29 +0000 (Tue, 05 Aug 2014) Log Message: ----------- 20140805 Minor modifications for/from debugging. Adding all current binaries of this version. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dev/apple-Makefile.mak sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc sandbox/rgf/misc/dbusoorexx/libdbusoorexx.dylib sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPong.rex Added Paths: ----------- sandbox/rgf/misc/dbusoorexx/dbusoorexx32.dll sandbox/rgf/misc/dbusoorexx/libdbusoorexx32.so sandbox/rgf/misc/dbusoorexx/libdbusoorexx64.so Removed Paths: ------------- sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx32.so sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx64.so Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-08-05 11:24:16 UTC (rev 229) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-08-05 18:35:29 UTC (rev 230) @@ -119,7 +119,7 @@ */ .local~dbus.dir=.directory~new -.dbus.dir~bDebug=.false -- .true -- .false -- .true +.dbus.dir~bDebug =.false -- .true -- .false -- .true .dbus.dir~bDebugServer=.false -- .true -- .false -- .true .dbus.dir~version="100.20140805" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' Added: sandbox/rgf/misc/dbusoorexx/dbusoorexx32.dll =================================================================== (Binary files differ) Index: sandbox/rgf/misc/dbusoorexx/dbusoorexx32.dll =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbusoorexx32.dll 2014-08-05 11:24:16 UTC (rev 229) +++ sandbox/rgf/misc/dbusoorexx/dbusoorexx32.dll 2014-08-05 18:35:29 UTC (rev 230) Property changes on: sandbox/rgf/misc/dbusoorexx/dbusoorexx32.dll ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/x-dosexec \ No newline at end of property Modified: sandbox/rgf/misc/dbusoorexx/dev/apple-Makefile.mak =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/apple-Makefile.mak 2014-08-05 11:24:16 UTC (rev 229) +++ sandbox/rgf/misc/dbusoorexx/dev/apple-Makefile.mak 2014-08-05 18:35:29 UTC (rev 230) @@ -1,5 +1,6 @@ # usage: make -f apple-Makefile.mak [all \ i386 | x86_64 | ppc | universal \ clean ] # rgf, 2011-08-15 +# rgf, 2014-08-05: adjust paths # Define a list of pkg-config packages we want to use @@ -10,15 +11,23 @@ INC_PATH = -I. -I/opt/local/include/dbus-1.0 INC_PATH_ORX = -I/opt/ooRexx/include $(INC_PATH) + +# port libraries likde dbus-1 LIB_PATH = -L/opt/local/lib -ADD_CFLAGS := -g -Wall -DUNIX -D__cplusplus + +# ADD_CFLAGS := -g -Wall -DUNIX -D__cplusplus +# Clang does not like -D__cplusplus +ADD_CFLAGS := -g -Wall -DUNIX + # LDFLAGS = -shared -rdynamic -lpthread -lc -lm ADD_LFLAGS = -shared -rdynamic CFLAGS = $(PKG_CFLAGS) $(ADD_CFLAGS) -fPIC LFLAGS = $(PKG_LDFLAGS) $(ADD_LFLAGS) +OOREXX_HOME_32=/Users/rony/dev/oorexx_allura/main/releases/4.2.0/trunk/tmp_i386/usr +OOREXX_HOME_64=/Users/rony/dev/oorexx_allura/main/releases/4.2.0/trunk/tmp_x86_64/usr # -------------------------------------------------------- @@ -26,17 +35,24 @@ # -------------------------------------------------------- i386: dbusoorexx.cc - g++ -c $(CFLAGS) $(INC_PATH) -I/opt/ooRexx-i386/include -m32 -arch i386 -DDBUSOOREXX_32 -DUSE_OREXX -DUNIX -odbusoorexx-mac-i386.o dbusoorexx.cc +# g++ -c $(CFLAGS) $(INC_PATH) -I/opt/ooRexx-i386/include -m32 -arch i386 -DDBUSOOREXX_32 -DUSE_OREXX -DUNIX -odbusoorexx-mac-i386.o dbusoorexx.cc + g++ -c $(CFLAGS) $(INC_PATH) -I$(OOREXX_HOME_32)/include -m32 -arch i386 -DDBUSOOREXX_32 -DUSE_OREXX -DUNIX -odbusoorexx-mac-i386.o dbusoorexx.cc - g++ -dynamiclib $(LFLAGS) -o libdbusoorexx-i386.dylib dbusoorexx-mac-i386.o /usr/lib/librexx.dylib /usr/lib/librexxapi.dylib $(LIB_PATH) -framework JavaVM -arch i386 +# g++ -dynamiclib $(LFLAGS) -o libdbusoorexx-i386.dylib dbusoorexx-mac-i386.o /usr/lib/librexx.dylib /usr/lib/librexxapi.dylib $(LIB_PATH) -framework JavaVM -arch i386 + g++ -dynamiclib $(LFLAGS) -o libdbusoorexx-i386.dylib dbusoorexx-mac-i386.o $(OOREXX_HOME_32)/lib/librexx.dylib $(OOREXX_HOME_32)/lib/librexxapi.dylib $(LIB_PATH) -arch i386 + # cp -p libdbusoorexx-i386.dylib 32/libdbusoorexx.dylib # --------------------------------------------------- x86_64: dbusoorexx.cc - g++ -c $(CFLAGS) $(INC_PATH) -I/opt/ooRexx-x86_64/include -m64 -arch x86_64 -DDBUSOOREXX_64 -DUSE_OREXX -DUNIX -odbusoorexx-mac-x86_64.o dbusoorexx.cc +# g++ -c $(CFLAGS) $(INC_PATH) -I/opt/ooRexx-x86_64/include -m64 -arch x86_64 -DDBUSOOREXX_64 -DUSE_OREXX -DUNIX -odbusoorexx-mac-x86_64.o dbusoorexx.cc + g++ -c $(CFLAGS) $(INC_PATH) -I$(OOREXX_HOME_64)/include -m64 -arch x86_64 -DDBUSOOREXX_64 -DUSE_OREXX -DUNIX -odbusoorexx-mac-x86_64.o dbusoorexx.cc - g++ -dynamiclib $(LFLAGS) -o libdbusoorexx-x86_64.dylib dbusoorexx-mac-x86_64.o /opt/ooRexx-x86_64/lib/ooRexx/librexx.dylib /opt/ooRexx-x86_64/lib/ooRexx/librexxapi.dylib $(LIB_PATH) -framework JavaVM -arch x86_64 + +# g++ -dynamiclib $(LFLAGS) -o libdbusoorexx-x86_64.dylib dbusoorexx-mac-x86_64.o /opt/ooRexx-x86_64/lib/ooRexx/librexx.dylib /opt/ooRexx-x86_64/lib/ooRexx/librexxapi.dylib $(LIB_PATH) -framework JavaVM -arch x86_64 + g++ -dynamiclib $(LFLAGS) -o libdbusoorexx-x86_64.dylib dbusoorexx-mac-x86_64.o $(OOREXX_HOME_64)/lib/librexx.dylib $(OOREXX_HOME_64)/lib/librexxapi.dylib $(LIB_PATH) -arch x86_64 + # cp -p libdbusoorexx-x86_64.dylib 64/libdbusoorexx.dylib # --------------------------------------------------- Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-08-05 11:24:16 UTC (rev 229) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-08-05 18:35:29 UTC (rev 230) @@ -122,7 +122,8 @@ // rgf, 2011-06-11, cf. <>http://gcc.gnu.org/gcc-4.3/porting_to.html> // (needed for old dbus-example to be able to compile unaltered), but also for memset() strlen(), str[n]cpy() -#include <cstring> // ? maybe removable, once old code is replaced/tidied up ? +// #include <cstring> // ? maybe removable, once old code is replaced/tidied up ? Clang won't accept that anymore (20140805) +#include <string.h> // will allow access to memset() et.al. #ifdef _MSC_VER # pragma warning(disable:4100) @@ -168,6 +169,7 @@ // #define DEBUG_MESSAGELOOP +// #define DEBUG_CONNECTION /* #define DEBUG_VARIANT @@ -222,6 +224,9 @@ #define DEBUG_WATCHLOOP #define DEBUG_TIMEOUTLOOP #define DEBUG_PRIVATE_SERVER + +#define DEBUG_CONNECTION // 2014-08-05, rgf: debug whether connection has a value or not + */ @@ -700,7 +705,7 @@ // raise exception context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); - return context->Nil(); // return .nil + return NULLOBJECT; // return nothing } if (NULL == conn) @@ -708,7 +713,7 @@ // raise exception SNPRINTF( msg, 1024, "%.16s/method/DbusNativeGetSystemBus(), connection error 2: no connection returned", DLLNAME); context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); - return context->Nil(); // return .nil + return NULLOBJECT; // return nothing } // save conn in a Rexx pointer object and save it as CSELF @@ -745,7 +750,7 @@ // raise exception context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); - return context->Nil(); // return .nil + return NULLOBJECT; // return nothing } if (NULL == conn) @@ -753,7 +758,7 @@ // raise exception SNPRINTF( msg, 1024, "%.16s/method/DbusNativeGetSessionBus(), connection error 2: no connection returned", DLLNAME); context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); - return context->Nil(); // return .nil + return NULLOBJECT; // return nothing } // save conn in a Rexx pointer object and save it as CSELF @@ -770,10 +775,22 @@ // get and return unique bus name (.Dbus instance method) RexxMethod1(RexxStringObject, DbusGetUniqueBusName, CSELF, connPtr) { -#if defined (DEBUG_METHODS) - fprintf(stderr, "===> arrived in DbusGetUniqueBusName\n"); +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) + fprintf(stderr, "===> arrived in DbusGetUniqueBusName, connPtr=[%p]\n", connPtr); fflush(stderr); #endif + if (connPtr==NULL) + { + { + char msg[1024]=""; // buffer for error message + SNPRINTF( msg, 1024, "%.16s/method/DbusGetUniqueBusName(), connection error 1: not connected (NULL)", DLLNAME); + + // raise exception + context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); + return NULLOBJECT; // return nothing + } + } + DBusConnection *conn=(DBusConnection *) connPtr; const char *tmpStr = dbus_bus_get_unique_name(conn); @@ -798,7 +815,7 @@ // get and return unique bus id (.Dbus instance method) RexxMethod1(RexxObjectPtr, DbusGetUniqueBusId, CSELF, connPtr) { -#if defined (DEBUG_METHODS) +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusGetUniqueBusId\n"); fflush(stderr); #endif @@ -817,7 +834,7 @@ // raise exception context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); - return context->Nil(); // return .nil + return NULLOBJECT; // return nothing } RexxStringObject rso = context->String( (tmpStr==NULL ? "" : tmpStr) ); dbus_free(tmpStr); @@ -829,7 +846,7 @@ // if open, returns true, false else; cf. <http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#ga611ae94556af36fe30bfb547366ca4e1> RexxMethod1(RexxObjectPtr, DbusConnectionIsConnected, CSELF, connPtr) { -#if defined (DEBUG_METHODS) +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusConnectionIsConnected\n"); fflush(stderr); #endif @@ -845,7 +862,7 @@ // expects a single char; if that is a supported type code returns .true, otherwise .false RexxMethod2(RexxObjectPtr, DbusConnectionCanSendType, CSTRING, typeCode, CSELF, connPtr) { -#if defined (DEBUG_METHODS) +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusConnectionCanSendType\n"); fflush(stderr); #endif @@ -861,7 +878,7 @@ // if authenticated, returns true, false else RexxMethod1(RexxObjectPtr, DbusConnectionIsAuthenticated, CSELF, connPtr) { -#if defined (DEBUG_METHODS) +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusConnectionIsAuthenticated\n"); fflush(stderr); #endif @@ -883,7 +900,7 @@ OPTIONAL_RexxObjectPtr, flags, CSELF, connPtr) { -#if defined (DEBUG_METHODS) +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusBusNameRequest\n"); fflush(stderr); #endif @@ -903,7 +920,6 @@ ); // raise exception context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); - // return context->Nil(); // return .nil return NULLOBJECT; // return nothing } } @@ -943,7 +959,7 @@ RexxMethod2(RexxObjectPtr, DbusBusNameHasOwner, CSTRING, busName, CSELF, connPtr) { -#if defined (DEBUG_METHODS) +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusBusNameHasOwner\n"); fflush(stderr); #endif @@ -975,7 +991,7 @@ RexxMethod2(RexxObjectPtr, DbusBusNameRelease, CSTRING, busName, CSELF, connPtr) { -#if defined (DEBUG_METHODS) +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusBusNameRelease\n"); fflush(stderr); #endif @@ -1010,7 +1026,7 @@ OPTIONAL_RexxObjectPtr, block, CSELF, connPtr) { -#if defined (DEBUG_METHODS) +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusBusAddMatch [%s] \n", rule); fflush(stderr); #endif @@ -1030,7 +1046,6 @@ ); // raise exception context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); - // return context->Nil(); // return .nil return NULLOBJECT; // return nothing } } @@ -1072,7 +1087,7 @@ OPTIONAL_RexxObjectPtr, block, CSELF, connPtr) { -#if defined (DEBUG_METHODS) +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusBusRemoveMatch [%s] \n", rule); fflush(stderr); #endif @@ -1092,7 +1107,6 @@ ); // raise exception context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); - // return context->Nil(); // return .nil return NULLOBJECT; // return nothing } } @@ -4779,7 +4793,7 @@ // - wrapped up as a Rexx method, hence easy to run it on a separate thread RexxMethod2(RexxObjectPtr, DbusMessageLoop, CSELF, connPtr, OSELF, self) { -#ifdef DEBUG_MESSAGELOOP +#if defined (DEBUG_MESSAGELOOP) || defined (DEBUG_CONNECTION) fprintf(stderr, "... MessageLoop(): just arrived ! ...\n"); fflush(stderr); #endif @@ -6037,7 +6051,7 @@ */ -#ifdef DEBUG_MESSAGELOOP +#if defined (DEBUG_MESSAGELOOP) || defined (DEBUG_CONNECTION) fprintf(stderr, "... MessageLoop(): left message loop, changed instance variable 'active' to .false ...\n"); fflush(stderr); #endif @@ -6061,7 +6075,7 @@ size_t items = (rexxArgs==NULLOBJECT ? 0 : context->ArraySize(rexxArgs)) ; size_t sigLen=strlen(signature); -#if defined (DEBUG_METHODS) +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) // fprintf(stderr, "===> arrived in DbusBusSignalMessage: rao=[%p], items=[%zu], signature=[%s]\n", rexxArgs, items, signature);fflush(stderr); fprintf(stderr, "===> arrived in DbusBusSignalMessage: rao=[%p], items=[%lu], signature=[%s]\n", rexxArgs, (unsigned long) items, signature);fflush(stderr); #endif @@ -6185,7 +6199,6 @@ char msg[1024]=""; // buffer for error message SNPRINTF( msg, 1024, "%.16s/method/DbusBusSignalMessage(), error 7: could not send signal message, 'dbus_connection_send()()' returned NULL", DLLNAME); -fprintf(stderr, "DBUS_SIG_TSK #1\n");fflush(stderr); // raise exception context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); dbus_message_unref(dbusMsg); // free the message resources @@ -6237,7 +6250,7 @@ size_t items = (rexxArgs==NULLOBJECT ? 0 : context->ArraySize(rexxArgs)) ; size_t argSignatureLength=strlen(argSignature); -#if defined (DEBUG_METHODS) +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) // fprintf(stderr, "===> arrived in DbusBusCallMessage: rao=[%p], items=[%zu], argSignature=[%s] | replySignature=[%s]\n", rexxArgs, items, argSignature, replySignature); fprintf(stderr, "===> arrived in DbusBusCallMessage: rao=[%p], items=[%lu], argSignature=[%s] | replySignature=[%s]\n", rexxArgs, (unsigned long) items, argSignature, replySignature); fprintf(stderr, "===> ... busName=[%s], targetObjectPath=[%s], callInterfaceName=[%s], callMemberName=[%s]\n", @@ -6436,7 +6449,6 @@ dbus_message_unref(dbusMsg); // free the message resources -fprintf(stderr, "DBUS_MSG_TSK #1\n");fflush(stderr); // raise exception context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); return NULLOBJECT; // return nothing @@ -6446,7 +6458,6 @@ { char msg[1024]=""; // buffer for error message SNPRINTF( msg, 1024, "%.16s/method/DbusBusCallMessage(), error 10: could not receive a valid pending message object from 'dbus_connection_send_with_reply()' (maybe you attempted to send Unix file descriptors and this connection does not support them?)", DLLNAME); -fprintf(stderr, "DBUS_MSG_TSK #2\n");fflush(stderr); // raise exception context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); @@ -6487,7 +6498,6 @@ char msg[1024]=""; // buffer for error message SNPRINTF( msg, 1024, "%.16s/method/DbusBusCallMessage(), error 11: could not receive a valid reply message object from 'dbus_connection_send_with_reply()'", DLLNAME); -fprintf(stderr, "DBUS_MSG_TSK #3\n");fflush(stderr); // raise exception context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); return NULLOBJECT; // return nothing @@ -6528,7 +6538,6 @@ if (msgType==DBUS_MESSAGE_TYPE_ERROR) // reply was an error message, raise condition in caller and inform him ! { -fprintf(stderr, "DBUS_MSG_TSK #4a\n");fflush(stderr); char msg[1024]=""; // buffer for error message logical_t isNoReturnValueError=dbus_message_is_error(replyMsg, REXX_ERROR_MESSAGE_NO_RETURN_VALUE); if (!isNoReturnValueError) @@ -6594,7 +6603,6 @@ context->SetGuardOff(); } -fprintf(stderr, "DBUS_MSG_TSK #4\n");fflush(stderr); context->RaiseException(Rexx_Error_Incorrect_method_user_defined, ra); return NULLOBJECT; @@ -6629,7 +6637,7 @@ // close a private connection RexxMethod1(RexxObjectPtr, DbusNativeConnectionOpenPrivate, CSTRING, address) { -#if defined (DEBUG_METHODS) +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusConnectionOpenPrivate: address=[%p] \n", address); fflush(stderr); #endif @@ -6652,9 +6660,9 @@ } dbus_error_free(&err); // not needed anymore - // save conn in a Rexx pointer object and save it as CSELF + // save conn in a Rexx pointer object and save it in attribute CSELF RexxPointerObject rpo = context->NewPointer(conn); - context->SetObjectVariable("CSELF", rpo); // set object's CSELF + context->SetObjectVariable("CSELF", rpo); // set object's CSELF attribute return NULLOBJECT; // return nothing } @@ -6664,17 +6672,25 @@ // close a private connection RexxMethod1(RexxObjectPtr, DbusNativeConnectionClose, CSELF, connPtr) { -#if defined (DEBUG_METHODS) - fprintf(stderr, "===> arrived in DbusNativeConnectionClose: connPtr=[%p] \n", connPtr); +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) + fprintf(stderr, "===> arrived in DbusNativeConnectionClose: connPtr=[%p], .nil=[%p] \n", connPtr, context->Nil()); fflush(stderr); #endif // get self and carry out the DBusConnection *conn=(DBusConnection *) connPtr; - dbus_connection_close(conn); - dbus_connection_unref(conn); - // not a valid connection anymore, hence set CSELF to .nil - context->SetObjectVariable("CSELF", context->Nil()); + if (connPtr!=NULL) // rgf, 20140805 + { +#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) + fprintf(stderr, " DbusNativeConnectionClose: about to close and unrer'ing...\n", connPtr); fflush(stderr); +#endif + dbus_connection_close(conn); + dbus_connection_unref(conn); + + // not a valid connection anymore, hence set CSELF attribute to .nil + context->SetObjectVariable("CSELF", context->Nil()); + } + return NULLOBJECT; // return nothing } @@ -6689,7 +6705,7 @@ // -------------------------------------------------------------------------------- void new_connection_callback (DBusServer *server, DBusConnection *conn, void *data) // callback on new connection { -#if defined (DEBUG_METHODS) || defined (DEBUG_PRIVATE_SERVER) || defined (DEBUG_OOREXX_FIND_CLASS) +#if defined (DEBUG_METHODS) || defined (DEBUG_PRIVATE_SERVER) || defined (DEBUG_OOREXX_FIND_CLASS) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in \"new_connection_callback(...)\", connPtr=[%p], data=[%p} \n", conn, data); fflush(stderr); #endif @@ -6939,7 +6955,7 @@ // wrapped up as a Rexx method, hence easy to run it on a separate thread RexxMethod3(RexxObjectPtr, DbusServerTimeoutLoop, RexxObjectPtr, timeoutDataPointer, CSELF, connPtr, OSELF, self) { -#if defined (DEBUG_TIMEOUTLOOP) || defined (DEBUG_METHODS) +#if defined (DEBUG_TIMEOUTLOOP) || defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) fprintf(stderr, "... TimeoutLoop(): just arrived ! ...\n"); fflush(stderr); #endif @@ -7037,7 +7053,7 @@ context->ReleaseLocalReference(ropTimeoutLoopActive); -#if defined (DEBUG_TIMEOUTLOOP) || defined (DEBUG_METHODS) +#if defined (DEBUG_TIMEOUTLOOP) || defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) fprintf(stderr, "... TimeoutLoop(): about to leav.\n"); fflush(stderr); #endif @@ -7171,7 +7187,7 @@ // wrapped up as a Rexx method, hence easy to run it on a separate thread RexxMethod2(RexxObjectPtr, DbusServerWatchLoop, CSELF, connPtr, OSELF, self) { -#ifdef DEBUG_WATCHLOOP +#if defined (DEBUG_WATCHLOOP) || defined (DEBUG_CONNECTION) fprintf(stderr, "... WatchLoop(): just arrived ! ...\n"); fflush(stderr); #endif @@ -7368,7 +7384,7 @@ } } // end while -#ifdef DEBUG_WATCHLOOP +#if defined (DEBUG_WATCHLOOP) || defined (DEBUG_CONNECTION) fprintf(stderr, "... WatchLoop(): about to leave.\n"); fflush(stderr); #endif @@ -7381,7 +7397,7 @@ // test whether server instance is active RexxMethod1(logical_t, DbusNativeServerIsActive, CSELF, serverPtr) { -#if defined (DEBUG_METHODS) || defined (DEBUG_PRIVATE_SERVER) +#if defined (DEBUG_METHODS) || defined (DEBUG_PRIVATE_SERVER) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusNativeServerIsActive: serverPtr=[%p] \n", serverPtr); fflush(stderr); #endif @@ -7395,7 +7411,7 @@ // get and return the server's id RexxMethod1(RexxObjectPtr, DbusNativeServerGetId, CSELF, serverPtr) { -#if defined (DEBUG_METHODS) || defined (DEBUG_PRIVATE_SERVER) +#if defined (DEBUG_METHODS) || defined (DEBUG_PRIVATE_SERVER) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusNativeServerGetId: serverPtr=[%p] \n", serverPtr); fflush(stderr); #endif @@ -7410,7 +7426,7 @@ // raise exception context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); - return NULL; + return NULLOBJECT; } RexxStringObject rso = context->String(tmpStr); dbus_free(tmpStr); @@ -7422,7 +7438,7 @@ // get and return server's address RexxMethod1(RexxObjectPtr, DbusNativeServerGetAddress, CSELF, serverPtr) { -#if defined (DEBUG_METHODS) || defined (DEBUG_PRIVATE_SERVER) +#if defined (DEBUG_METHODS) || defined (DEBUG_PRIVATE_SERVER) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusNativeServerGetAddress: serverPtr=[%p] \n", serverPtr); fflush(stderr); #endif @@ -7437,7 +7453,7 @@ // raise exception context->RaiseException1(Rexx_Error_Incorrect_method_user_defined, context->String(msg)); - return NULL; + return NULLOBJECT; } RexxStringObject rso = context->String(tmpStr); dbus_free(tmpStr); @@ -7449,17 +7465,21 @@ // disconnect the server RexxMethod2(RexxObjectPtr, DbusNativeServerDisconnect, CSELF, serverPtr, OSELF, self) { -#if defined (DEBUG_METHODS) || defined (DEBUG_PRIVATE_SERVER) +#if defined (DEBUG_METHODS) || defined (DEBUG_PRIVATE_SERVER) || defined (DEBUG_CONNECTION) fprintf(stderr, "===> arrived in DbusNativeServerDisconnect: serverPtr=[%p] \n", serverPtr); fflush(stderr); #endif DBusServer *server=(DBusServer *) serverPtr; dbus_server_disconnect(server); - dbus_server_unref(server); + dbus_server_unref(server); // TODO: rgf, 20140805: the 2011 private build of dbus for 32-bit Windows will abend here; context->SendMessage1(self, "CSELF=", context->Nil()); // set CSELF +#if defined (DEBUG_METHODS) || defined (DEBUG_PRIVATE_SERVER) || defined (DEBUG_CONNECTION) + fprintf(stderr, " DbusNativeServerDisconnect: serverPtr=[%p], about to leave\n", serverPtr); + fflush(stderr); +#endif return NULLOBJECT; } Deleted: sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx32.so =================================================================== (Binary files differ) Deleted: sandbox/rgf/misc/dbusoorexx/dev/libdbusoorexx64.so =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/libdbusoorexx.dylib =================================================================== (Binary files differ) Added: sandbox/rgf/misc/dbusoorexx/libdbusoorexx32.so =================================================================== (Binary files differ) Index: sandbox/rgf/misc/dbusoorexx/libdbusoorexx32.so =================================================================== --- sandbox/rgf/misc/dbusoorexx/libdbusoorexx32.so 2014-08-05 11:24:16 UTC (rev 229) +++ sandbox/rgf/misc/dbusoorexx/libdbusoorexx32.so 2014-08-05 18:35:29 UTC (rev 230) Property changes on: sandbox/rgf/misc/dbusoorexx/libdbusoorexx32.so ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/x-sharedlib \ No newline at end of property Added: sandbox/rgf/misc/dbusoorexx/libdbusoorexx64.so =================================================================== (Binary files differ) Index: sandbox/rgf/misc/dbusoorexx/libdbusoorexx64.so =================================================================== --- sandbox/rgf/misc/dbusoorexx/libdbusoorexx64.so 2014-08-05 11:24:16 UTC (rev 229) +++ sandbox/rgf/misc/dbusoorexx/libdbusoorexx64.so 2014-08-05 18:35:29 UTC (rev 230) Property changes on: sandbox/rgf/misc/dbusoorexx/libdbusoorexx64.so ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/x-sharedlib \ No newline at end of property Modified: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPong.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPong.rex 2014-08-05 11:24:16 UTC (rev 229) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPong.rex 2014-08-05 18:35:29 UTC (rev 230) @@ -85,6 +85,7 @@ say "about to do a server~shutdown..." server~shutdown +say "main: after server~shutdown" say "server~active (after shutdown): " pp2(server~active) -- "server2:" pp2(server2~active) say "DbusVersion() ="pp2(DbusVersion()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2014-08-06 17:26:01
|
Revision: 231 http://sourceforge.net/p/bsf4oorexx/code/231 Author: orexx Date: 2014-08-06 17:25:57 +0000 (Wed, 06 Aug 2014) Log Message: ----------- 20140806 Adding support for 64-bit Windows, fiddling with Makefiles, fixing an error only surfacing on the Windows dbus. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc sandbox/rgf/misc/dbusoorexx/libdbusoorexx.dylib sandbox/rgf/misc/dbusoorexx/libdbusoorexx32.so sandbox/rgf/misc/dbusoorexx/libdbusoorexx64.so sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPongDoingOtherStuff.rex Added Paths: ----------- sandbox/rgf/misc/dbusoorexx/dbusoorexx-32.dll sandbox/rgf/misc/dbusoorexx/dbusoorexx-64.dll sandbox/rgf/misc/dbusoorexx/dev/Makefile32 sandbox/rgf/misc/dbusoorexx/dev/Makefile64 sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx-32.def sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx-64.def sandbox/rgf/misc/dbusoorexx/dev/rony-dbus-cheat-sheet.txt sandbox/rgf/misc/dbusoorexx/doc/201112-DBus4ooRexx-article.pdf Removed Paths: ------------- sandbox/rgf/misc/dbusoorexx/dbusoorexx32.dll Added: sandbox/rgf/misc/dbusoorexx/dbusoorexx-32.dll =================================================================== (Binary files differ) Index: sandbox/rgf/misc/dbusoorexx/dbusoorexx-32.dll =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbusoorexx-32.dll 2014-08-05 18:35:29 UTC (rev 230) +++ sandbox/rgf/misc/dbusoorexx/dbusoorexx-32.dll 2014-08-06 17:25:57 UTC (rev 231) Property changes on: sandbox/rgf/misc/dbusoorexx/dbusoorexx-32.dll ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/x-dosexec \ No newline at end of property Added: sandbox/rgf/misc/dbusoorexx/dbusoorexx-64.dll =================================================================== (Binary files differ) Index: sandbox/rgf/misc/dbusoorexx/dbusoorexx-64.dll =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbusoorexx-64.dll 2014-08-05 18:35:29 UTC (rev 230) +++ sandbox/rgf/misc/dbusoorexx/dbusoorexx-64.dll 2014-08-06 17:25:57 UTC (rev 231) Property changes on: sandbox/rgf/misc/dbusoorexx/dbusoorexx-64.dll ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/x-dosexec \ No newline at end of property Deleted: sandbox/rgf/misc/dbusoorexx/dbusoorexx32.dll =================================================================== (Binary files differ) Added: sandbox/rgf/misc/dbusoorexx/dev/Makefile32 =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/Makefile32 (rev 0) +++ sandbox/rgf/misc/dbusoorexx/dev/Makefile32 2014-08-06 17:25:57 UTC (rev 231) @@ -0,0 +1,84 @@ +# debug, e.g.: nmake /f Makefile32 clean && nmake /f Makefile32 +# release, e.g.: nmake /f Makefile32 clean && nmake /f Makefile32 RELEASE=1 +# 32-bit version, rgf, 2009-09-07, adapted for dbus on 2011-08-17 +# rgf, 2014-08-06 + + +# rgf, 2011-09-20 +# DBUS_HOME = e:\programme\dbus + +# rgf, 2014-08-06 +DBUS_HOME = e:\programme\dbus-20140805 +DBUS_INCLUDE = $(DBUS_HOME)\include +DBUS_LIB_HOME = $(DBUS_HOME)\lib + +LIB = $(LIB);$(DBUS_LIB_HOME) + +INC_PATH = .;$(DBUS_INCLUDE) +INCLUDE = $(INCLUDE);$(INC_PATH) +OP_SYS = -DWINDOWS +# <--- rgf + + +# What we are going to build +all: dbusoorexx-32.dll + +!IF DEFINED(REXX_HOME) +INCLUDE = $(INCLUDE);$(REXX_HOME)\api +LIB = $(LIB);$(REXX_HOME)\api +!ENDIF + +REXX_LIBS = rexx.lib rexxapi.lib +DBUS_LIB = dbus-1.lib WS2_32.lib + +WARNINGFLAGS = /W3 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE + +DEF_FILE = /def:dbusoorexx-32.def + +!IF DEFINED(RELEASE) +# Set the compile and link flags for a release build +# OOREXX_CFLAGS = /nologo /EHsc /O2 /Gs /FAcs /MT /showIncludes $(WARNINGFLAGS) -DWINDOWS -DDBUSOOREXX_32 /c +OOREXX_CFLAGS = /nologo /EHsc /O2 /Gs /FAcs /MT $(WARNINGFLAGS) -DWINDOWS -DDBUSOOREXX_32 /c +DLL_LFLAGS = /nologo /SUBSYSTEM:Windows $(REXX_LIBS) $(DBUS_LIB) $(DEF_FILE) /DLL +!ELSE # release not defined +# Set the compile and link flags for a debug build +OOREXX_CFLAGS = /nologo /EHsc /Zi /Od /MTd $(WARNINGFLAGS) -DWINDOWS -DDBUSOOREXX_32 /c +DLL_LFLAGS = /nologo /DEBUG -debugtype:cv /SUBSYSTEM:Windows $(REXX_LIBS) $(DBUS_LIB) $(DEF_FILE) /DLL +!ENDIF + + +dbusoorexx-32.dll: dbusoorexx-32.obj + @echo "DLL_LFLAGS :" $(DLL_LFLAGS) + @echo begin-LIB--- + @echo $(LIB) + @echo begin-LINK--- + @echo link $(DLL_LFLAGS) $(@B).obj -out:$(@B).dll + @echo start--- + link $(DLL_LFLAGS) $(@B).obj -out:$(@B).dll + @echo end--- + copy $(@B).dll .. + copy $(@B).dll dbusoorexx.dll +# copy $(@B).dll 32\dbusoorexx.dll + @if exist $(@B).exp copy $(@B).exp dbusoorexx.exp > nul + @if exist $(@B).ilk copy $(@B).ilk dbusoorexx.ilk > nul + @if exist $(@B).lib copy $(@B).lib dbusoorexx.lib > nul + @if exist $(@B).obj copy $(@B).obj dbusoorexx.obj > nul + @if exist $(@B).pdb copy $(@B).pdb dbusoorexx.pdb > nul + + + +dbusoorexx-32.obj: dbusoorexx.cc + @echo "OOREXX_CFLAGS:" $(OOREXX_CFLAGS) + @echo --begin--compile + @echo cl $(OOREXX_CFLAGS) /Fo$(@B).obj dbusoorexx.cc + @echo --start--compile + cl $(OOREXX_CFLAGS) /Fo$(@B).obj dbusoorexx.cc + @echo --end--compile + +mostlyclean: + del *.obj *.ilk *.lib *.exp *.cod *.res *.map 1>nul 2>&1 + +clean: + attrib -h *.suo 1>nul 2>&1 + del *.exe *.dll *.obj *.ilk *.pdb *.lib *.exp *.suo *.cod *.res *.sln *.map 1>nul 2>&1 + Property changes on: sandbox/rgf/misc/dbusoorexx/dev/Makefile32 ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: sandbox/rgf/misc/dbusoorexx/dev/Makefile64 =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/Makefile64 (rev 0) +++ sandbox/rgf/misc/dbusoorexx/dev/Makefile64 2014-08-06 17:25:57 UTC (rev 231) @@ -0,0 +1,91 @@ +# debug, e.g.: nmake /f Makefile64 clean && nmake /f Makefile64 +# release, e.g.: nmake /f Makefile64 clean && nmake /f Makefile64 RELEASE=1 +# 64-bit version, rgf, 2014-08-06 + + +# rgf, 2011-09-20 +# DBUS_HOME = e:\programme\dbus + +# rgf, 2014-08-06 +DBUS_HOME = e:\programme\dbus-20140805-64bit +DBUS_INCLUDE = $(DBUS_HOME)\include +DBUS_LIB_HOME = $(DBUS_HOME)\lib + +LIB = $(LIB);$(DBUS_LIB_HOME) + +INC_PATH = .;$(DBUS_INCLUDE) +INCLUDE = $(INCLUDE);$(INC_PATH) +OP_SYS = -DWINDOWS +# <--- rgf + + +# What we are going to build +all: dbusoorexx-64.dll + +# rgf: using path to directory that contains ooRexx 64-bit API files (to allow compilation on a 32-bit system) +REXX_API=oorexx64api +INCLUDE = $(INCLUDE);$(REXX_API) +LIB = $(LIB);$(REXX_API) + +# !IF DEFINED(REXX_HOME) +# INCLUDE = $(INCLUDE);$(REXX_HOME)\api +# LIB = $(LIB);$(REXX_HOME)\api +# !ENDIF + +REXX_LIBS = rexx.lib rexxapi.lib +# DBUS_LIB = dbus-1.lib +# even on 64-bit with MS cl it is called "ws2_32.lib" ! +DBUS_LIB = dbus-1.lib ws2_32.lib + +WARNINGFLAGS = /W3 /Wp64 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE + +DEF_FILE = /def:dbusoorexx-64.def + +!IF DEFINED(RELEASE) +# Set the compile and link flags for a release build +# OOREXX_CFLAGS = /nologo /EHsc /O2 /Gs /FAcs /MT /showIncludes $(WARNINGFLAGS) -DWINDOWS -DDBUSOOREXX_64 /c +OOREXX_CFLAGS = /nologo /EHsc /O2 /Gs /FAcs /MT $(WARNINGFLAGS) -DWINDOWS -DDBUSOOREXX_64 /c /Fo$(@B).obj +DLL_LFLAGS = /nologo /SUBSYSTEM:Windows $(REXX_LIBS) $(DBUS_LIB) $(DEF_FILE) /DLL +!ELSE # release not defined +# Set the compile and link flags for a debug build +OOREXX_CFLAGS = /nologo /EHsc /Zi /Od /MTd $(WARNINGFLAGS) -DWINDOWS -DDBUSOOREXX_64 /c +DLL_LFLAGS = /nologo /DEBUG -debugtype:cv /SUBSYSTEM:Windows $(REXX_LIBS) $(DBUS_LIB) $(DEF_FILE) /DLL +!ENDIF + + +dbusoorexx-64.dll: dbusoorexx-64.obj + @echo "DLL_LFLAGS :" $(DLL_LFLAGS) + @echo begin-LIB--- + @echo $(LIB) + @echo begin-LINK--- + @echo link $(DLL_LFLAGS) $(@B).obj -out:$(@B).dll + @echo start--- +# link $(DLL_LFLAGS) $(@B).obj -out:$(@B).dll + link $(DLL_LFLAGS) $(@B).obj bufferoverflowu.lib -out:$(@B).dll + @echo end--- + copy $(@B).dll .. + copy $(@B).dll dbusoorexx.dll +# copy $(@B).dll 64\dbusoorexx.dll + @if exist $(@B).exp copy $(@B).exp dbusoorexx.exp > nul + @if exist $(@B).ilk copy $(@B).ilk dbusoorexx.ilk > nul + @if exist $(@B).lib copy $(@B).lib dbusoorexx.lib > nul + @if exist $(@B).obj copy $(@B).obj dbusoorexx.obj > nul + @if exist $(@B).pdb copy $(@B).pdb dbusoorexx.pdb > nul + + + +dbusoorexx-64.obj: dbusoorexx.cc + @echo "OOREXX_CFLAGS:" $(OOREXX_CFLAGS) + @echo --begin--compile + @echo cl $(OOREXX_CFLAGS) /Fo$(@B).obj dbusoorexx.cc + @echo --start--compile + cl $(OOREXX_CFLAGS) /Fo$(@B).obj dbusoorexx.cc + @echo --end--compile + +mostlyclean: + del *.obj *.ilk *.lib *.exp *.cod *.res *.map 1>nul 2>&1 + +clean: + attrib -h *.suo 1>nul 2>&1 + del *.exe *.dll *.obj *.ilk *.pdb *.lib *.exp *.suo *.cod *.res *.sln *.map 1>nul 2>&1 + Property changes on: sandbox/rgf/misc/dbusoorexx/dev/Makefile64 ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx-32.def =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx-32.def (rev 0) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx-32.def 2014-08-06 17:25:57 UTC (rev 231) @@ -0,0 +1,32 @@ +; ------------------------ Apache Version 2.0 license ------------------------- +; Copyright (C) 2011 Rony G. Flatscher +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; ----------------------------------------------------------------------------- + +; 2011-08-17, ---rgf, created for "dbusoorexx.dll" + + +LIBRARY dbusoorexx-32 +; HEAPSIZE 40960 +; STACKSIZE 40960 + +; the following was defined for BSF4ooRexx +; HEAPSIZE 131072 +; STACKSIZE 131072 + + +; functions in the DLL to be made available to other programs +EXPORTS + RexxGetPackage + Property changes on: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx-32.def ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx-64.def =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx-64.def (rev 0) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx-64.def 2014-08-06 17:25:57 UTC (rev 231) @@ -0,0 +1,32 @@ +; ------------------------ Apache Version 2.0 license ------------------------- +; Copyright (C) 2011 Rony G. Flatscher +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; ----------------------------------------------------------------------------- + +; 2011-08-17, ---rgf, created for "dbusoorexx.dll" + + +LIBRARY dbusoorexx-64 +; HEAPSIZE 40960 +; STACKSIZE 40960 + +; the following was defined for BSF4ooRexx +; HEAPSIZE 131072 +; STACKSIZE 131072 + + +; functions in the DLL to be made available to other programs +EXPORTS + RexxGetPackage + Property changes on: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx-64.def ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-08-05 18:35:29 UTC (rev 230) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-08-06 17:25:57 UTC (rev 231) @@ -43,14 +43,15 @@ 2014-08-05, rgf: - adding ReleaseLocalReference() where methods/routines may be running forever,ie. in the various message/server loops and the functions that may be invoked from within (ooRexx releases local references when returning from native - Rexx methods/routines) + Rexx methods/routines); added a missing dbus_server_ref()-call (caused abend + on Windows) - ooRexx 4.2.0 now required (because of using .context~name possible todos: - add globals for Nil(), True(), Flase(), .Array, .DateTime, .DBus, "1", NullString() + - change attribute name CSELF (probably misleading as it is not the same as CSELF in an + ooRexx native method or routine argument type); if so, don't forget dbus.cls - - - version: 100.20140805 + version: 100.20140806 license: Apache License 2.0 ------------------------ Apache Version 2.0 license ------------------------- @@ -136,11 +137,11 @@ #ifdef DBUSOOREXX_32 - #define DBUS_REXXVERSION "100.20140805 32-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20140806 32-bit" // version: "MajorNumber"."YYYYMMDD" #elif defined (DBUSOOREXX_64) - #define DBUS_REXXVERSION "100.20140805 64-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20140806 64-bit" // version: "MajorNumber"."YYYYMMDD" #else - #define DBUS_REXXVERSION "100.20140805 n/a-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20140806 n/a-bit" // version: "MajorNumber"."YYYYMMDD" #endif #ifndef TID @@ -6679,17 +6680,11 @@ // get self and carry out the DBusConnection *conn=(DBusConnection *) connPtr; - if (connPtr!=NULL) // rgf, 20140805 - { -#if defined (DEBUG_METHODS) || defined (DEBUG_CONNECTION) - fprintf(stderr, " DbusNativeConnectionClose: about to close and unrer'ing...\n", connPtr); fflush(stderr); -#endif - dbus_connection_close(conn); - dbus_connection_unref(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); - // not a valid connection anymore, hence set CSELF attribute to .nil - context->SetObjectVariable("CSELF", context->Nil()); - } + // not a valid connection anymore, hence set CSELF attribute to .nil + context->SetObjectVariable("CSELF", context->Nil()); return NULLOBJECT; // return nothing } @@ -7096,6 +7091,8 @@ } dbus_error_free(&err); // not needed anymore + dbus_server_ref(server); // increase ref counter + // save server's pointer RexxPointerObject rpo = context->NewPointer(server); context->SendMessage1(self, "CSELF=", rpo); // set CSELF @@ -7472,6 +7469,7 @@ DBusServer *server=(DBusServer *) serverPtr; dbus_server_disconnect(server); + dbus_server_unref(server); // TODO: rgf, 20140805: the 2011 private build of dbus for 32-bit Windows will abend here; context->SendMessage1(self, "CSELF=", context->Nil()); // set CSELF Added: sandbox/rgf/misc/dbusoorexx/dev/rony-dbus-cheat-sheet.txt =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/rony-dbus-cheat-sheet.txt (rev 0) +++ sandbox/rgf/misc/dbusoorexx/dev/rony-dbus-cheat-sheet.txt 2014-08-06 17:25:57 UTC (rev 231) @@ -0,0 +1,80 @@ +cheat-sheet, 20140805, ---rgf +----------------------------- + +- git clone ssh://git.freedesktop.org/git/dbus/dbus + did not work (authentication?) + +- git clone git://anongit.freedesktop.org/dbus/dbus + worked! + + +- cd F:\work\git\dbus-win-20140805\dbus + +- add2path E:\Programme\CMake\bin + +f: +cd F:\work\git\dbus-win-20140805\dbus + + +------------------------------------------- 32-bit: +- md dbus-build + +- cd dbus-build + +- add2path E:\Programme\Expat_2.1.0\Bin + +- "e:\Programme\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat" +[- F:\work\svn\bsf4oorexx\trunk\bsf4oorexx.dev\source_cc\env4_32bit_xp.cmd] + + +cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=E:/Programme/dbus-20140805 -DDBUS_USE_EXPAT=ON -DEXPAT_INCLUDE_DIR=E:/Programme/Expat_2.1.0/Source/lib F:/work/git/dbus-win-20140805/dbus/cmake + + +------------------------------------------- 64-bit: +- md dbus-build64 + +- md dbus-build64 + +- add2path e:\Programme\expat-2.1.0-64bit\bin + +- "e:\Programme\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86_amd64 + +- "E:\Programme\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86_amd64 + "E:\Programme\Microsoft Platform SDK for Windows Server 2003 R2\SetEnv.Cmd" /XP64 /RETAIL + ? "E:\Programme\Microsoft Platform SDK for Windows Server 2003 R2\SetEnv.Cmd" /AMD64 /RETAIL ? + +cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=E:/Programme/dbus-20140805-64bit -DEXPAT_LIBRARY=E:/Programme/expat-2.1.0-64bit/lib -DEXPAT_INCLUDE_DIR=E:/Programme/expat-2.1.0-64bit/include F:/work/git/dbus-win-20140805/dbus/cmake + + +------------------------------------------- both + + +nmake + +nmake install + +nmake help + + +---- add'tl infos: ---- + +--> // MAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel. +--> CMAKE_BUILD_TYPE:STRING=Debug +to change: + + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_BUILD_TYPE=RelWithDebInfo + -DCMAKE_BUILD_TYPE=MinSizeRel + + +---- creating 64-bit expat for Windows: + +get tarball from <http://sourceforge.net/projects/expat/files/expat/2.1.0/>, +extract + +goto expat-directory, create subdir "md expat-210-64bit", change into it + +issue: + +cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=E:/Programme/expat-2.1.0-64bit F:/download/windows/expat/work64/expat-2.1.0 + Property changes on: sandbox/rgf/misc/dbusoorexx/dev/rony-dbus-cheat-sheet.txt ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: sandbox/rgf/misc/dbusoorexx/doc/201112-DBus4ooRexx-article.pdf =================================================================== (Binary files differ) Index: sandbox/rgf/misc/dbusoorexx/doc/201112-DBus4ooRexx-article.pdf =================================================================== --- sandbox/rgf/misc/dbusoorexx/doc/201112-DBus4ooRexx-article.pdf 2014-08-05 18:35:29 UTC (rev 230) +++ sandbox/rgf/misc/dbusoorexx/doc/201112-DBus4ooRexx-article.pdf 2014-08-06 17:25:57 UTC (rev 231) Property changes on: sandbox/rgf/misc/dbusoorexx/doc/201112-DBus4ooRexx-article.pdf ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/pdf \ No newline at end of property Modified: sandbox/rgf/misc/dbusoorexx/libdbusoorexx.dylib =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/libdbusoorexx32.so =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/libdbusoorexx64.so =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPongDoingOtherStuff.rex =================================================================== --- sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPongDoingOtherStuff.rex 2014-08-05 18:35:29 UTC (rev 230) +++ sandbox/rgf/misc/dbusoorexx/tests/privateDBusServer/b_PrivateServerPongDoingOtherStuff.rex 2014-08-06 17:25:57 UTC (rev 231) @@ -63,6 +63,7 @@ say "server~address: " pp2(server~address) say "server~serverAddress: " pp2(server~serverAddress) +say "on Windows fetching the session and/or system bus will fail as of DBus 1.8.99." signal on syntax signal on halt This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2014-09-16 16:07:37
|
Revision: 239 http://sourceforge.net/p/bsf4oorexx/code/239 Author: orexx Date: 2014-09-16 16:07:23 +0000 (Tue, 16 Sep 2014) Log Message: ----------- 20140916 Comment code oorexxdoc/javadoc-like. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-09-16 16:06:22 UTC (rev 238) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-09-16 16:07:23 UTC (rev 239) @@ -1,7 +1,63 @@ #!/usr/bin/rexx +/** This program makes the Linux DBus infrastructure available to ooRexx in an easy to use manner. It is closely intertwined +* with the accompanying native ooRexx library. Therefore do not change any code unless you <em>know</em> what you are doing! :) +* +* These are the core classes that are defined in this package: + +<ul> + +<li>DBus +<br> Represents a DBus connection and among other things allows for registering ooRexx DBus signal listeners and +ooRexx service objects. +</li> + +<li>DBusProxyObject +<br>Represents a remote DBus service object with all its defined properties, signals and messages. +</li> + +<li>DBusServiceObject +<br>Makes it easy to use a Rexx object as a DBus service object. +</li> + +<li>DBusServer +<br>Represents a private DBus server. +</li> + +<li>IDBus +<br>This class ("introspect DBus") allows to introspect a DBus service object's introspection XML data. +</li> + +<li>IntrospectHelper +<br>Allows to create introspect data programmatically, its <code>makeString</code> method will turn the definitions into a valid introspection XML-file +</li> + +<li>IDBusPathMaker +<br>Allows to create the infrastructure to serve DBus object paths for service objects. +</li> + +</ul> +* +* The <code>.local</code> environment contains an entry named <code>DBUS.DIR</code> which contains DBus related entries. Two entries control +whether this package outputs debug information or not, depending on the logical values of its entries named: +<ul> +<li><code>bDebug</code> +</li> + +<ul> +<li><code>bDebugServer</code> +</li> + +* +* @author Rony G. Flatscher +* @since 2011-06-11 +* @version 1.00 +* +*/ + + /* author: Rony G. Flatscher (C) 2011 - date: 2011-08-07 (2011-06-11, 2011-07-19) + date: 2011-08-12 (2011-06-11, 2011-07-19) name: dbus.cls purpose: make the DBUS language binding for ooRexx available needs: - dbus-message bus system installed (by default available on Linuxes) @@ -13,7 +69,7 @@ cf.: dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> (as of 2011-07-14) - version: 100.20140807 + version: 100.20140916 changes: - 2011-07-20, rgf; DBusProxyObject: - added proxy.dispatch(methodName[,args...])-method to send messages that @@ -91,6 +147,7 @@ <http://sourceforge.net/p/oorexx/bugs/1275> gets fixed - 2014-08-07, rgf: - tidied up the code - removed dependency on rgf_util2.rex + - 2014-08-11 through 20140916, rgf: - add oorexxdoc comments license: Apache License 2.0 @@ -113,7 +170,10 @@ */ -.local~dbus=.dbus -- save .DBus class in .local to allow native code to use FindClass("DBUS") successfully +.local~dbus=.dbus -- save .DBus class in .local to allow native code to use FindClass("DBUS") successfully + -- as of ooRexx 4.2.0 (Sept 2014) it may be the case that the native code finds this + -- class by mistake; putting it into .local makes sure that the native code will always + -- find it "legally" :) /* Defining dbus shared constants, leaving the dbus names untouched, such that dbus-samples employing these constants can be easily transcribed to Rexx. @@ -124,7 +184,7 @@ .dbus.dir~bDebug =.false -- .true -- .false -- .true .dbus.dir~bDebugServer=.false -- .true -- .false -- .true -.dbus.dir~version="100.20140807" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' +.dbus.dir~version="100.20140916" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' .dbus.dir~DBUS_SERVICE_DBUS ="org.freedesktop.DBus" -- "The bus name used to talk to the bus itself." .dbus.dir~DBUS_PATH_DBUS ="/org/freedesktop/DBus" -- "The object path used to talk to the bus itself." @@ -206,6 +266,9 @@ -- ::requires "rgf_util2.rex" -- installed with the BSF4ooRexx package +/** This routine requires dynamically the ooRexx package <code>BSF.CLS</code> and +* in the case it is not available will allow to continue gracefully. +*/ ::routine dynamicRequiresBSF4ooRexx -- BSF4ooRexx: needed need for UTF-8 conversion routines signal on any if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -216,14 +279,19 @@ -/* =============================================================================== */ +/* ============================================================================================= */ /* Define the DBus class, which allows connecting, getting objects to talk to, adding own servers on the bus. */ +/** This class represents a DBus connection. It allows connecting, getting service objects +* to send messages to, adding own service objects and listener objects on the bus. +*/ ::class "DBus" public inherit Worker /* --- class methods ------ */ +/** Class constructor method for initializing class attributes. +*/ ::method init class expose system session tid2human tid2human=.directory~new -- attribute that allows to translate TIDs into human readable form @@ -232,6 +300,12 @@ -- will be usually called from native DbusGetTID(), which allows one optional argument indicating the desired formatting +/** Class method that is being used by native code to turn the inconceivable thread ids into human legible values. +* +* @param tid the thread id number +* @param option H[uman readable] (default) or S[system] (thread id number) +* @return thread id according to the given option +*/ ::method formatTID unguarded class -- unguarded (access to tid2human only in here) expose tid2human use strict arg tid, option="H" @@ -256,9 +330,17 @@ /* unique id for the computer */ +/** Gets and returns the machine's id according to DBus. +* +* @return machine's id according to DBus +*/ ::method machineID class external "LIBRARY dbusoorexx DbusGetUniqueMachineId" +/** Establishes and returns a connection to the<code>system</code> on DBus, and caches that connection. +* +* @return returns the connection to the <code>system</code> bus on DBus +*/ ::method system class /* returns the shared system bus connection */ expose system if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "arg(1):" pp(arg(1)) @@ -274,6 +356,10 @@ return system +/** Establishes and returns a connection to the<code>session</code> on DBus, and caches that connection. +* +* @return returns the connection to the <code>session</code> bus on DBus +*/ ::method session class /* returns the shared session bus connection */ expose session if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "arg(1):" pp(arg(1)) @@ -289,13 +375,24 @@ return session - +/** Creates a new connection and returns it, using the <code>NEW</code> class method. +* +* @see NEW class method +*/ ::method connect class /* connect to an existing dbus connection */ if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) forward message ("NEW") -- let our version of NEW handle this - +/** Creates a new connection and returns it. +* +* @param address the address to connect to; special address names are "system" and "session" +* @return instance of this class representing the connection +* +* @see session class method +* @see system class method +* +*/ ::method new class expose system session use strict arg address @@ -341,8 +438,13 @@ syntax: raise propagate -- raise in caller +/** The address to which the connection is established. +* +*/ ::attribute address get +/** Setter method for the native library to allow setting a pseudo address for private connections (to private servers). +*/ ::attribute pseudoAddress set -- 20140728, rgf: allows private server to set a pseudo address for each connected client expose address use strict arg address -- just assign whatever we receive @@ -352,6 +454,10 @@ /* much is implemented in native code, including setting attributes 'address', 'uniqueBusName' and 'wellKnownBusName', if given */ + +/** Constructor method that initializes attributes. Note, the native code will set the values of +* some of the attributes! +*/ ::method init expose cself busType address makeSlotDir makeReplySlotDir active - internalRegisteredServiceObjects internalSignalListeners - @@ -404,7 +510,9 @@ ::method nativeGetSystemBus private external "LIBRARY dbusoorexx DbusNativeGetSystemBus" ::method nativeGetSessionBus private external "LIBRARY dbusoorexx DbusNativeGetSessionBus" - +/** Connect to the given address and start the message loop for this connection. +* @param address to connect to +*/ ::method connectToAddress -- unguarded expose active if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -437,16 +545,16 @@ end else do -say " -> self~nativeConnectPrivate(address)" pp(address) "-->" +-- say " -> self~nativeConnectPrivate(address)" pp(address) "-->" self~nativeConnectPrivate(address) -- create a private connection to the address -say " <- self~nativeConnectPrivate(address)" +-- say " <- self~nativeConnectPrivate(address)" end self~startMessageLoop -- will start message loop in its own thread -/* controls whether a received message call without defined return value will return an empty message reply */ +/** Controls whether a received message call without defined return value will return an empty message reply */ ::attribute sendEmptyReply get ::attribute sendEmptyReply set -- default: .true (append slotDir as last argument) expose sendEmptyReply @@ -462,9 +570,9 @@ syntax: raise propagate - /* attribute controls whether the arguments from a signal or a remote method call get + /** Attribute controls whether the arguments from a signal or a remote method call get appended with a slotDir-directory supplying possibly useful information about the - DBUS message; default: .true + DBus message; default: <code>.true</code> */ ::attribute makeSlotDir get ::attribute makeSlotDir set -- default: .true (append slotDir as last argument) @@ -481,9 +589,9 @@ syntax: raise propagate - /* attribute controls whether the arguments from a reply (result of calling a message on - a remote DBUS object) will get appended with a slotDir-directory supplying possibly - useful information about the DBUS message; default: .false + /** Attribute controls whether the arguments from a reply (result of calling a message on + a remote DBus object) will get appended with a slotDir-directory supplying possibly + useful information about the DBUS message; default: <code>.false</code> */ ::attribute makeReplySlotDir get ::attribute makeReplySlotDir set -- default: .false (do not append slotDir to result of a message call (turning result into an array object) @@ -500,8 +608,8 @@ syntax: raise propagate - /* attribute controls whether byte arrays (signature 'ay') should be unmarshalled as - Rexx string instead of a Rexx array with individual bytes + /** Attribute controls whether byte arrays (signature 'ay') should be unmarshalled as + Rexx strings instead of a Rexx array with individual bytes */ ::attribute unmarshalByteArrayAsString get ::attribute unmarshalByteArrayAsString set -- default: .true (append slotDir to result of a message call (turning result into an array object) @@ -518,13 +626,23 @@ syntax: raise propagate +/** Determines whether statistics about the messages and signals should be maintained; default: <code>.true</code>. +*/ ::attribute collectStatistics -- default: .true (keep slotDirs of last received messages/errors/signals and their respective counters) + +/** Storage for collected statistics, a Rexx directory. +*/ ::attribute statistics -- a directory + +/** If set to <code>.true</code>, then an unexpected Rexx condition will cause all Rexx threads to be halted. +*/ ::attribute haltAllThreadsOnUnexpectedError -- if set to .true, then an unexpected Rexx condition will cause all Rexx threads to be halted /** Method blocks until connection got closed and message loop thread stopped, turning attribute * <code>active</code> to <code>.false</code>. +* +* @since 2014-08 */ ::method waitOnConnectionClosed unguarded expose active @@ -534,6 +652,8 @@ ::method nativeStartMessageLoop private external "LIBRARY dbusoorexx DbusMessageLoop" +/** Starts a connection's message loop, will be automatically invoked when a connection is established. +*/ ::method startMessageLoop unguarded expose active stopLoop address busType if .dbus.dir~bDebug=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "arrived" @@ -566,6 +686,28 @@ -- 2014-07-23: do not allow to start message loop by third parties! +/** Obsolete implementation, do not use anymore! +* +* @param action +<ul> +<li>"<code>start</code>": automatically done at connection creation time. +</li> + +<li>"<code>stop</code>": automatically done in method <code>close</code> +</li> + +<li>"<code>wait</code>": replaced by method <code>waitOnConnectionClosed</code> +</li> + +<li>"<code>active</code>": replaced by the get attribute named <code>active</code> +</li> + +</ul> +* +* +* @deprecated +* @since 2014-07-23 deprecated +*/ ::method messageLoop unguarded -- query, start, stop messageLoop, waitUntilStopped expose active stopLoop bustype parse upper arg action . @@ -595,6 +737,7 @@ ::method nativeCloseConnection private EXTERNAL "LIBRARY dbusoorexx DbusNativeConnectionClose" +/** Close connection, which cannot be used for exchanging messages anymore. */ ::method close -- unguarded -- close (private) connection expose busType address statistics active stopLoop @@ -626,6 +769,25 @@ ::method nativeIsAuthenticated private external "LIBRARY dbusoorexx DbusConnectionIsAuthenticated" ::method nativeCanSendType private external "LIBRARY dbusoorexx DbusConnectionCanSendType" +/** Allows to query some state information on the connection returning either <code>.true</code> or <code>.false</code>. +* +* @param option can be one of: +<ul> +<li><code>"A[uthenticated]"</code> or <code>"IsA[uthenticated]"</code>, +</li> + +<li><code>"O[pen]"</code> or <code>"IsO[pened]"</code> or + <code>"C[onnected]"</code> or <code>"IsC[onnected]"</code>, +</li> + +<li><code>"T[ypecode]"</code>: this option allows for a second argument which must be one or more of the DBus type character codes; if the +second argument is omitted, then a comma separated list of all supported type (codes) gets returned, instead of a Boolean value +</li> + +</ul> + +* +*/ ::method query unguarded -- reroute invocation through message loop thread expose active stopLoop address bustype if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -720,6 +882,11 @@ supports() ... return "typeCodes={a,...,x}" ... returns string denoting available types supports("T[ypecode]", typecode) ... returns .false/.true; typecode can be a string: only returns .true then, if all characters are supported type codes */ + +/** Checks whether the connection supports exchanging values of the given type (codes). If omitting the typecode argument, +* then a comma-delimited string of supported type codes gets returned. +* +*/ ::method canSendTypeCode private -- this name is neutral enough to allow extensions, if other connection-related tests are needed if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) if arg()=0 then @@ -745,7 +912,8 @@ return .true - +/** Destructor method that makes sure that the connection gets closed, if still active. +*/ ::method uninit -- make sure we stop the message loop thread, if necessary expose busType active @@ -762,6 +930,16 @@ /* add listener object, syntax: - a[dd] | r[emove], object [,[interface] [,signalname]] - g[etListeners] */ +/** Allows to add, remove or get all ooRexx signal listeners. +* +* @param action one of <code>"a[dd]"</code>, <code>"r[emove]"</code>, <code>"g[etListeners]"</code> +* @param listenerObject mandatory for adding, optional for removing (all listener objects qualify) +* @param interface optional, the DBus interface to listen to, if omitted any interface will be monitored +* @param signalName optional, the signal name to listen to, if omitted any signal will be handled +* @return <ul><li>add<br><code>.true</code></li> + <li>remove<br>number of listener objects removed</li> + <li>getListeners<br>a copy of the listener objects array +*/ ::method listener unguarded expose internalSignalListeners internalRegisteredServiceObjects @@ -824,6 +1002,23 @@ - r[emove], objectPath - g[etRegisteredServiceObjects] */ +/** Allows to add, remove or get all ooRexx service objects for this connection. If the service +* objects are subclasses of the class <code>DBusService</code> then the support for introspection +* utilities like DFeet is set up automatically. For all other ooRexx service objects, one may +* add that particular object path introspection support by using the special "default" +* in place of the object path (second argument) and supplying an instance of <code>IDBusPathMaker</code> +* as the third argument. +* +* @param action one of <code>"a[dd]"</code>, <code>"r[emove]"</code>, <code>"g[etListeners]"</code> +* @param objectPathmandatory for adding, optional for removing (all object paths qualify); if +* the special string "default" is being used, then the third argument must be an +* instance of @see <code>IDBusPathMaker</code> +* @param serviceObject mandatory for adding, optional for removing (all service objects qualify) +* @return <ul><li>add<br>old service object that got replaced, <code>.nil</code> else</li> + <li>remove<br>number of service objects removed</li> + <li>getListeners<br>a copy of the service objects directory +*/ + ::method serviceObject unguarded expose internalSignalListeners internalRegisteredServiceObjects -- a directory if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -906,15 +1101,24 @@ +/** Set by native code, stores the native connection pointer, if connection is active. */ +::attribute cself /* native's representation of this dbus object, set in native code */ -::attribute cself /* native's representation of this dbus object, set in native code */ -::attribute busType /* bustype for the dbus connection, if any; - DBusBusType defines types that will be named - "session", "system", "starter" and maybe "private" in Rexx*/ +/** One of <code>"session"</code>, <code>"system"</code>, <code>"native"</code>, or <code>"private"</code>. */ +::attribute busType /* bustype for the dbus connection, if any; DBusBusType defines types that will be named + "session", "system", "native" and maybe "private" in Rexx */ + +/** If set, a (private) connection to the server. + @see <code>DBusServer</code> +*/ ::attribute server /* if set, connection belongs to a DBusServer (i.e. a client connection) */ /* unique id for the bus */ ::method nativeUniqueBusID private external "LIBRARY dbusoorexx DbusGetUniqueBusId" + +/** Returns the uniqe bus id of this connection. +* @return unique bus id +*/ ::method uniqueBusID expose stopLoop address bustype if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -951,7 +1155,32 @@ ::method nativeBusNameHasOwner private external "LIBRARY dbusoorexx DbusBusNameHasOwner" -- deprecated! ::method nativeReleaseBusName private external "LIBRARY dbusoorexx DbusBusNameRelease" +/** Allows to request and to release a bus name, query whether a bus name has an owner and query athe unique bus name. +* +* @param function on of <code>"req[uest]"</code>, <code>"h[asOwner]"</code>, <code>"rel[ease]"</code>, <code>"u[niqueName]"</code> +* @param flags if <code>"req[quest]"</code> function, can be one of or addition of (constant names can be used against <code>.dbus.dir</code> +<ul> +<li>1 - DBUS_NAME_FLAG_ALLOW_REPLACEMENT</li> +<li>2 - DBUS_NAME_FLAG_REPLACE_EXISTING</li> +<li>4 - DBUS_NAME_FLAG_DO_NOT_QUEUE</li> +</ul>; if this argument is omitted the default value used will be <code>7</code> (all options set), cf. <a href="http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-names">http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-names</a> +* +* @return in the case of function <code>"req[uest]"</code>: +<ul> +<li>1 - DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER</li>, +<li>2 - DBUS_REQUEST_NAME_REPLY_IN_QUEUE</li>, +<li>3 - DBUS_REQUEST_NAME_REPLY_EXISTS</li>, +<li>4 - DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER</li>, +</ul> +in the case of function <code>"rel[ease]"</code>: +<ul> +<li>1 - DBUS_RELEASE_NAME_REPLY_RELEASED</li>, +<li>2 - DBUS_RELEASE_NAME_REPLY_NON_EXISTENT</li>, +<li>3 - DBUS_RELEASE_NAME_REPLY_NOT_OWNER<li>, +</ul> +else no return value +*/ ::method busName -- route invocation through the message loop thread expose stopLoop address bustype if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1042,8 +1271,12 @@ ::method nativeAddMatch private external "LIBRARY dbusoorexx DbusBusAddMatch" ::method nativeRemoveMatch private external "LIBRARY dbusoorexx DbusBusRemoveMatch" -/** Delegate invocation to message loop thread using the Worker's class infrastructure. This way - invoking DBUs-connection related invocations take place in the thread, that +/** Allows to add or remove a DBus match rule, cf. <a href="http://dbus.freedesktop.org/doc/dbus-specification.html#bus-messages-add-match">http://dbus.freedesktop.org/doc/dbus-specification.html#bus-messages-add-match</a> +* +* @param action <code>"A[dd]"</code> or <code>"r[emove]"</code>a match rule +* @param filter the match rule (a string) for matching DBus messages, cf. <a href="http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules">http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules</a> +* @param block optional, determines whether the call should block or not, default: <code>.false</code> +* */ ::method match -- reroute invocation through message loop thread expose stopLoop address bustype @@ -1094,6 +1327,47 @@ /* folding methods of the "message" group into one parametrized method */ +/** Call a message or issue a signal message. The arguments differ, depending whether a called method or an issued signal is intended. +* +* The parameters for a call: +* <ul> +* <li>C[all]</li> +* <li>busName</li> +* <li>targetObjectPath</li> +* <li>interface (optional)</li> +* <li>methodName</li> +* <li>replySignature (optional)</li> +* <li>argSignature (optional)</li> +* <li></li> +* </ul> +* +* The paramters for a signal: +* <ul> +* <li>S[ignal]</li> +* <li>senderObjectPath</li> +* <li>interface</li> +* <li>signalName</li> +* <li>signature (optional)</li> +* </ul> +* +* @param function <code>"C[all]"</code> or <code>"S[ignal]"</code> +<br>if a call, the parameters are: +* @param busName (call) a valid (existing) bus name +* @param targetObjectPath (call) a valid (existing) path to the target object that the message is directed to +* @param interface (call) optional, defaults to empty string +* @param methodName (call) the name of the method to call +* @param replySignature (call) optional, defaults to empty string, determines the signature for the return value +* @param argSignature (call) optional, defaults to empty string, determines the signature for the arguments + +<br>if a signal, the parameters are: +* @param busName (signal) +* @param senderObjectPath (signal) the object path of the signal sender +* @param interface (signal) +* @param signalName (signal) the name of the signal +* @param signature (signal) optional, defines the types of optional arguments +* +* @return whatever value a called message returns +*/ ::method message -- send message to service object; reroute invocation through message loop thread expose stopLoop address bustype if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "/// arg(5):" pp(arg(5)) @@ -1185,7 +1459,15 @@ raise propagate -- raise any other error in caller - +/** Request access to a remote object to interact with, returns a <code>DBusProxyObject</code>. The resulting proxy DBus object +* is able to understand ooRexx messages and translates them transparently to the necessary DBus message calls "behind the curtain", +* making it very easy to interact with remote DBus objects. +* +* @param busName where the remote object is located +* @param objectPath path to the object +* @return a <code>DBusProxyObject</code> to which one can send ooRexx messages by the name of the DBus message the +* remote object can understand +*/ ::method getObject unguarded -- request remote object, return a Rexx proxy object to allow interaction with it use strict arg busName, objectPath if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1205,7 +1487,12 @@ raise propagate - +/** Queries and returns the object paths on a given bus name. +* +* @param busName the bus name to search for objects +* @return an array of object paths reachable via the supplied bus name +* +*/ ::method getObjectPaths unguarded -- return an array of object paths for the supplied bus name / service name use strict arg busName if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1221,7 +1508,6 @@ return objectPathList - ::method workerGetObjectPaths unguarded private -- interrogates service possessing bus/service name for object paths (if that service supports that) use arg objPath, busName, objectPathList if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1273,6 +1559,13 @@ /* ---------------------------------------------------------------------------------------- */ /* as of 2011-07-05 ooRexx from trunk does not support UTF-8, hence depending on BSF4ooRexx */ +/** Routine that encodes a string to UTF-8. If <code>BSF4ooRexx</code> (a Sourceforge package to bridge ooRexx with Java) is available, then Java is used to carry out the encoding, +* otherwise an algorithm from Mike F. Cowlishaw ("father of Rexx") is employed instead. +* +* @param str string to encode +* @return UTF-8 encoded string +* +*/ ::routine stringToUtf8 public -- needs BSF4ooRexx parse arg str if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1306,6 +1599,11 @@ /* ---------------------------------------------------------------------------------------- */ +/** This routine decodes UTF-8 using Java, therefore needs <code>BSFooRexx</code> (a Sourceforge package to bridge ooRexx with Java). +* +* @param str UTF-encoded string +* @return decoded string +*/ ::routine utf8ToString public -- needs BSF4ooRexx parse arg str if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1313,6 +1611,17 @@ /* ---------------------------------------------------------------------------------------- */ +/** Routine that forces encoding values according to the supplied signature. This makes it possible to force a certain signature on +* values that some DBus applications mandate, eg. in the context of variants, where the marshalling of the variant itself must be +* done according to the target application. +* +* @param signature a valid DBus signature +* @param argument optional, otherwise the argument(s) to marshall; if omitted the native marshalling code will create marshal values +* that correspond to the 0-value or empty strings of the respective types +* @return a two-element array, the first entry containing the string "useThisSignature=" followed by the signature, +* the second entry containing the argument(s); the native marshalling code will then marshal the arguments accordingly +* +*/ ::routine dbus.box public -- for variant types or overruling reply signatures, allow boxing use strict arg signature, argument=.nil if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1333,6 +1642,14 @@ /* ---------------------------------------------------------------------------------------- */ /* allow for sending error-messages instead of a reply back to the invoker, will get honored in the message loop of the DBus connection that invoked the Rexx method calling this routine */ +/** This routine is meant to be called from an ooRexx service object while processing a DBus message in the case that an error reply should be +* transported back to the caller. +* +* @param errName optional (default: <code>"org.freedesktop.DBus.Error.RexxServiceRaised"</code> +* @param errMessage optional (default: .nil) +* @condition 93.900 +* +*/ ::routine raiseDBusError public -- this condition will be turned into an error-message in native code use arg errName="org.freedesktop.DBus.Error.RexxServiceRaised", errMessage=.nil if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1343,16 +1660,29 @@ /* ---------------------------------------------------------------------------------------- */ -/* return the version information that includes the library version and this package's version */ +/** Returns the version information that includes the library version and this package's version information. +* +* @return version string formatted as: <code>"library dbusoorexx=[major*100+minor.yyyymmdd], compile-time dbus=[major.minor.micro], runtime dbus=[major.minor.micro], dbus.cls=[major*100+minor.yyymmdd]"<code> +*/ ::routine DBusVersion public if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) return DBusVersionLibrary()", package dbus.cls=[".dbus.dir~version"]" -/* =============================================================================== */ +/* ============================================================================================= */ /* ooRexx proxy for a DBus object, responsible for processing messages */ + +/** Proxy class representing a remot DBus object to interact with using ooRexx messages. +*/ ::class "DBusProxyObject" public +/** Constructor method that initializes the attributes, introspects the remote DBus object using the result for transparent interaction with it (if avalable). An ooRexx programmer merely needs to +* send ooRexx messages and supply arguments without type information! The proxy will transparently reformulate the ooRexx messge into the appropriate DBus message call. +* +* @param proxy.connection the connection (a DBus object) to use +* @param proxy.busname the busname to use +* @param proxy.objectPath the object path to the remote DBus object +*/ ::method init expose proxy.busname proxy.connection proxy.objectPath proxy.methods proxy.introspectData use strict arg proxy.connection, proxy.busname, proxy.objectPath @@ -1394,7 +1724,12 @@ ::attribute proxy.methods get /* make introspection parse tree available */ - +/** Method that processes the intrsospect data or a file that contains the XML encoded introspection data for the remote object. +* +* @param introData either the introspect data or a file containing the XML encoded introspect data +* @return introData the method received as argument +* +*/ ::method proxy.parseIntrospectData -- parse introspect data, memorize introspectData and introspectFileName, if any expose proxy.introspectData proxy.introspectFileName use strict arg introData @@ -1425,8 +1760,12 @@ raise propagate -- raise condition in caller - - +/** Pass-through method for DBus messages that have ooRexx method implementations, which would therefore not be passed on. Any arguments +* supplied to the message will be forwarded as arguments for the DBus method call. +* +* @param methodName DBus method name to be called +* @return the return value from the DBus message call, if any +*/ ::METHOD proxy.dispatch -- allow sending messages that would be intercepted on the Rexx side (e.g. by .Object) parse arg methodName if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1436,6 +1775,10 @@ return +/** This method turns the received ooRexx message into the appropriate DBus message call +* using the introspection data for the remote object. The support includes camouflaging +* DBus properties as ooRexx attributes. +*/ ::method unknown -- implements sending message calls to remote object expose proxy.busname proxy.connection proxy.objectPath proxy.methods use arg msgName, msgArgs @@ -1519,11 +1862,20 @@ -/* =============================================================================== */ +/* ============================================================================================= */ /* Allows an ooRexx object to listen to DBus signals. Intentionally not public. Will be used by method 'listener' subfunction 'add' and will be retrieved by the native code. */ +/** Class that gets used by the method <code>listener</code> in the class <code>DBus</code> to wrap an ooRexx object that should +* get invoked whenever a signal is received. +* +* @param listenerObject the ooRexx listener object +* @param interface optional, if present restricts the listening to signals from this DBus interface +* @param signalName optional, if present restricts the listening to this signal name +* +* @see method <code>listener</code> in the class <code>DBus</code> +*/ ::class "DBUSSignalListener" ::method init @@ -1536,14 +1888,22 @@ ::attribute signalName -/* =============================================================================== */ +/* ============================================================================================= */ /* Allows an ooRexx object to serve DBus method invocations in an easy manner, by adding the ability to e.g. dynamically determine replySignatures from the introspect data or make it rather easy for a service object to emit signals, etc. Definition of this class allows it to be used as a mixin. */ +/** Base class for allowing an ooRexx class to be used for implementing a DBus service. +* +*/ ::class "DbusServiceObject" mixinclass object public +/** Constructor method to initialize attributes and to process the optionally supplied introspection data that defines the services available to DBus clients. +* +* @param introData optional introspection data +* +*/ ::method init -- intorData, service.connection, service.objectPath; introData may be supplied later, using the respective methods expose service.connections service.introspectRootNode service.methods if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1566,6 +1926,11 @@ raise propagate -- raise condition in caller +/** Method that analyzes and sets up introspection data for this DBus service. +* +* @param introData introspection data to parse, can be a file name containing the XML data +* @return introData the received argument value +*/ ::method service.parseIntrospectData -- parse introspect data, memorize introspectData and introspectFileName, if any expose service.introspectData service.introspectFileName if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1600,7 +1965,10 @@ raise propagate -- raise condition in caller - +/** Implements the DBus Introspect method to allow potential DBus service clients to learn about the published interfaces. +* +* @return the XML encoded introspect data +*/ ::method Introspect -- return introspection data to client expose service.introspectData if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1612,6 +1980,9 @@ ::attribute service.introspectData get ::attribute service.introspectFileName get +/** Attribute setter method that allows to set the introspection root node attribute. In addition any methods in the introspection data get cached for faster lookup. +* +*/ ::attribute service.introspectRootNode set /* make introspection parse tree available */ expose service.methods service.introspectRootNode if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1640,6 +2011,16 @@ return .nil -- no signature/member found +/** Utility method to make issuing a signal easy through all the connections that we currently serve. If the service object has introspection methods +* defined and cached, then this definition is looked up to determine the signal's interface and signature. +* +* @param objectPath optional, DBus object path of sender, defaults to <code>.nil</code> +* @param interface optional, DBus interface name, defaults to empty string +* @param member signal name +* @param signature optional, argument signature, defaults to empty string +* @param arg1...argN optional arguments to be sent with the signal +* +*/ ::method service.sendSignal -- utility method to ease emitting signals from the service object; -- will emit the signal to all connections this service object is registered with expose service.methods service.connections @@ -1716,6 +2097,9 @@ /* service requests */ +/** This method turns the received ooRexx message into the appropriate DBus message call using the +* introspection data for the service object. +*/ ::method unknown expose service.methods if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -1833,14 +2217,37 @@ -/* =============================================================================== */ +/* ============================================================================================= */ /* ------------------------------------------------------------------------------------- */ /* DbusDataType( value [,typeName]) typeNames: B[usName], I[nterfaceName], M[emberName], O[bjectPath], S[ignature] modelled after Rexx' DataType(...) */ -::routine DbusDataType public -- check or determine whether dbus datatype + +/** Routine that determines which DBus datatype a value may be (or <code>.nil</code>, if not determinable) or +* tests whether a supplied value is of the given DBus datatype. +* +* @param a string value representing a DBus value of type <code>"B[usname]"</code>, +* <code>"I[nterface]"</code>, <code>"M[ember]"</code>, +* <code>"O[bjectPath]"</code> or <code>"S[ignature]"</code> +* +* @param optional, one of <code>"B[usname]"</code>, <code>"I[nterface]"</code>, +* <code>"M[ember]"</code>, <code>"O[bjectPath]"</code> or +* <code>"S[ignature]"</code> +* +* @return <dl> +* <dt>if only the first argument is supplied, then returns either +* <dd><code>"OBJECTPATH"</code>, <code>"INTERFACENAME"</code>, +* <code>"BUSNAME"</code>, <code>"MEMBERNAME"</code> or +* <code>.nil</code>, if neither of these types can be determined +* +* <dt>if both arguments are supplied, then the first argument is tested whether it +* is of the DBus type expressed in the second argument, returning +* <dd><code>.true</code> or <code>.false</code>, respectively +* </dl> +*/ +::routine DBusDataType public -- check or determine whether dbus datatype parse arg value, type . if .dbus.dir~bDebug=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -2136,10 +2543,26 @@ /* =============================== DBusServer ====================================================== */ --- a private ooRexx DBus server implemenation; connection to clients using .DBus +-- ; connection to clients using .DBus /* ------------------------------ class definition ------------------------------ */ +/** This class is a private ooRexx DBus server implementation which makes it easy to use ooRexx +* to create a private DBus server, serving any clients via DBus, independent of their location +* (usually communicating via Internet) and operating system (provided the DBus infrastructure +* is available on the client's computer). +*/ ::class "DBusServer" public +/** Constructor method that initializes attributes. Note, the native code will set the values of +* some of the attributes! +* +* @param address a private DBus server address, this server should listen to +* @param defaultService optional, a DBusService ooRexx object that supplies the default services +* to any new connected client +* @param defaultListener optional, an ooRexx object that will be used as the listener for any new +* connected client +* @param allowAnonymous optional, defaults to <code>.false</code>; if set to <code>.true</code> +* then connections from anonymous clients are acceptable +*/ ::method init expose cself address allowAnonymous defaultService defaultListener connections - watchLoopActive watchlist timeoutLoopActive watchConnections @@ -2168,13 +2591,26 @@ ::attribute allowAnonymous -- allow anonymous clients to connect ::attribute defaultService -- default Rexx service object, used, if no matching entry found in internalRegisteredServiceObjects ::attribute defaultListener -- default Rexx listener object, used, if internalSignalListeners is empty + +/** Getter definition for the attribute <code>connections</code>. +* @return a copy of the connection array +*/ ::attribute connections get -- list of established connections expose connections if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) return connections~copy -- return a copy of the current connections +/** Getter definition for the attribute <code>watchLoopActive</code>. +* @return <code>.true</code>, if the server message loopo is active, <code>.false</code> else +*/ ::attribute watchLoopActive get -- indicates whether the server message loop is active or not +/** Do not use ! Method gets invoked by the native code whenever a new client connects to this private DBus server, such +* that the connection's message loop can be started, allowing the client to use it to interact with +* this private DBus server. +* +* @param the connection through which the client connected to this private DBus server +*/ ::method newConnection -- new connection to this server received (from callback in native code) expose defaultService defaultListener connections watchConnections if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -2208,7 +2644,12 @@ return - +/** Method gets invoked by the native code whenever a connection gets lost. The method +* will close the connection and remove it from the <code>connections</code> attribute that maintains +* all served connections. +* +* @param the connection through which the client connected to this private DBus server +*/ ::method disconnect -- invoked from native code (not reliably invoked all the time as of 1.6.4 on Ubuntu) expose connections if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -2219,8 +2660,14 @@ ::method nativeServerWatchLoop private external "LIBRARY dbusoorexx DbusServerWatchLoop" -::method nativeServerStartup private external "LIBRARY dbusoorexx DbusNativeServerStartup" -::method startup unguarded -- startup server +::method nativeServerStartup private external "LIBRARY dbusoorexx DbusNativeServerStartup" + + +/** This method will startup the private server and start the server's watch loop. +* +* @conditition if server was already started a syntax 93.900 condition will be raised +*/ +::method startup unguarded -- startup server expose allowAnonymous cself address if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -2236,8 +2683,13 @@ if .dbus.dir~bDebugServer=.true then say "///" pp(.dateTime~new)", tid="pp(DbusGetTID()) "->" pp(self)":" pp(.context~executable) pp(.context~name) "line:" pp(.line) "AFTER : self~nativeServerWatchLoop" - -- as of DBus 1.4.14, the private server does not receive a "Disconnected" signal, hence testing the connections constantly +/** This method creates a Rexx thread which constantly watches connections to make sure +* that any stalled connections get disconnected. +* +* @param sleepTime optional argument (defaults to 0.1 second) that determines the sleeping time +* between checks +*/ ::method watchConnections unguarded -- check whether client connections are available, if not disconnect the stalled connecition expose connections watchConnections if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) @@ -2290,9 +2742,14 @@ return +::method nativeStartServerTimeoutLoop private external "LIBRARY dbusoorexx DbusServerTimeoutLoop" - -::method nativeStartServerTimeoutLoop private external "LIBRARY dbusoorexx DbusServerTimeoutLoop" +/** Do not use! Meant to be used from native code, if a timer callback is set or removed. +* +* @param "STArt" or "STOp" +* @param timeoutDataPointer if first argument has the value "STArt" an +* opaque value from the native code (a Pointer) +*/ ::method timerLoop unguarded -- "START" or "STOP" expose timeoutLoopActive if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) @@ -2314,16 +2771,20 @@ use strict arg action, timeoutDataPointer reply -- create a new thread -if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) "after REPLY" +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "after REPLY" self~nativeStartServerTimeoutLoop(timeoutDataPointer) -- start the timeout loop, pass (*data) via Rexx to native function ::method nativeServerShutdown private external "LIBRARY dbusoorexx DbusNativeServerDisconnect" + +/** This method shuts down the private server by stopping the watch loop, shutting down the server and +* disconnecting its clients and . +*/ ::method shutdown unguarded -- shutdown server expose connections cself watchLoopActive -if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) if cself=.nil then raise syntax 93.900 array (self": shutdown not possible, as server was not started") @@ -2342,25 +2803,38 @@ ::method nativeServerID private external "LIBRARY dbusoorexx DbusNativeServerGetId" +/** Returns this private server's ID from native code. +* +* @return the server's ID +*/ ::method serverID expose cself -if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) if cself=.nil then return .nil return self~nativeServerID ::method nativeActive private external "LIBRARY dbusoorexx DbusNativeServerIsActive" + +/** Tests whether this server is still active (connected). +* +* @return <code>.true</code>, if the server is active (connected), <ocde>.false</code> else +*/ ::method active expose cself -if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) if cself=.nil then return .false return self~nativeActive -- for debugging: ::method nativeServerAddress private external "LIBRARY dbusoorexx DbusNativeServerGetAddress" +/** Returns this private server's address from native code. +* +* @return the address this server is servicing +*/ ::method serverAddress expose cself -if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) "line:" pp(.line) +if .dbus.dir~bDebugServer=.true then say pp(DbusGetTID()) pp(.dateTime~new) pp(self) pp(.context~executable) pp(.context~name) "line:" pp(.line) if cself=.nil then return .nil return self~nativeServerAddress @@ -2374,23 +2848,43 @@ /* cf. <http://standards.freedesktop.org/dbus/1.0/introspect.dtd> */ /* ------------------------------ class definition ------------------------------ */ +/** This class parses DBus introspection data into a parse tree and makes its +* definitions available to clients. +* +* @see <http://standards.freedesktop.org/dbus/1.0/introspect.dtd> +*/ ::class "IDBus" public -- define base class, attributes name and content ::attribute name -- name: name of the element, CDATA ::attribute parent -- parent: node to which this one belongs to, if any ::attribute content -- content: whatever elements an element contains in document order +/** Caseless comparator method used by the array <code>sort</code> method. Allows to sort caselessly by name. +* +* @return <code>1</code>, <code>0</code> or <code>-1</code> if this name is lexically larger, + equal or smaller than the argument +*/ ::method compareTo -- allow for sorting by name expose name use arg otherValue return (self~class~id name)~caselessCompareTo(otherValue~class~id otherValue~name) - +/** Constructor method, initializing attributes. +* +* @param name optional (defaults to empty string) +*/ ::method init -- constructor expose name content node use strict arg name="" parent=.nil content=.array~new +/** Class method for creating the instrospection tree. +* +* @param data the introspection data adhering to the DBus Introspection DTD or +* a file name containing the Introspection data to parse +* +* @return the root node of the resulting introspection tree +*/ ::method newIntrospection class -- parses file/data, creates a parse tree and returns its root node use strict arg data -- "data" can be a filename or the introspection data @@ -2550,11 +3044,24 @@ raise propagate -- raise condition in caller +/** Tests wheter the introspection tree contains a node of the supplied type. +* +* @param kind optional, or one of <code>"I[nterface]"</code>, +* <code>"M[ethod]"</code>, +* <code>"N[ode]"</code>, +* <code>"S[ignal]"</code>, +* <code>"P[roperty]"</code>, +* <code>"AR[gument]"</code>, +* <code>"AN[nnotation]"</code> +* +* @return <code>.true</code> if the supplied kind (type) is contained in the introspection tree, +* <code>.false</code> else +*/ ::method contains -- returns .true if the supplied type exists in the tree parse upper arg kind +1 1 kind2 +2 if pos(kind,"AIMNSP")=0 then - raise syntax 88.916 array ('"type"', '"I[nterface]", "M[ethod]", "N[ode]", "S[ignal], "P[roperty]", "AR[gumgent]", "AN[notation]"', arg(1)) + raise syntax 88.916 array ('"type"', '"I[nterface]", "M[ethod]", "N[ode]", "S[ignal], "P[roperty]", "AR[gument]", "AN[notation]"', arg(1)) select when kind="A" then @@ -2588,6 +3095,18 @@ end return .false +/** Counts the number of occurrences of the supplied type (kind) in the introspection tree. +* +* @param kind optional, or one of <code>"I[nterface]"</code>, +* <code>"M[ethod]"</code>, +* <code>"N[ode]"</code>, +* <code>"S[ignal]"</code>, +* <code>"P[roperty]"</code>, +* <code>"AR[gument]"</code>, +* <code>"AN[nnotation]"</code> +* +* @return number of occurrences of the supplied kind (type) +*/ ::method count -- returns # of occurrences of given type parse upper arg kind +1 1 kind2 +2 @@ -2628,16 +3147,23 @@ /* ------------------------------ class definition ------------------------------ */ +/** This class represents an introspection node. */ ::class "IDBusNode" public subclass IDBus /* ------------------------------ class definition ------------------------------ */ +/** This class represents a DBUs interface node. */ ::class "IDBusInterface" public subclass IDBus /* ------------------------------ class definition ------------------------------ */ +/** This class represents a DBUs method node and defines method related attributes and methods. */ ::class "IDBusMethod" public subclass IDBus ::attribute argSignature ::attribute replySignature +/** Constructor method, initializing attributes. +* +* @param name optional (defaults to empty string) +*/ ::method init -- constructor expose argSignature replySignature use strict arg name @@ -2645,6 +3171,8 @@ replySignature="" forward class (super) -- array (name) -- continue -- invoke superclass constructor +/** Worker method that creates the argument's and reply signatures from its <code>IDBusArg</code> subnodes if any. +*/ ::method createSignatures -- create signatures from IDbusArg definitions expose argSignature replySignature @@ -2658,16 +3186,26 @@ end /* ------------------------------ class definition ------------------------------ */ +/** This class represents a DBus call method node. */ ::class "IDBusCallMethod" public subclass IDBusMethod /* ------------------------------ class definition ------------------------------ */ +/** This class represents a DBus signal method node. */ ::class "IDBusSignalMethod" public subclass IDBusMethod /* ------------------------------ class definition ------------------------------ */ +/** This class represents a DBus property method node. */ ::class "IDBusPropertyMethod" public subclass IDBusMethod -- properties are actually methods to get/set values ::attribute type -- type: type code ::attribute access -- access: read, readwrite, write +/** Constructor method, initializing attributes. +* +* @param name the name of the property +* @param type the type of the property +* @property access one or both of <code>"read"</code> and <code>"write"</code> +* +*/ ::method init -- constructor expose type access use strict arg name, type, access @@ -2680,10 +3218,17 @@ /* ------------------------------ class definition ------------------------------ */ +/** This class represents a DBus argument node. */ ::class "IDBusArg" public subclass IDBus ::attribute type -- type: type code ::attribute direction +/** Constructor method, initializing attributes. +* +* @param name the name of the property +* @param type the type of the property +* @param direction one or both of <code>"in"</code> and <code>"out"</code> +*/ ::method init -- constructor expose type direction use strict arg name, type, direction @@ -2692,9 +3237,15 @@ /* ------------------------------ class definition ------------------------------ */ +/** This class represents a DBus annotation node. */ ::class "IDBusAnnotation" public subclass IDBus ::attribute value -- value: CDATA +/** Constructor method, initializing attributes. +* +* @param name the name of the property +* @param value the annotation text +*/ ::method init -- constructor expose value use strict arg name, value @@ -2704,6 +3255,15 @@ /* ========================== introspection related ... [truncated message content] |
From: <or...@us...> - 2014-10-19 16:16:25
|
Revision: 258 http://sourceforge.net/p/bsf4oorexx/code/258 Author: orexx Date: 2014-10-19 16:16:22 +0000 (Sun, 19 Oct 2014) Log Message: ----------- 20141014 Prepare version for distribution. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbus.cls sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc Modified: sandbox/rgf/misc/dbusoorexx/dbus.cls =================================================================== --- sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-10-15 12:11:08 UTC (rev 257) +++ sandbox/rgf/misc/dbusoorexx/dbus.cls 2014-10-19 16:16:22 UTC (rev 258) @@ -50,7 +50,7 @@ * * @author Rony G. Flatscher * @since 2011-06-11 -* @version 1.00 +* @version 2.00 * */ @@ -69,7 +69,7 @@ cf.: dbus-specifications: <http://dbus.freedesktop.org/doc/dbus-specification.html> (as of 2011-07-14) - version: 100.20140916 + version: 200.20141020 changes: - 2011-07-20, rgf; DBusProxyObject: - added proxy.dispatch(methodName[,args...])-method to send messages that @@ -184,7 +184,7 @@ .dbus.dir~bDebug =.false -- .true -- .false -- .true .dbus.dir~bDebugServer=.false -- .true -- .false -- .true -.dbus.dir~version="100.20140916" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' +.dbus.dir~version="200.20141020" -- current version of DBUS.CLS, released will start with: '100.yyyymmdd' .dbus.dir~DBUS_SERVICE_DBUS ="org.freedesktop.DBus" -- "The bus name used to talk to the bus itself." .dbus.dir~DBUS_PATH_DBUS ="/org/freedesktop/DBus" -- "The object path used to talk to the bus itself." Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-10-15 12:11:08 UTC (rev 257) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-10-19 16:16:22 UTC (rev 258) @@ -31,7 +31,7 @@ * </ul> * * @author Rony G. Flatscher - * @version 2014-08-11 + * @version 2014-10-20 * */ @@ -84,7 +84,8 @@ on Windows) - ooRexx 4.2.0 now required (because of using .context~name in 'dbus.cls' package 2014-08-07, rgf: - tidied up the source - 2014-08-11, rgf: - adding doclet-kind documentation + 2014-08-11, rgf: - adding doclet-kind documentation + 2014-10-20, rgf: - changed version to 2.00, 2014-10-20, ie. "200.20141020" possible todos: - add globals for Nil(), True(), Flase(), .Array, .DateTime, .DBus, "1", "", as well @@ -92,7 +93,7 @@ - change attribute name CSELF (probably misleading as it is not the same as CSELF in an ooRexx native method or routine argument type); if so, don't forget dbus.cls - version: 100.20140807 + version: 200.20141020 license: Apache License 2.0 ------------------------ Apache Version 2.0 license ------------------------- @@ -155,11 +156,11 @@ #ifdef DBUSOOREXX_32 - #define DBUS_REXXVERSION "100.20140811 32-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20141020 32-bit" // version: "MajorNumber"."YYYYMMDD" #elif defined (DBUSOOREXX_64) - #define DBUS_REXXVERSION "100.20140811 64-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20141020 64-bit" // version: "MajorNumber"."YYYYMMDD" #else - #define DBUS_REXXVERSION "100.20140811 n/a-bit" // version: "MajorNumber"."YYYYMMDD" + #define DBUS_REXXVERSION "100.20141020 n/a-bit" // version: "MajorNumber"."YYYYMMDD" #endif #ifndef TID This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2014-10-19 16:33:30
|
Revision: 259 http://sourceforge.net/p/bsf4oorexx/code/259 Author: orexx Date: 2014-10-19 16:33:26 +0000 (Sun, 19 Oct 2014) Log Message: ----------- 20141019 Get rid of MSC 64-bit compiler warnings. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbusoorexx-32.dll sandbox/rgf/misc/dbusoorexx/dbusoorexx-64.dll sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc Modified: sandbox/rgf/misc/dbusoorexx/dbusoorexx-32.dll =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/dbusoorexx-64.dll =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-10-19 16:16:22 UTC (rev 258) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-10-19 16:33:26 UTC (rev 259) @@ -1387,7 +1387,8 @@ * @param context The RexxThreadContext to interact with ooRexx * @return the number of items in the given dimension */ -inline size_t GET_UNMARSHAL_ARRAY_VALUE_AT_INDEX(RexxArrayObject arrIdx, int32_t index, RexxThreadContext *context) +// inline size_t GET_UNMARSHAL_ARRAY_VALUE_AT_INDEX(RexxArrayObject arrIdx, int32_t index, RexxThreadContext *context) +inline size_t GET_UNMARSHAL_ARRAY_VALUE_AT_INDEX(RexxArrayObject arrIdx, size_t index, RexxThreadContext *context) { size_t val=0; @@ -3674,7 +3675,8 @@ pmarsh->context->ReleaseLocalReference(rso); } - if (!dbus_message_iter_append_fixed_array(&iter_array, DBUS_TYPE_BYTE, &stringValue, stringLength )) + // 2014-10-19, rgf: add cast to int to remove warning on 64-bit + if (!dbus_message_iter_append_fixed_array(&iter_array, DBUS_TYPE_BYTE, &stringValue, (int) stringLength )) { pmarsh->dbusError = true; SNPRINTF(pmarsh->msgChunk256, 256, ": DBus-API returned 'no memory' while marshalling a byte array using the 'dbus_message_iter_append_fixed_array()'-API"); @@ -3699,7 +3701,8 @@ #endif // process all array items - size_t items=GET_ARRAY_SIZE_AT_DIMENSION(rao, level, pmarsh->context); + // 2014-10-19, rgf: add cast (int32_t) to stop warning on 64-bit MSC + size_t items=GET_ARRAY_SIZE_AT_DIMENSION(rao, (int32_t) level, pmarsh->context); #ifdef DEBUG_ARRAY fprintf(stderr, " ...ma(...): rao=[%s], has rao-size/items at level=[%lu]/dim|items: [%lu] | arrIdx=[%s]\n", @@ -3776,7 +3779,9 @@ pmarsh->context->ReleaseLocalReference(rop); pmarsh->context->ReleaseLocalReference(oriRop); - if (!dbus_message_iter_append_fixed_array(&iter_array, DBUS_TYPE_BYTE, &stringValue, stringLength )) + + // 2014-10-19, rgf: add cast (int) to stop warning on 64-bit MSC + if (!dbus_message_iter_append_fixed_array(&iter_array, DBUS_TYPE_BYTE, &stringValue, (int) stringLength )) { pmarsh->dbusError = true; SNPRINTF(pmarsh->msgChunk256, 256, ": DBus-API returned 'no memory' while marshalling a byte array using the 'dbus_message_iter_append_fixed_array()'-API"); @@ -3920,7 +3925,9 @@ #endif logical_t bRetValue=false; - size_t items=GET_ARRAY_SIZE_AT_DIMENSION(rao, level, pmarsh->context); + + // 2014-10-19, rgf: add cast (int32_t) to stop warning on 64-bit MSC + size_t items=GET_ARRAY_SIZE_AT_DIMENSION(rao, (int32_t) level, pmarsh->context); if (items==0) // e.g. if .nil was supplied; we still need to create the array containers, even if they remain empty { items=1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2014-10-19 16:46:45
|
Revision: 260 http://sourceforge.net/p/bsf4oorexx/code/260 Author: orexx Date: 2014-10-19 16:46:37 +0000 (Sun, 19 Oct 2014) Log Message: ----------- 20141019 Preparing release. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/libdbusoorexx.dylib sandbox/rgf/misc/dbusoorexx/libdbusoorexx64.so Modified: sandbox/rgf/misc/dbusoorexx/libdbusoorexx.dylib =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/libdbusoorexx64.so =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <or...@us...> - 2014-10-21 13:48:47
|
Revision: 261 http://sourceforge.net/p/bsf4oorexx/code/261 Author: orexx Date: 2014-10-21 13:48:43 +0000 (Tue, 21 Oct 2014) Log Message: ----------- 20141021 Prepare for GA. Modified Paths: -------------- sandbox/rgf/misc/dbusoorexx/dbusoorexx-32.dll sandbox/rgf/misc/dbusoorexx/dbusoorexx-64.dll sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc sandbox/rgf/misc/dbusoorexx/libdbusoorexx.dylib sandbox/rgf/misc/dbusoorexx/libdbusoorexx32.so sandbox/rgf/misc/dbusoorexx/libdbusoorexx64.so Modified: sandbox/rgf/misc/dbusoorexx/dbusoorexx-32.dll =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/dbusoorexx-64.dll =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc =================================================================== --- sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-10-19 16:46:37 UTC (rev 260) +++ sandbox/rgf/misc/dbusoorexx/dev/dbusoorexx.cc 2014-10-21 13:48:43 UTC (rev 261) @@ -7700,7 +7700,7 @@ STANDARD_PACKAGE_HEADER REXX_INTERPRETER_4_2_0, // anything including and after 4.2.0 will work "dbus", // name of the package - "1.00", // package information + "2.00", // package version information #if defined(REXX_LOADER_UNLOADER) || defined (REXX_LOADER) dbusLoader, Modified: sandbox/rgf/misc/dbusoorexx/libdbusoorexx.dylib =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/libdbusoorexx32.so =================================================================== (Binary files differ) Modified: sandbox/rgf/misc/dbusoorexx/libdbusoorexx64.so =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |