aboutsummaryrefslogtreecommitdiff
path: root/Lib
diff options
context:
space:
mode:
authorLogan Johnson <ljohnson@users.sourceforge.net>2003-04-26 00:00:19 +0000
committerLogan Johnson <ljohnson@users.sourceforge.net>2003-04-26 00:00:19 +0000
commita00aa780ce1cbc906fbc9aaf08b1fba17d449ca0 (patch)
tree64ca743834ae8372c774244937d0c73a1ea61937 /Lib
parent9e945cb779e2be3fea2921d4af463a45fe7becb8 (diff)
downloadswig-a00aa780ce1cbc906fbc9aaf08b1fba17d449ca0.tar.gz
Add inv and outv Ruby typemaps for std::string.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@4714 626c5289-ae23-0410-ae9c-e8d60b6d4f22
Diffstat (limited to 'Lib')
-rw-r--r--Lib/ruby/director.swg165
-rw-r--r--Lib/ruby/std_string.i21
2 files changed, 186 insertions, 0 deletions
diff --git a/Lib/ruby/director.swg b/Lib/ruby/director.swg
new file mode 100644
index 000000000..652d64356
--- /dev/null
+++ b/Lib/ruby/director.swg
@@ -0,0 +1,165 @@
+/***********************************************************************
+ * director.swg
+ *
+ * This file contains support for director classes that proxy
+ * method calls from C++ to Ruby extensions.
+ *
+ * Author : Lyle Johnson (lyle@users.sourceforge.net)
+ * Based on the original Python implementation by
+ * Mark Rose (mrose@stm.lbl.gov).
+ ************************************************************************/
+
+#ifdef __cplusplus
+
+#include <string>
+
+/* Base class for director exceptions */
+class SWIG_DIRECTOR_EXCEPTION {
+protected:
+ std::string _msg;
+public:
+ SWIG_DIRECTOR_EXCEPTION(const char* msg="") {}
+ const char *getMessage() const { return _msg.c_str(); }
+ virtual ~SWIG_DIRECTOR_EXCEPTION() {}
+};
+
+/* Type mismatch in the return value from a Ruby method call */
+class SWIG_DIRECTOR_TYPE_MISMATCH : public SWIG_DIRECTOR_EXCEPTION {
+public:
+ SWIG_DIRECTOR_TYPE_MISMATCH(const char* msg="") {
+ _msg = "Swig director type mismatch: ";
+ _msg += msg;
+ // PyErr_SetString(PyExc_TypeError, msg); // FIXME
+ }
+};
+
+/* Any Ruby exception that occurs during a director method call */
+class SWIG_DIRECTOR_METHOD_EXCEPTION : public SWIG_DIRECTOR_EXCEPTION {};
+
+/* Attempted to call a pure virtual method via a director method */
+class SWIG_DIRECTOR_PURE_VIRTUAL_EXCEPTION : public SWIG_DIRECTOR_EXCEPTION {};
+
+
+/* Simple thread abstraction for pthreads or win32 */
+#ifdef __THREAD__
+ #define __PTHREAD__
+ #if defined(_WIN32) || defined(__WIN32__)
+ #define pthread_mutex_lock EnterCriticalSection
+ #define pthread_mutex_unlock LeaveCriticalSection
+ #define pthread_mutex_t CRITICAL_SECTION
+ #define MUTEX_INIT(var) CRITICAL_SECTION var
+ #else
+ #include <pthread.h>
+ #define MUTEX_INIT(var) pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER
+ #endif
+#endif
+
+/* director base class */
+class __DIRECTOR__ {
+private:
+ /* pointer to the wrapped Ruby object */
+ VALUE _self;
+ /* flag indicating whether the object is owned by Ruby or c++ */
+ mutable bool _disown;
+ /* shared flag for breaking recursive director calls */
+ static bool _up;
+
+#ifdef __PTHREAD__
+ /* locks for sharing the _up flag in a threaded environment */
+ static pthread_mutex_t _mutex_up;
+ static bool _mutex_active;
+ static pthread_t _mutex_thread;
+#endif
+
+ /* reset the _up flag once the routing direction has been determined */
+#ifdef __PTHREAD__
+ void __clear_up() const {
+ __DIRECTOR__::_up = false;
+ __DIRECTOR__::_mutex_active = false;
+ pthread_mutex_unlock(&_mutex_up);
+ }
+#else
+ void __clear_up() const {
+ __DIRECTOR__::_up = false;
+ }
+#endif
+
+public:
+ /* the default constructor should not be called */
+ __DIRECTOR__() {
+ assert(false);
+ }
+
+ /* wrap a Ruby object, optionally taking ownership */
+ __DIRECTOR__(VALUE self, bool disown) : _self(self), _disown(disown) {
+ }
+
+ /* discard our reference at destruction */
+ virtual ~__DIRECTOR__() {
+ }
+
+ /* return a pointer to the wrapped Ruby object */
+ VALUE __get_self() const {
+ return _self;
+ }
+
+
+ /* get the _up flag to determine if the method call should be routed
+ * to the c++ base class or through the wrapped Ruby object
+ */
+#ifdef __PTHREAD__
+ bool __get_up() const {
+ if (__DIRECTOR__::_mutex_active) {
+ if (pthread_equal(__DIRECTOR__::_mutex_thread, pthread_self())) {
+ bool up = _up;
+ __clear_up();
+ return up;
+ }
+ }
+ return false;
+ }
+#else
+ bool __get_up() const {
+ bool up = _up;
+ _up = false;
+ return up;
+ }
+#endif
+
+ /* set the _up flag if the next method call should be directed to
+ * the c++ base class rather than the wrapped Ruby object
+ */
+#ifdef __PTHREAD__
+ void __set_up() const {
+ pthread_mutex_lock(&__DIRECTOR__::_mutex_up);
+ __DIRECTOR__::_mutex_thread = pthread_self();
+ __DIRECTOR__::_mutex_active = true;
+ __DIRECTOR__::_up = true;
+ }
+#else
+ void __set_up() const {
+ __DIRECTOR__::_up = true;
+ }
+#endif
+
+ /* acquire ownership of the wrapped Ruby object (the sense of "disown"
+ * is from Ruby) */
+ void __disown() const {
+ assert(_self);
+ if (!_disown) {
+ _disown = true;
+ }
+ }
+};
+
+bool __DIRECTOR__::_up = false;
+
+#ifdef __PTHREAD__
+ MUTEX_INIT(__DIRECTOR__::_mutex_up);
+ pthread_t __DIRECTOR__::_mutex_thread;
+ int __DIRECTOR__::_mutex_active = false;
+#endif
+
+#endif /* __cplusplus */
+
+
diff --git a/Lib/ruby/std_string.i b/Lib/ruby/std_string.i
index c063ab85d..e971ffae9 100644
--- a/Lib/ruby/std_string.i
+++ b/Lib/ruby/std_string.i
@@ -25,6 +25,7 @@ namespace std {
%rename(String) string;
class string;
+ /* Overloading check */
%typemap(typecheck) string = char *;
%typemap(typecheck) const string & = char *;
@@ -53,4 +54,24 @@ namespace std {
$result = rb_str_new2($1->c_str());
}
+ %typemap(inv) string, const string &, string & "$1_name.c_str()";
+
+ %typemap(inv) string *, const string * "$1_name->c_str()";
+
+ %typemap(outv) string {
+ if (TYPE($input) == T_STRING)
+ $result = std::string(StringValuePtr($input));
+ else
+ throw SWIG_DIRECTOR_TYPE_MISMATCH("string expected");
+ }
+
+ %typemap(outv) const string & (std::string temp) {
+ if (TYPE($input) == T_STRING) {
+ temp = std::string(StringValuePtr($input));
+ $result = &temp;
+ } else {
+ throw SWIG_DIRECTOR_TYPE_MISMATCH("string expected");
+ }
+ }
+
}