OSSP CVS Repository

ossp - Difference in ossp-pkg/sio/sio.c versions 1.1 and 1.2
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/sio/sio.c 1.1 -> 1.2

--- sio.c        2002/10/22 12:57:20     1.1
+++ sio.c        2002/10/23 17:05:10     1.2
@@ -57,19 +57,27 @@
 struct sio_halfduplex_st {
     NODE(sio_halfduplex_t) hd;
     sio_stage_t *stage;
+    sio_halfduplex_t *cross;
+    al_t *al;
     sio_rc_t (*func)(sio_t *, al_t *, void *);
 };
 
 struct sio_st {
     struct {
-        LIST(sio_halfduplex_t) hd;
+        LIST(sio_halfduplex_t)  hd;
         al_t                   *al;
     } readers;
     struct {
-        LIST(sio_halfduplex_t) hd;
+        LIST(sio_halfduplex_t)  hd;
         al_t                   *al;
     } writers;
+    sio_labelnum_t             label_data;
+    sio_labelnum_t             label_error;
+    sio_labelnum_t             label_eof;
 };
+#define SIO_LABEL_DATA(sio)  ((void*)&(sio)->label_data)
+#define SIO_LABEL_ERROR(sio) ((void*)&(sio)->label_error)
+#define SIO_LABEL_EOF(sio)   ((void*)&(sio)->label_eof)
 
 struct sio_stage_st {
     sio_halfduplex_t reader;
@@ -82,23 +90,38 @@
 /****************************************************************************/
 
 static
-sio_rc_t sio_strategy(sio_t *sio, sio_halfduplex_t *chain, al_t *al)
+sio_rc_t sio_strategy(sio_t *sio, sio_halfduplex_t *chain)
 {
     sio_rc_t rc;
     sio_halfduplex_t *h;
 
+    /*
+     * call stage and direct data upstream/downstream
+     * according to response code
+     *
+     * if we the stage does not return a direction,
+     * simply end the code
+     *
+     * if we drop off the chain, simply result SIO_OK
+     *
+     */
     h = chain;
     while (h != NULL) {
-        rc = h->func(sio, al, h->stage->userdata);
+        rc = h->func(sio, h->al, h->stage->userdata);
         if (rc == SIO_UPSTREAM)
             h = NEXT(h,hd);
         else if (rc == SIO_DOWNSTREAM)
-            h = NEXT(h,hd);
+            h = PREV(h,hd);
+        else if (rc == SIO_XSTREAM)
+            h = h->cross;
         else
             break;
     }
 
-    return SIO_OK;
+    if (h == NULL)
+        rc = SIO_OK;
+
+    return rc;
 }
 
 /**************************************************************************/
@@ -118,6 +141,10 @@
     LISTINIT(&sio->readers,hd);
     LISTINIT(&sio->writers,hd);
 
+    sio->label_data  = SIO_LN_DATA;
+    sio->label_error = SIO_LN_ERROR;
+    sio->label_eof   = SIO_LN_EOF;
+
     *siop = sio;
 
     return SIO_OK;
@@ -138,7 +165,6 @@
 {
     sio_rc_t rc;
     sio_stage_t *sios;
-    void *u;
 
     /* argument sanity check(s) */
     if (sio == NULL || siom == NULL || siosp == NULL)
@@ -151,19 +177,26 @@
     NODEINIT(&sios->reader,hd);
     NODEINIT(&sios->writer,hd);
     sios->module       = siom;
-    sios->userdata     = u;
+    sios->userdata     = NULL;
     sios->rw           = SIO_MODE_INVALID;
     sios->reader.func  = siom->input;
     sios->reader.stage = sios;
     sios->writer.func  = siom->output;
     sios->writer.stage = sios;
 
-    rc = sios->module->init(sio, sios->userdata);
+    rc = sios->module->init(sio, &sios->userdata);
+    if (rc != SIO_OK) {
+        free(sios);
+        return SIO_RC(rc);
+    }
+
+    *siosp = sios;
 
     return SIO_RC(rc);
 }
 
-sio_rc_t sio_cofigure_stage(sio_t *sio, sio_stage_t *sios, void *obj, void *value)
+sio_rc_t sio_configure_stage(sio_t *sio, sio_stage_t *sios,
+                             void *obj, void *value)
 {
     sio_rc_t rc;
 
@@ -190,39 +223,104 @@
     return SIO_OK;
 }
 
+static
+sio_rc_t sio_create_al(sio_t *sio, sio_mode_t rw)
+{
+    al_rc_t arc;
+    int freereader = 0;
+
+    if (rw == SIO_MODE_READ || rw == SIO_MODE_READWRITE) {
+        if (ISEMPTY(&sio->readers,hd)) {
+            arc = al_create(&sio->readers.al);
+            if (arc != AL_OK)
+                return SIO_ERR_INT;
+            freereader = 1;
+        }
+    }
+    if (rw == SIO_MODE_WRITE || rw == SIO_MODE_READWRITE) {
+        if (ISEMPTY(&sio->writers,hd)) {
+            arc = al_create(&sio->writers.al);
+            if (arc != AL_OK) {
+                if (freereader)
+                    al_destroy(sio->readers.al);
+                return SIO_ERR_INT;
+            }
+        }
+    }
+
+    return SIO_OK;
+}
+
+static
+sio_rc_t sio_destroy_al(sio_t *sio, sio_mode_t rw)
+{
+    if (rw == SIO_MODE_READ || rw == SIO_MODE_READWRITE) {
+        if (ISEMPTY(&sio->readers,hd)) {
+            al_destroy(sio->readers.al);
+            sio->readers.al = NULL;
+        }
+    }
+    if (rw == SIO_MODE_WRITE || rw == SIO_MODE_READWRITE) {
+        if (ISEMPTY(&sio->writers,hd)) {
+            al_destroy(sio->writers.al);
+            sio->writers.al = NULL;
+        }
+    }
+
+    return SIO_OK;
+}
+
 sio_rc_t sio_attach(sio_t *sio, sio_stage_t *sios, sio_mode_t rw)
 {
     sio_rc_t rc;
+    int freereader = 0;
 
     /* argument sanity check(s) */
     if (sio == NULL || sios == NULL)
         return SIO_RC(SIO_ERR_ARG);
-
-    /* is module already attached ? */
-    if (sios->rw != SIO_MODE_INVALID)
-        return SIO_RC(SIO_ERR_ARG);
-
-    /* prepare module for being attached */
-    rc = sios->module->open(sio, sios->userdata);
-    if (rc != SIO_OK) return SIO_RC(rc);
-
     switch (rw) {
     case SIO_MODE_READ:
-        ADDTAIL(&sio->readers,hd,&sios->reader);
-        break;
     case SIO_MODE_WRITE:
-        ADDTAIL(&sio->writers,hd,&sios->writer);
-        break;
     case SIO_MODE_READWRITE:
-        ADDTAIL(&sio->readers,hd,&sios->reader);
-        ADDTAIL(&sio->writers,hd,&sios->writer);
         break;
     default:
         return SIO_RC(SIO_ERR_ARG);
     }
 
-    /* Remember the lists that sios has been attached to */
-    sios->rw = rw;
+    /* is module already attached ? */
+    if (sios->rw != SIO_MODE_INVALID)
+        return SIO_RC(SIO_ERR_ARG);
+
+    /* create assembly lines (if aready existing) */
+    rc = sio_create_al(sio, rw);
+    if (rc != SIO_OK)
+        return SIO_RC(rc);
+
+    if (rw == SIO_MODE_READ || rw == SIO_MODE_READWRITE) {
+        rc = sios->module->openr(sio, sio->readers.al, sios->userdata);
+        if (rc != SIO_OK) {
+            sio_destroy_al(sio, rw);
+            return SIO_ERR_INT;
+        }
+        ADDTAIL(&sio->readers,hd,&sios->reader);
+        freereader = 1;
+    }
+    if (rw == SIO_MODE_WRITE || rw == SIO_MODE_READWRITE) {
+        rc = sios->module->openw(sio, sio->writers.al, sios->userdata);
+        if (rc != SIO_OK) {
+            if (freereader) {
+                REMOVE(&sio->readers,hd,&sios->reader);
+                sios->module->closer(sio, sio->readers.al, sios->userdata);
+            }
+            sio_destroy_al(sio, rw);
+            return SIO_ERR_INT;
+        }
+        ADDTAIL(&sio->writers,hd,&sios->writer);
+    }
+
+    sios->reader.al = sio->readers.al;
+    sios->writer.al = sio->writers.al;
+    sios->rw        = rw;
 
     return SIO_OK;
 }
@@ -237,21 +335,33 @@
 
     switch (sios->rw) {
     case SIO_MODE_READ:
-        REMOVE(&sio->readers,hd,&sios->reader);
-        break;
     case SIO_MODE_WRITE:
-        REMOVE(&sio->writers,hd,&sios->writer);
-        break;
     case SIO_MODE_READWRITE:
-        REMOVE(&sio->readers,hd,&sios->reader);
-        REMOVE(&sio->writers,hd,&sios->writer);
         break;
     default:
         return SIO_RC(SIO_ERR_ARG);
-        break;
     }
 
-    rc = sios->module->close(sio, sios->userdata);
+    rc = SIO_OK;
+    if (sios->rw == SIO_MODE_WRITE || sios->rw == SIO_MODE_READWRITE) {
+        REMOVE(&sio->writers,hd,&sios->writer);
+        rc = sios->module->closew(sio, sio->writers.al, sios->userdata);
+    }
+    if (sios->rw == SIO_MODE_READ || sios->rw == SIO_MODE_READWRITE) {
+        REMOVE(&sio->readers,hd,&sios->reader);
+        if (rc == SIO_OK)
+            rc = sios->module->closer(sio, sio->readers.al, sios->userdata);
+        else
+            /* XXX - double error handling ? */
+            sios->module->closer(sio, sio->readers.al, sios->userdata);
+    }
+
+    sios->writer.al = NULL;
+    sios->reader.al = NULL;
+
+    sio_destroy_al(sio, sios->rw);
+
+    sios->rw = SIO_MODE_INVALID;
 
     return SIO_RC(rc);
 }
