Added first ecore_con bits.
[ruby-ecore.git] / src / ecore_con / rb_server.c
diff --git a/src/ecore_con/rb_server.c b/src/ecore_con/rb_server.c
new file mode 100644 (file)
index 0000000..d267350
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * $Id: rb_server.c 362 2006-02-13 22:46:35Z tilman $
+ *
+ * Copyright (C) 2005 ruby-ecore team (see AUTHORS)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <ruby.h>
+
+#include <Ecore.h>
+#include <Ecore_Con.h>
+#include <stdbool.h>
+
+#include "../ecore/rb_event_handler.h"
+
+#define CHECK_DELETED(s) \
+       if (s->deleted) \
+               rb_raise (rb_eIOError, "server deleted");
+
+typedef struct {
+       Ecore_Con_Server *real;
+       bool deleted;
+} RbServer;
+
+static void c_free (RbServer *svr)
+{
+       if (svr->real && !svr->deleted)
+               ecore_con_server_del (svr->real);
+
+       ecore_con_shutdown ();
+
+       free (svr);
+}
+
+static VALUE c_alloc (VALUE klass)
+{
+       RbServer *svr = NULL;
+
+       return Data_Make_Struct (klass, RbServer, NULL, c_free, svr);
+}
+
+static VALUE c_init (VALUE self, VALUE type, VALUE host, VALUE port)
+{
+       RbServer *svr = NULL;
+
+       Check_Type (type, T_FIXNUM);
+       StringValue (host);
+       Check_Type (port, T_FIXNUM);
+
+       Data_Get_Struct (self, RbServer, svr);
+
+       ecore_con_init ();
+
+       svr->deleted = false;
+       svr->real = ecore_con_server_connect (FIX2INT (type),
+                                             StringValuePtr (host),
+                                             FIX2INT (port), (void *) self);
+       if (!svr->real)
+               rb_raise (rb_eIOError, "cannot create Server");
+
+       return self;
+}
+
+static VALUE c_write (VALUE self, VALUE data)
+{
+       RbServer *svr;
+       int n;
+
+       StringValue (data);
+
+       Data_Get_Struct (self, RbServer, svr);
+       CHECK_DELETED (svr);
+
+       n = ecore_con_server_send (svr->real,
+                                  StringValuePtr (data),
+                                  RSTRING (data)->len);
+       if (!n)
+               rb_raise (rb_eIOError, "couldn't write data");
+       else
+               return INT2FIX (n);
+}
+
+/*
+ * call-seq:
+ *  server.delete => nil
+ *
+ * Deletes <i>server</i>.
+ */
+static VALUE c_delete (VALUE self)
+{
+       RbServer *svr = NULL;
+
+       Data_Get_Struct (self, RbServer, svr);
+       CHECK_DELETED (svr);
+
+       ecore_con_server_del (svr->real);
+       svr->deleted = true;
+       svr->real = NULL;
+
+       return self;
+}
+
+static VALUE find_server (Ecore_Con_Server *c)
+{
+       /* FIXME what if the Ruby object has been destroyed already? */
+       return (VALUE) ecore_con_server_data_get (c);
+}
+
+static VALUE c_ev_server_add_init (VALUE self, VALUE event)
+{
+       VALUE c = CLASS_OF (self), server;
+       Ecore_Con_Event_Server_Add *e = (void *) event;
+
+       server = find_server (e->server);
+       if (NIL_P (server))
+               rb_bug ("cannot find server");
+
+       rb_define_attr (c, "server", 1, 0);
+
+       rb_iv_set (self, "@server", server);
+
+       return self;
+}
+
+static VALUE c_ev_server_del_init (VALUE self, VALUE event)
+{
+       VALUE c = CLASS_OF (self), server;
+       Ecore_Con_Event_Server_Del *e = (void *) event;
+
+       server = find_server (e->server);
+       if (NIL_P (server))
+               rb_bug ("cannot find server");
+
+       rb_define_attr (c, "server", 1, 0);
+
+       rb_iv_set (self, "@server", server);
+
+       return self;
+}
+
+static VALUE c_ev_server_data_init (VALUE self, VALUE event)
+{
+       VALUE c = CLASS_OF (self), server;
+       Ecore_Con_Event_Server_Data *e = (void *) event;
+
+       server = find_server (e->server);
+       if (NIL_P (server))
+               rb_bug ("cannot find server");
+
+       rb_define_attr (c, "server", 1, 0);
+       rb_define_attr (c, "data", 1, 0);
+
+       rb_iv_set (self, "@server", server);
+       rb_iv_set (self, "@data", rb_str_new (e->data, e->size));
+
+       return self;
+}
+
+void Init_Server (VALUE m)
+{
+       VALUE c = rb_define_class_under (m, "Server", rb_cObject);
+
+       rb_define_alloc_func (c, c_alloc);
+       rb_define_method (c, "initialize", c_init, 3);
+       rb_define_method (c, "write", c_write, 1);
+       rb_define_alias (c, "<<", "write");
+       rb_define_method (c, "delete", c_delete, 0);
+
+       ADD_EVENT (m, ECORE_CON_EVENT_, SERVER_ADD, "ServerAdd", c);
+       rb_define_private_method (c, "initialize",
+                                 c_ev_server_add_init, 1);
+
+       ADD_EVENT (m, ECORE_CON_EVENT_, SERVER_DATA, "ServerData", c);
+       rb_define_private_method (c, "initialize",
+                                 c_ev_server_data_init, 1);
+
+       ADD_EVENT (m, ECORE_CON_EVENT_, SERVER_DEL, "ServerDel", c);
+       rb_define_private_method (c, "initialize",
+                                 c_ev_server_del_init, 1);
+}