ruby-ivy 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,86 @@
1
+ IVY - Ruby interface to IVY API
2
+ ===============================
3
+
4
+ Copyright Notice
5
+ ----------------
6
+
7
+ Ruby/IVY v0.1.0
8
+
9
+ Copyright (C) 2007 Gregoire Lejeune <gregoire.lejeune@free.fr>
10
+
11
+ Ruby/IVY is freely distributable according to the terms of the
12
+ GNU Lesser General Public Licence (see the file 'COPYING').
13
+
14
+ This program is distributed without any warranty. See the file
15
+ 'COPYING' for details.
16
+
17
+ About IVY
18
+ ---------
19
+
20
+ IVY provides users with the ability to write Ruby programs
21
+ that tightly integrate with IVY API.
22
+
23
+ With this module, you can define and register Ruby callbacks with the IVY
24
+ engine. This module calls your ruby callbacks using interpreters from a
25
+ threaded persistent interpreter pool. IVY contexts are presented using an
26
+ object-oriented style interface for performing operations on a IVY context.
27
+
28
+ The main project web page for this module is:
29
+
30
+ http://greg.rubyfr.net
31
+
32
+ Prerequisites
33
+ -------------
34
+
35
+ Ruby/IVY has been tested with the following:
36
+
37
+ IVY-c-3.9.1
38
+ PCRE-7.0
39
+ ruby 1.8.4 built
40
+
41
+ You can find the latest version of IVY from:
42
+
43
+ http://www.tls.cena.fr/products/ivy/
44
+
45
+ and the latest version of PCRE from :
46
+
47
+ http://www.pcre.org/
48
+
49
+ This module has only been tested on MacOSX 10.4.8. It was also compiled on Linux.
50
+
51
+ Building Ruby/IVY
52
+ -----------------
53
+
54
+ Begin by building ivy-c, pcre, and ruby. Next, perform the following
55
+ commands:
56
+
57
+ % ruby setup.rb config # or if you need to pass options to build the extension :
58
+ # ruby setup.rb config -- --with-option-...
59
+ % ruby setup.rb setup
60
+ % ruby setup.rb install
61
+
62
+ Using Ruby/IVY
63
+ --------------
64
+
65
+ See the documentation for complete information on writing your own program using IVY.
66
+
67
+ Testing the samples
68
+ -------------------
69
+
70
+ 000-IVYTranslater.rb. You can run it by using the following command:
71
+
72
+ % ruby 000-IVYTranslater.rb
73
+
74
+ Then in another terminal window, launch ivyprobe ’(.*)’. You are then ready to start. Type "Hello Paul",
75
+ and you should get "Bonjour Paul". Type "Bye", and your application should quit:
76
+
77
+ % ivyprobe ’(.*)’
78
+ IvyTranslater connected from localhost
79
+ IvyTranslater subscribes to ’Hello (.*)’
80
+ IvyTranslater subscribes to ’Bye’
81
+ Hello Paul
82
+ IvyTranslater sent ’Bonjour Paul’
83
+ Bye
84
+ IvyTranslater disconnected from localhost
85
+ Ctrl-D
86
+ %
@@ -0,0 +1,4 @@
1
+ #ifndef EXTCONF_H
2
+ #define EXTCONF_H
3
+ #define HAVE_IVY_H 1
4
+ #endif
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/ruby -w
2
+ # See the LICENSE file for copyright and distribution information
3
+
4
+ require "mkmf"
5
+
6
+ #$LIBPATH.push(Config::CONFIG['libdir'])
7
+
8
+ def crash( )
9
+ printf(<<EOL)
10
+ extconf failure: need libivy (see http://www.tls.cena.fr/products/ivy/index.html)
11
+
12
+ Install the library or try one of the following options to extconf.rb:
13
+
14
+ --with-ivy-dir=/path/to/libivy
15
+ --with-ivy-lib=/path/to/libivy/lib
16
+ --with-ivy-include=/path/to/libivy/include
17
+ EOL
18
+
19
+ exit 1
20
+ end
21
+
22
+
23
+ dir_config( "ivy" )
24
+ have_library( 'ivy', 'IvyInit' ) || crash( )
25
+ have_header( 'ivy.h' ) || crash( )
26
+
27
+ $CFLAGS = '-DMEMWATCH -g -Wall ' + $CFLAGS
28
+
29
+ create_header()
30
+ create_makefile("ivy")
@@ -0,0 +1,299 @@
1
+ /**
2
+ * Copyright (C) 2007 Gregoire Lejeune <gregoire.lejeune@free.fr>
3
+ *
4
+ * This program is free software; you can redistribute it and/or modify
5
+ * it under the terms of the GNU Lesser General Public License as published by
6
+ * the Free Software Foundation; either version 2 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+ */
18
+
19
+ #include "rb_ivy.h"
20
+
21
+ void ruby_ivy_free( RbTIvy *pRbTIvy ) {
22
+ if (pRbTIvy != NULL)
23
+ free(pRbTIvy);
24
+ }
25
+
26
+ void ruby_ivy_mark( RbTIvy *pRbTIvy ) {
27
+ if( pRbTIvy == NULL ) return;
28
+ if( !NIL_P(pRbTIvy->strAgentName) ) rb_gc_mark( pRbTIvy->strAgentName );
29
+ if( !NIL_P(pRbTIvy->strReadyMsg) ) rb_gc_mark( pRbTIvy->strReadyMsg );
30
+ }
31
+
32
+ VALUE ruby_ivy_new( VALUE class ) {
33
+
34
+ RbTIvy *pRbTIvy;
35
+
36
+ pRbTIvy = (RbTIvy *)malloc(sizeof(RbTIvy));
37
+ if( pRbTIvy == NULL )
38
+ rb_raise(rb_eNoMemError, "No memory left for IVY struct");
39
+
40
+ return( Data_Wrap_Struct( class, ruby_ivy_mark, ruby_ivy_free, pRbTIvy ) );
41
+ }
42
+
43
+ /** o = IVY.new( strAgentName, [strReadyMessage] ) */
44
+ static VALUE ruby_ivy_initialize( int iNbArgs, VALUE *vArgs, VALUE class ) {
45
+
46
+ RbTIvy *pRbTIvy;
47
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
48
+
49
+ if( iNbArgs < 1 || iNbArgs > 2 ) {
50
+ rb_raise( rb_eArgError, "wrong number of arguments (%d for 1)", iNbArgs );
51
+ }
52
+
53
+ pRbTIvy->strAgentName = vArgs[0];
54
+ if( iNbArgs == 2 ) {
55
+ pRbTIvy->strReadyMsg = vArgs[1];
56
+ } else {
57
+ pRbTIvy->strReadyMsg = Qnil;
58
+ }
59
+
60
+ IvyInit( STR2CSTR( pRbTIvy->strAgentName ), NULL, NULL, NULL, NULL, NULL );
61
+
62
+ return( class );
63
+ }
64
+
65
+ /** ------------------------------------------------------------------------ */
66
+
67
+ void ruby_ivy_message_free( RbTIvyMsg *pRbTIvyMsg ) {
68
+ if (pRbTIvyMsg != NULL)
69
+ free(pRbTIvyMsg);
70
+ }
71
+
72
+ void ruby_ivy_message_mark( RbTIvyMsg *pRbTIvyMsg ) {
73
+ if( pRbTIvyMsg == NULL ) return;
74
+ if( !NIL_P(pRbTIvyMsg->cb) ) rb_gc_mark( pRbTIvyMsg->cb );
75
+ if( !NIL_P(pRbTIvyMsg->data) ) rb_gc_mark( pRbTIvyMsg->data );
76
+ if( !NIL_P(pRbTIvyMsg->regexp) ) rb_gc_mark( pRbTIvyMsg->regexp );
77
+ }
78
+
79
+ /** o = IVY::Message.new() */
80
+ // VALUE ruby_ivy_message_new( VALUE class, VALUE cb, VALUE data, VALUE regexp ) {
81
+ VALUE ruby_ivy_message_new( VALUE class, VALUE data, VALUE regexp ) {
82
+ RbTIvyMsg *pRbTIvyMsg;
83
+
84
+ pRbTIvyMsg = (RbTIvyMsg *)malloc(sizeof(RbTIvyMsg));
85
+ if( pRbTIvyMsg == NULL )
86
+ rb_raise(rb_eNoMemError, "No memory left for IVY::MESSAGE struct");
87
+
88
+ pRbTIvyMsg->cb = rb_block_proc( );
89
+ pRbTIvyMsg->data = data;
90
+ pRbTIvyMsg->regexp = regexp;
91
+ pRbTIvyMsg->id = IvyBindMsg( callback, (void*)pRbTIvyMsg, STR2CSTR( pRbTIvyMsg->regexp ) );
92
+
93
+ return( Data_Wrap_Struct( class, ruby_ivy_message_mark, ruby_ivy_message_free, pRbTIvyMsg ) );
94
+ }
95
+
96
+ /** ------------------------------------------------------------------------ */
97
+
98
+ void ruby_ivy_client_free( RbTIvyClient *pRbTIvyClient ) {
99
+ if (pRbTIvyClient != NULL)
100
+ free(pRbTIvyClient);
101
+ }
102
+
103
+ void ruby_ivy_client_mark( RbTIvyClient *pRbTIvyClient ) {
104
+ if( pRbTIvyClient == NULL ) return;
105
+ }
106
+
107
+ VALUE ruby_ivy_client_new_internal( VALUE class, IvyClientPtr client ) {
108
+ RbTIvyClient *pRbTIvyClient;
109
+
110
+ pRbTIvyClient = (RbTIvyClient *)malloc(sizeof(RbTIvyClient));
111
+ if( pRbTIvyClient == NULL )
112
+ rb_raise(rb_eNoMemError, "No memory left for IVY::Client struct");
113
+
114
+ pRbTIvyClient->client = client;
115
+
116
+ return( Data_Wrap_Struct( class, ruby_ivy_client_mark, ruby_ivy_client_free, pRbTIvyClient ) );
117
+ }
118
+
119
+ /** o = IVY::Client.new( xClientName ) */
120
+ VALUE ruby_ivy_client_new( VALUE class, VALUE clientName ) {
121
+ RbTIvyClient *pRbTIvyClient;
122
+
123
+ pRbTIvyClient = (RbTIvyClient *)malloc(sizeof(RbTIvyClient));
124
+ if( pRbTIvyClient == NULL )
125
+ rb_raise(rb_eNoMemError, "No memory left for IVY::Client struct");
126
+
127
+ pRbTIvyClient->client = IvyGetApplication( STR2CSTR( clientName ) );
128
+
129
+ return( Data_Wrap_Struct( class, ruby_ivy_client_mark, ruby_ivy_client_free, pRbTIvyClient ) );
130
+ }
131
+
132
+ /** ------------------------------------------------------------------------ */
133
+
134
+ VALUE ruby_ivy_appname( VALUE class ) {
135
+ RbTIvyClient *pRbTIvyClient;
136
+ char *xAppName = NULL;
137
+
138
+ Data_Get_Struct( class, RbTIvyClient, pRbTIvyClient );
139
+
140
+ if( pRbTIvyClient->client != NULL )
141
+ xAppName = IvyGetApplicationName( pRbTIvyClient->client );
142
+
143
+ return( rb_str_new2( xAppName ) );
144
+ }
145
+
146
+ VALUE ruby_ivy_apphost( VALUE class ) {
147
+ RbTIvyClient *pRbTIvyClient;
148
+ char *xAppHost = NULL;
149
+
150
+ Data_Get_Struct( class, RbTIvyClient, pRbTIvyClient );
151
+
152
+ if( pRbTIvyClient->client != NULL )
153
+ xAppHost = IvyGetApplicationHost( pRbTIvyClient->client );
154
+
155
+ return( rb_str_new2( xAppHost ) );
156
+ }
157
+
158
+ /** ------------------------------------------------------------------------ */
159
+
160
+ VALUE ruby_ivy_start( int iNbArgs, VALUE *vArgs, VALUE class ) {
161
+ RbTIvy *pRbTIvy;
162
+ const char *bus = NULL;
163
+
164
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
165
+
166
+ if( iNbArgs == 0 ) {
167
+ bus = getenv( "IVYBUS" );
168
+ } else if( iNbArgs == 1 ) {
169
+ bus = STR2CSTR( vArgs[0] );
170
+ } else {
171
+ rb_raise( rb_eArgError, "wrong number of arguments (%d for 1)", iNbArgs );
172
+ }
173
+
174
+ IvyStart( bus );
175
+
176
+ return( Qnil );
177
+ }
178
+
179
+ VALUE ruby_ivy_mainloop( VALUE class ) {
180
+ RbTIvy *pRbTIvy;
181
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
182
+
183
+ IvyMainLoop( );
184
+
185
+ return( Qnil );
186
+ }
187
+
188
+ VALUE ruby_ivy_stop( VALUE class ) {
189
+ RbTIvy *pRbTIvy;
190
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
191
+
192
+ IvyStop( );
193
+
194
+ return( Qnil );
195
+ }
196
+
197
+ VALUE ruby_ivy_sendmsg( VALUE class, VALUE message ) {
198
+ RbTIvy *pRbTIvy;
199
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
200
+
201
+ IvySendMsg( STR2CSTR( message ) );
202
+
203
+ return( Qnil );
204
+ }
205
+
206
+ VALUE ruby_ivy_applist( VALUE class ) {
207
+ RbTIvy *pRbTIvy;
208
+ char *xAppList = NULL;
209
+ VALUE aryResult = rb_ary_new();
210
+
211
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
212
+
213
+ xAppList = IvyGetApplicationList( "|" );
214
+ xAppList = strtok( xAppList, "|" );
215
+ while( xAppList ) {
216
+ rb_ary_push( aryResult, rb_str_new2( xAppList ) );
217
+ xAppList = strtok (NULL, " ");
218
+ }
219
+ return( aryResult );
220
+ }
221
+
222
+ /** ------------------------------------------------------------------------ */
223
+
224
+ // VALUE ruby_ivy_bindmsg( VALUE class, VALUE data, VALUE regexp ) {
225
+ VALUE ruby_ivy_bindmsg( VALUE class, VALUE data, VALUE regexp ) {
226
+ VALUE method;
227
+ RbTIvy *pRbTIvy;
228
+
229
+ Data_Get_Struct( class, RbTIvy, pRbTIvy );
230
+
231
+ return( ruby_ivy_message_new( cIvyMsg, data, regexp ) );
232
+ }
233
+
234
+ VALUE ruby_ivy_unbindmsg( VALUE class ) {
235
+ RbTIvyMsg *pRbTIvyMsg;
236
+ Data_Get_Struct( class, RbTIvyMsg, pRbTIvyMsg );
237
+
238
+ if( pRbTIvyMsg->id != NULL ) {
239
+ IvyUnbindMsg( pRbTIvyMsg->id );
240
+ pRbTIvyMsg->id = NULL;
241
+ } else {
242
+ rb_warn( "IVY::Message not binded!" );
243
+ }
244
+
245
+ return( Qnil );
246
+ }
247
+
248
+ /** ------------------------------------------------------------------------ */
249
+
250
+ static void callback( IvyClientPtr app, void *data, int argc, char **argv ) {
251
+ RbTIvyMsg *pRbTIvyMsg = (RbTIvyMsg *)data;
252
+
253
+ int callID = rb_intern ("call");
254
+ VALUE res;
255
+
256
+ int i;
257
+ VALUE *aryArgs;
258
+
259
+ aryArgs = (VALUE *)malloc( sizeof( VALUE ) );
260
+
261
+ aryArgs[0] = ruby_ivy_client_new_internal( cIvyClient, app ); // IvyClientPtr app
262
+ aryArgs[1] = pRbTIvyMsg->data; // void *data
263
+ aryArgs[2] = rb_ary_new();
264
+ for( i = 0; i < argc; i++ ) {
265
+ rb_ary_push( aryArgs[2], rb_str_new2( argv[i] ) );
266
+ }
267
+
268
+ res = rb_funcall2( pRbTIvyMsg->cb, callID, 3, aryArgs );
269
+ }
270
+
271
+ /** ------------------------------------------------------------------------ */
272
+
273
+ void Init_ivy( void ) {
274
+ cIvy = rb_define_class( "IVY", rb_cObject );
275
+ cIvyMsg = rb_define_class_under( cIvy, "Message", rb_cObject );
276
+ cIvyClient = rb_define_class_under( cIvy, "Client", rb_cObject );
277
+
278
+ rb_define_const( cIvy, "RB_IVY_VERSION", rb_str_new2(RUBY_RBIVY_VERSION) );
279
+ rb_define_const( cIvy, "IVY_VERSION", rb_str_new2(RUBY_IVY_VERSION) );
280
+
281
+ rb_define_alloc_func( cIvy, ruby_ivy_new );
282
+ rb_define_private_method( cIvy, "initialize", ruby_ivy_initialize, -1);
283
+
284
+ // IVY
285
+ rb_define_method( cIvy, "start", ruby_ivy_start, -1 );
286
+ rb_define_method( cIvy, "mainloop", ruby_ivy_mainloop, 0 );
287
+ rb_define_method( cIvy, "stop", ruby_ivy_stop, 0 );
288
+ rb_define_method( cIvy, "sendmsg", ruby_ivy_sendmsg, 1 );
289
+ rb_define_method( cIvy, "applicationList", ruby_ivy_applist, 0 );
290
+ rb_define_method( cIvy, "bindmsg", ruby_ivy_bindmsg, 2 ); // renvoi un message de type IVY::MESSAGE
291
+
292
+ // IVY::Message
293
+ rb_define_method( cIvyMsg, "unbindmsg", ruby_ivy_unbindmsg, 0 );
294
+
295
+ // IVY::Client
296
+ rb_define_singleton_method( cIvyClient, "new", ruby_ivy_client_new, 1 );
297
+ rb_define_method( cIvyClient, "applicationName", ruby_ivy_appname, 0);
298
+ rb_define_method( cIvyClient, "applicationHost", ruby_ivy_apphost, 0);
299
+ }
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Copyright (C) 2006 Gregoire Lejeune <gregoire.lejeune@free.fr>
3
+ *
4
+ * This program is free software; you can redistribute it and/or modify
5
+ * it under the terms of the GNU Lesser General Public License as published by
6
+ * the Free Software Foundation; either version 2 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+ */
18
+
19
+ #include <sys/types.h>
20
+ #include <sys/stat.h>
21
+ #include <errno.h>
22
+ #include <stdio.h>
23
+ #include <stdlib.h>
24
+ #include <string.h>
25
+ #include <sysexits.h>
26
+ #include <unistd.h>
27
+
28
+ #include <ruby.h>
29
+ #include <rubyio.h>
30
+ #include <intern.h>
31
+
32
+ #include "ivyloop.h"
33
+ #include "ivysocket.h"
34
+ #include "ivychannel.h"
35
+ #include "ivybind.h"
36
+ #include "ivy.h"
37
+ #include "timer.h"
38
+
39
+ #ifndef bool
40
+ # define bool int
41
+ # define TRUE 1
42
+ # define FALSE 0
43
+ #endif /* ! bool */
44
+
45
+ #define RUBY_RBIVY_VERSION "0.1.0"
46
+ #define RUBY_RBIVY_VERNUM 010
47
+ #define RUBY_IVY_VERSION "IVYMAJOR_VERSION.IVYMINOR_VERSION"
48
+
49
+ typedef struct RbTIvy {
50
+
51
+ VALUE strAgentName;
52
+ VALUE strReadyMsg;
53
+
54
+ } RbTIvy;
55
+ VALUE cIvy;
56
+
57
+ typedef struct RbTIvyMsg {
58
+
59
+ MsgRcvPtr id;
60
+ VALUE cb;
61
+ VALUE data;
62
+ VALUE regexp;
63
+
64
+ } RbTIvyMsg;
65
+ VALUE cIvyMsg;
66
+
67
+ typedef struct RbTIvyClient {
68
+ IvyClientPtr client;
69
+ } RbTIvyClient;
70
+ VALUE cIvyClient;
71
+
72
+ static void callback( IvyClientPtr, void *, int, char ** );