* src/expat_erl.c: Now uses port control instead of port output
authorAlexey Shchepin <alexey@process-one.net>
Wed, 1 Dec 2004 22:48:53 +0000 (22:48 +0000)
committerAlexey Shchepin <alexey@process-one.net>
Wed, 1 Dec 2004 22:48:53 +0000 (22:48 +0000)
* src/xml_stream.erl: Likewise

* src/stringprep/stringprep.erl: Now register port instead of
storing it in ets table

* doc/guide.tex: Updated URLs to R10C release

SVN Revision: 287

ChangeLog
doc/guide.html
doc/guide.tex
src/expat_erl.c
src/stringprep/stringprep.erl
src/xml_stream.erl

index f64537fbeb00be9e4f5efc018413f20a8aa6eea0..b884095a3a970fcda6579c860a53ce809da7f039 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2004-12-01  Alexey Shchepin  <alexey@sevcom.net>
+
+       * src/expat_erl.c: Now uses port control instead of port output
+       * src/xml_stream.erl: Likewise
+
+2004-11-30  Alexey Shchepin  <alexey@sevcom.net>
+
+       * src/stringprep/stringprep.erl: Now register port instead of
+       storing it in ets table
+
+2004-11-28  Alexey Shchepin  <alexey@sevcom.net>
+
+       * doc/guide.tex: Updated URLs to R10C release
+
 2004-11-20  Alexey Shchepin  <alexey@sevcom.net>
 
        * src/mod_vcard.erl: Added missed index
index e112b16af0da7c3f732adf7fa26554377f79ef7e..9609458aa163b9a0adaa6608023410a4ea231e96 100644 (file)
@@ -179,7 +179,7 @@ To compile <TT>ejabberd</TT> in MS Windows environment, you will need the follow
 packages:
 <UL><LI>
 MS Visual C++ 6.0 Compiler
-<LI><A HREF="http://www.erlang.org/download/otp_win32_R9C-0.exe">Erlang/OTP R9C-0</A>
+<LI><A HREF="http://erlang.org/download/otp_win32_R10B-1a.exe">Erlang/OTP R10B-1a</A>
 <LI><A HREF="http://prdownloads.sourceforge.net/expat/expat_win32bin_1_95_7.exe?download">Expat 1.95.7</A>
 <LI><A HREF="http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.9.1.tar.gz">Iconv 1.9.1</A>
 (optional)
@@ -410,7 +410,8 @@ The following ACLs pre-defined:
 <B><TT>all</TT></B><DD> Matches all JIDs.
 <DT><B><TT>none</TT></B><DD> Matches none JIDs.
 </DL>