@@ -259,17 +369,23 @@
 sio_rc_t sio_input(sio_t *sio, al_t *al, size_t limit)
 {
     sio_rc_t rc;
-    al_t *src = sio->readers.al;
+    sio_halfduplex_t *h;
+    al_t *src;
     size_t n;
 
     /* argument sanity check(s) */
     if (sio == NULL || al == NULL)
         return SIO_RC(SIO_ERR_ARG);
 
+    h = HEAD(&sio->readers,hd);
+    if (h == NULL)
+        return SIO_RC(SIO_ERR_ARG);
+
+    src = h->al;
     n = al_bytes(src);
     if (n == 0) {
 
-        rc = sio_strategy(sio, HEAD(&sio->readers,hd), src);
+        rc = sio_strategy(sio, h);
         if (rc != SIO_OK) return SIO_RC(rc);
 
         n = al_bytes(src);
@@ -286,61 +402,55 @@
     return SIO_OK;
 }
 
-sio_rc_t sio_discard(sio_t *sio)
-{
-    sio_rc_t rc;
-    al_t *src = sio->readers.al;
-    size_t n;
-
-    /* argument sanity check(s) */
-    if (sio == NULL)
-        return SIO_RC(SIO_ERR_ARG);
-
-    while ((n = al_bytes(src)) > 0) {
-        rc = sio_strategy(sio, HEAD(&sio->readers,hd), src);
-        if (rc != SIO_OK)
-            break;
-    }
-
-    if (rc == SIO_ERR_EOF)
-        return SIO_OK;
-
-    return SIO_RC(rc);
-}
-
 sio_rc_t sio_output(sio_t *sio, al_t *al)
 {
     sio_rc_t rc;
-    al_t *dst = sio->writers.al;
+    al_rc_t arc;
+    sio_halfduplex_t *h;
+    al_t *dst;
     size_t n;
 
     /* argument sanity check(s) */
     if (sio == NULL || al == NULL)
         return SIO_RC(SIO_ERR_ARG);
 
+    h = HEAD(&sio->writers,hd);
+    if (h == NULL)
+        return SIO_RC(SIO_ERR_ARG);
+    dst = h->al;
+
     n = al_bytes(dst);
-    al_splice(dst, n, 0, al, NULL);
+    arc = al_splice(dst, n, 0, al, NULL);
+    if (arc != AL_OK)
+        return SIO_RC(SIO_ERR_INT);
 
-    rc = sio_strategy(sio, HEAD(&sio->writers,hd), dst);
+    rc = sio_strategy(sio, h);
 
     return SIO_RC(rc);
 }
 
-sio_rc_t sio_flush(sio_t *sio)
+sio_rc_t sio_push(sio_t *sio)
 {
     sio_rc_t rc;
-    al_t *dst = sio->writers.al;
-    size_t n;
+    al_rc_t arc;
+    sio_halfduplex_t *h;
+    al_t *dst;
+    char eof = '\0';
 
     /* argument sanity check(s) */
     if (sio == NULL)
         return SIO_RC(SIO_ERR_ARG);
 
-    while ((n = al_bytes(dst)) > 0) {
-        rc = sio_strategy(sio, HEAD(&sio->writers,hd), sio->writers.al);
-        if (rc != SIO_OK)
-            break;
-    }
+    h = HEAD(&sio->writers,hd);
+    if (h == NULL)
+        return SIO_RC(SIO_ERR_ARG);
+    dst = h->al;
+
+    arc = al_append_bytes(dst, &eof, 1, SIO_LABEL_EOF(sio));
+    if (arc != AL_OK)
+        return SIO_RC(SIO_ERR_INT);
+
+    rc = sio_strategy(sio, h);
 
     return SIO_RC(rc);
 }
@@ -351,12 +461,16 @@
     sio_rc_t rc;
     al_t *al;
 
+    if (n == 0)
+        return SIO_OK;
+
     arc = al_create(&al);
     if (arc != AL_OK) return SIO_RC(SIO_ERR_INT);
 
     rc = sio_input(sio, al, n);
     if (rc == AL_OK) {
-        arc = al_flatten(al, 0, n, dst, actualp);
+        arc = al_flatten(al, 0, n, AL_FORWARD_SPAN, SIO_LABEL_DATA(sio),
+                         dst, actualp);
         if (arc != AL_OK)
             rc = SIO_ERR_INT;
     }
@@ -373,10 +487,13 @@
     sio_rc_t rc;
     al_t *al;
 
+    if (n == 0)
+        return SIO_OK;
+
     arc = al_create(&al);
     if (arc != AL_OK) return SIO_RC(SIO_ERR_INT);
 
-    arc = al_append_bytes(al, src, n);
+    arc = al_append_bytes(al, src, n, SIO_LABEL_DATA(sio));
     if (arc != AL_OK)
         rc = SIO_ERR_INT;
     else
@@ -401,9 +518,32 @@
     case SIO_ERR_INT:    mess = "Internal Error"; break;
     case SIO_UPSTREAM:   mess = "Invoke Upstream Stage"; break;
     case SIO_DOWNSTREAM: mess = "Invoke Downstream Stage"; break;
+    case SIO_XSTREAM:    mess = "Invoke Crossstream Stage"; break;
     default:             mess = "Invalid Result Code"; break;
     }
 
     return mess;
 }
 
+sio_rc_t sio_label(sio_t *sio, sio_labelnum_t ln, void **p)
+{
+    void *label;
+
+    switch (ln) {
+    case SIO_LN_DATA:
+        label = SIO_LABEL_DATA(sio);
+        break;
+    case SIO_LN_ERROR:
+        label = SIO_LABEL_ERROR(sio);
+        break;
+    case SIO_LN_EOF:
+        label = SIO_LABEL_EOF(sio);
+        break;
+    default:
+        return SIO_ERR_ARG;
+    }
+
+    *p = label;
+    return SIO_OK;
+}
+

CVSTrac 2.0.1