-An entry allowing or denying different services would look similar to this:
+An entry allowing or denying access to different services would look similar to
+this:
 <PRE>
   {access, &lt;accessname&gt;, [{allow, &lt;aclname&gt;},
                           {deny, &lt;aclname&gt;},
@@ -811,7 +812,7 @@ Replicating of table makes lookup in this table faster on this node,
  replicas is down, other replicas will be used.<BR>
 <BR>
 Also section ``5.3 Table Fragmentation''
- <A HREF="http://erlang.org/doc/r9c/lib/mnesia-4.1.4/doc/html/part_frame.html">here</A>
+ <A HREF="http://www.erlang.se/doc/doc-5.4/lib/mnesia-4.2/doc/html/index.html">here</A>
  can be useful.<BR>
 <BR>
 (alt) Same as in previous item, but for other tables.<BR>
index 0dc0f7e343763371d5a0f045eeab3ba0bf7c0a15..2ced9bc604f771ff8ffdb1fbd6d046ac5cb0ed03 100644 (file)
@@ -157,7 +157,7 @@ To compile \ejabberd{} in MS Windows environment, you will need the following
 packages:
 \begin{itemize}
 \item MS Visual C++ 6.0 Compiler
-\item \footahref{http://www.erlang.org/download/otp\_win32\_R9C-0.exe}{Erlang/OTP R9C-0}
+\item \footahref{http://erlang.org/download/otp_win32_R10B-1a.exe}{Erlang/OTP R10B-1a}
 \item \footahref{http://prdownloads.sourceforge.net/expat/expat\_win32bin\_1\_95\_7.exe?download}{Expat 1.95.7}
 \item
 \footahref{http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.9.1.tar.gz}{Iconv 1.9.1}
@@ -406,7 +406,8 @@ The following ACLs pre-defined:
 \titem{none} Matches none JIDs.
 \end{description}
 
-An entry allowing or denying different services would look similar to this:
+An entry allowing or denying access to different services would look similar to
+this:
 \begin{verbatim}
   {access, <accessname>, [{allow, <aclname>},
                           {deny, <aclname>},
@@ -813,7 +814,7 @@ mnesia:change_table_copy_type(schema, node(), disc_copies).
   replicas is down, other replicas will be used.
   
   Also section ``5.3 Table Fragmentation''
-  \footahref{http://erlang.org/doc/r9c/lib/mnesia-4.1.4/doc/html/part_frame.html}{here}
+  \footahref{http://www.erlang.se/doc/doc-5.4/lib/mnesia-4.2/doc/html/index.html}{here}
   can be useful.
   
   (alt) Same as in previous item, but for other tables.
index 2df857d8f14ea192ee797a0bcc8fe316789b8117..8cc9f2903c0c081477ea86430346d94cd8b7307e 100644 (file)
@@ -106,6 +106,9 @@ int ei_x_encode_string_fixed(ei_x_buff* x, const char* s)
 #define XML_CDATA 2
 #define XML_ERROR 3
 
+#define PARSE_COMMAND 0
+
+ei_x_buff event_buf;
 
 typedef struct {
       ErlDrvPort port;
@@ -117,44 +120,39 @@ void *erlXML_StartElementHandler(expat_data *d,
                                 const XML_Char **atts)
 {
    int i;
-   ei_x_buff buf;
-   
-   ei_x_new_with_version(&buf);
-   ei_x_encode_tuple_header(&buf, 2);
-   ei_x_encode_long(&buf, XML_START);
-   ei_x_encode_tuple_header(&buf, 2);
-   ei_x_encode_string_fixed(&buf, name);
-   
+
+   ei_x_encode_list_header(&event_buf, 1);
+   ei_x_encode_tuple_header(&event_buf, 2);
+   ei_x_encode_long(&event_buf, XML_START);
+   ei_x_encode_tuple_header(&event_buf, 2);
+   ei_x_encode_string_fixed(&event_buf, name);
+
    for (i = 0; atts[i]; i += 2) {}
 
-   ei_x_encode_list_header(&buf, i/2);
-  
-   for (i = 0; atts[i]; i += 2)
+   if (i > 0)
    {
-      ei_x_encode_tuple_header(&buf, 2);
-      ei_x_encode_string_fixed(&buf, atts[i]);
-      ei_x_encode_string_fixed(&buf, atts[i+1]);
+      ei_x_encode_list_header(&event_buf, i/2);
+
+      for (i = 0; atts[i]; i += 2)
+      {
+        ei_x_encode_tuple_header(&event_buf, 2);
+        ei_x_encode_string_fixed(&event_buf, atts[i]);
+        ei_x_encode_string_fixed(&event_buf, atts[i+1]);
+      }
    }
-   
-   ei_x_encode_empty_list(&buf);
-   
-   driver_output(d->port, buf.buff, buf.index);
-   ei_x_free(&buf);
+
+   ei_x_encode_empty_list(&event_buf);
+
    return NULL;
 }
 
 void *erlXML_EndElementHandler(expat_data *d,
                               const XML_Char *name)
 {
-   ei_x_buff buf;
-   
-   ei_x_new_with_version(&buf);
-   ei_x_encode_tuple_header(&buf, 2);
-   ei_x_encode_long(&buf, XML_END);
-   ei_x_encode_string_fixed(&buf, name);
-
-   driver_output(d->port, buf.buff, buf.index);
-   ei_x_free(&buf);
+   ei_x_encode_list_header(&event_buf, 1);
+   ei_x_encode_tuple_header(&event_buf, 2);
+   ei_x_encode_long(&event_buf, XML_END);
+   ei_x_encode_string_fixed(&event_buf, name);
    return NULL;
 }
 
@@ -162,15 +160,10 @@ void *erlXML_CharacterDataHandler(expat_data *d,
                                  const XML_Char *s,
                                  int len)
 {
-   ei_x_buff buf;
-   
-   ei_x_new_with_version(&buf);
-   ei_x_encode_tuple_header(&buf, 2);
-   ei_x_encode_long(&buf, XML_CDATA);
-   ei_x_encode_string_len_fixed(&buf, s, len);
-
-   driver_output(d->port, buf.buff, buf.index);
-   ei_x_free(&buf);
+   ei_x_encode_list_header(&event_buf, 1);
+   ei_x_encode_tuple_header(&event_buf, 2);
+   ei_x_encode_long(&event_buf, XML_CDATA);
+   ei_x_encode_string_len_fixed(&event_buf, s, len);
    return NULL;
 }
 
@@ -182,6 +175,8 @@ static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff)
    d->parser = XML_ParserCreate("UTF-8");
    XML_SetUserData(d->parser, d);
 
+   set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
+
    XML_SetStartElementHandler(
       d->parser, (XML_StartElementHandler)erlXML_StartElementHandler);
    XML_SetEndElementHandler(
@@ -199,48 +194,65 @@ static void expat_erl_stop(ErlDrvData handle)
    driver_free((char*)handle);
 }
 
-static void expat_erl_output(ErlDrvData handle, char *buff, int bufflen)
+static int expat_erl_control(ErlDrvData drv_data,
+                            unsigned int command,
+                            char *buf, int len,
+                            char **rbuf, int rlen)
 {
-   expat_data* d = (expat_data*)handle;
+   expat_data* d = (expat_data*)drv_data;
    int res, errcode;
    char *errstring;
-   ei_x_buff buf;
-
-   res = XML_Parse(d->parser, buff, bufflen, 0);
+   ErlDrvBinary *b;
+   size_t size;
 
-   if(!res)
+   switch (command)
    {
-      errcode = XML_GetErrorCode(d->parser);
-      errstring = (char *)XML_ErrorString(errcode);
-
-      ei_x_new_with_version(&buf);
-      ei_x_encode_tuple_header(&buf, 2);
-      ei_x_encode_long(&buf, XML_ERROR);
-      ei_x_encode_tuple_header(&buf, 2);
-      ei_x_encode_long(&buf, errcode);
-      ei_x_encode_string_fixed(&buf, errstring);
-
-      driver_output(d->port, buf.buff, buf.index);
-      ei_x_free(&buf);
+      case PARSE_COMMAND:
+        ei_x_new_with_version(&event_buf);
+        res = XML_Parse(d->parser, buf, len, 0);
+
+        if(!res)
+        {
+           errcode = XML_GetErrorCode(d->parser);
+           errstring = (char *)XML_ErrorString(errcode);
+
+           ei_x_encode_list_header(&event_buf, 1);
+           ei_x_encode_tuple_header(&event_buf, 2);
+           ei_x_encode_long(&event_buf, XML_ERROR);
+           ei_x_encode_tuple_header(&event_buf, 2);
+           ei_x_encode_long(&event_buf, errcode);
+           ei_x_encode_string_fixed(&event_buf, errstring);
+        }
+
+        ei_x_encode_empty_list(&event_buf);
+
+        size = event_buf.index;
+
+        b = driver_alloc_binary(size);
+        memcpy(b->orig_bytes, event_buf.buff, size);
+
+        ei_x_free(&event_buf);
+        *rbuf = (char *)b;
+        return size;
+      default:
+        return 0;
    }
-   
-   //driver_output(d->port, &res, 1);
 }
 
-
-
 ErlDrvEntry expat_driver_entry = {
-   NULL,                       /* F_PTR init, N/A */
-   expat_erl_start,          /* L_PTR start, called when port is opened */
-   expat_erl_stop,           /* F_PTR stop, called when port is closed */
-   expat_erl_output,         /* F_PTR output, called when erlang has sent */
-   NULL,                       /* F_PTR ready_input, called when input descriptor ready */
-   NULL,                       /* F_PTR ready_output, called when output descriptor ready */
-   "expat_erl",              /* char *driver_name, the argument to open_port */
-   NULL,                       /* F_PTR finish, called when unloaded */
-   NULL,                       /* F_PTR control, port_command callback */
-   NULL,                       /* F_PTR timeout, reserved */
-   NULL                        /* F_PTR outputv, reserved */
+   NULL,                       /* F_PTR init, N/A */
+   expat_erl_start,            /* L_PTR start, called when port is opened */
+   expat_erl_stop,             /* F_PTR stop, called when port is closed */
+   NULL,                       /* F_PTR output, called when erlang has sent */
+   NULL,                       /* F_PTR ready_input, called when input descriptor ready */
+   NULL,                       /* F_PTR ready_output, called when output descriptor ready */
+   "expat_erl",                        /* char *driver_name, the argument to open_port */
+   NULL,                       /* F_PTR finish, called when unloaded */
+   NULL,                       /* handle */
+   expat_erl_control,          /* F_PTR control, port_command callback */
+   NULL,                       /* F_PTR timeout, reserved */
+   NULL                                /* F_PTR outputv, reserved */
 };
 
 DRIVER_INIT(expat_erl) /* must match name in driver_entry */
index 58360b2925347eaa9bfac88f8de1ba634e9dfacd..ac06a0965eaee9a855e75149fc2269cf3808f8d8 100644 (file)
@@ -26,6 +26,8 @@
         code_change/3,
         terminate/2]).
 
+-define(STRINGPREP_PORT, stringprep_port).
+
 -define(NAMEPREP_COMMAND, 1).
 -define(NODEPREP_COMMAND, 2).
 -define(RESOURCEPREP_COMMAND, 3).
@@ -39,8 +41,7 @@ start_link() ->
 init([]) ->
     ok = erl_ddll:load_driver(ejabberd:get_so_path(), stringprep_drv),
     Port = open_port({spawn, stringprep_drv}, []),
-    ets:new(stringprep_table, [set, public, named_table]),
-    ets:insert(stringprep_table, {port, Port}),
+    register(?STRINGPREP_PORT, Port),
     {ok, Port}.
 
 
@@ -84,8 +85,7 @@ resourceprep(String) ->
     control(?RESOURCEPREP_COMMAND, String).
 
 control(Command, String) ->
-    [{port, Port} | _] = ets:lookup(stringprep_table, port),
-    case port_control(Port, Command, String) of
+    case port_control(?STRINGPREP_PORT, Command, String) of
        [0 | _] -> error;
        [1 | Res] -> Res
     end.
index b81575a44f03fe4cb532f76e8ae1f6638792c07a..8a892bf30e88db5e8cf0f7eb1fc4a5e2104a7818 100644 (file)
@@ -17,6 +17,8 @@
 -define(XML_CDATA, 2).
 -define(XML_ERROR, 3).
 
+-define(PARSE_COMMAND, 0).
+
 start(CallbackPid) ->
     spawn(?MODULE, init, [CallbackPid]).
 
@@ -38,8 +40,12 @@ loop(CallbackPid, Port, Stack) ->
            Data = binary_to_term(Bin),
            loop(CallbackPid, Port, process_data(CallbackPid, Stack, Data));
        {_From, {send, Str}} ->
-           Port ! {self(), {command, Str}},
-           loop(CallbackPid, Port, Stack);
+           Res = port_control(Port, ?PARSE_COMMAND, Str),
+           NewStack = lists:foldl(
+                        fun(Data, St) ->
+                                process_data(CallbackPid, St, Data)
+                        end, Stack, binary_to_term(Res)),
+           loop(CallbackPid, Port, NewStack);
        {'DOWN', _Ref, _Type, _Object, _Info} ->
            ok
     end.