OSSP CVS Repository

ossp - Difference in ossp-pkg/l2/l2_channel.c versions 1.20 and 1.21
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/l2/l2_channel.c 1.20 -> 1.21

--- l2_channel.c 2001/09/27 13:56:35     1.20
+++ l2_channel.c 2001/11/03 22:51:36     1.21
@@ -51,7 +51,7 @@
  * Last-modified: 2000-09-28/14:40
  * Name: l2_ch_lifecycle
  * Version: eo/1.0
- * H4sIAIsvszsCA62WTW/bMAyGz/WvENBzM5KyPnwusGFAdtp1l8BVWgOZUyTuhv77
+ * H4sIAGdztDsCA62WTW/bMAyGz/WvENBzM5KyPnwusGFAdtp1l8BVWgOZUyTuhv77
  * kfKHnC4t5CZJ7JAO3kcUKUq5/fr9m9IrKtab9uFYb55DcR/aLhyKH6E7NHWxDh17
  * ShUIsAIofjbt4y4Ud1QgASgqQGlSt3V8Fai0AoV8gTJyI76xLD6Tb35iPSpybNlS
  * PsknV5po5WC0BZZRWSlL8km+tlYsa3MwJfAP6Kdokl8iltHKwjiwJ5jJL52DbIxB
@@ -84,12 +84,16 @@
 
     /* initialize channel structure */
     ch->state = L2_CHSTATE_CREATED;
-    ch->downstream = NULL;
+    ch->parent = NULL;
+    ch->sibling = NULL;
+    ch->child = NULL;
     memset(&ch->context, 0, sizeof(l2_context_t));
     memcpy(&ch->handler, h, sizeof(l2_handler_t));
     ch->rvErrorInfo = L2_OK;
     ch->szErrorInfo[0] = '\0';
     ch->szError[0] = '\0';
+    ch->levelmask = L2_LEVEL_ALL;
+    ch->flushmask = L2_LEVEL_NONE;
 
     /* (optionally) perform create operation in handler */
     if (ch->handler.create != NULL) {
@@ -102,6 +106,84 @@
     return ch;
 }
 
+/* stack channel on top of another channel */
+l2_result_t l2_channel_stack(l2_channel_t *ch, l2_channel_t *chP)
+{
+    l2_channel_t *chT;
+
+    /* argument sanity check */
+    if (ch == NULL || chP == NULL)
+        return L2_ERR_ARG;
+
+    /* make sure both channels are in state "created" */
+    if (   ch->state  != L2_CHSTATE_CREATED
+        || chP->state != L2_CHSTATE_CREATED)
+        return L2_ERR_USE;
+
+    /* make sure parent channel is a filter channel */
+    if (chP->handler.type != L2_CHANNEL_FILTER)
+        return L2_ERR_USE;
+
+    /* make sure child still has no parent */
+    if (ch->parent != NULL)
+        return L2_ERR_USE;
+
+    /* stack the two channels */
+    ch->parent = chP;
+    if (chP->child == NULL)
+        chP->child = ch;
+    else {
+        chT = chP->child;
+        while (chT->sibling != NULL)
+            chT = chT->sibling;
+        chT->sibling = ch;
+    }
+
+    return L2_OK;
+}
+
+/* return upstream channel */
+l2_result_t l2_channel_upstream(l2_channel_t *ch, l2_channel_t **chU)
+{
+    /* argument sanity check */
+    if (ch == NULL || chU == NULL)
+        return L2_ERR_ARG;
+
+    /* determine parent/upstream channel */
+    *chU = ch->parent;
+
+    return (*chU != NULL ? L2_OK : L2_ERR_CH);
+}
+
+/* return (subsequent) downstream channel(s) */
+l2_result_t l2_channel_downstream(l2_channel_t *ch, l2_channel_t **chD)
+{
+    /* argument sanity check */
+    if (ch == NULL || chD == NULL)
+        return L2_ERR_ARG;
+
+    /* determine (next) downstream/child channel */
+    if (*chD == NULL)
+        *chD = ch->child;
+    else
+        *chD = (*chD)->sibling;
+
+    return (*chD != NULL ? L2_OK : L2_ERR_CH);
+}
+
+/* return channel type */
+l2_result_t l2_channel_type(l2_channel_t *ch, l2_chtype_t *type)
+{
+    /* argument sanity check */
+    if (ch == NULL || type == NULL)
+        return L2_ERR_ARG;
+
+    /* return type */
+    (*type) = ch->handler.type;
+
+    return L2_OK;
+}
+
 /* configure channel */
 l2_result_t l2_channel_configure(l2_channel_t *ch, const char *fmt, ...)
 {
@@ -126,10 +208,12 @@
     return rv;
 }
 
-/* open channel (stack) */
+/* open channel */
 l2_result_t l2_channel_open(l2_channel_t *ch)
 {
     l2_result_t rv;
+    l2_result_t rvD;
+    l2_channel_t *chD;
 
     /* argument sanity check */
     if (ch == NULL)
@@ -139,29 +223,42 @@
     if (ch->state != L2_CHSTATE_CREATED)
         return L2_ERR_USE;
 
-    /* skip empty open handlers on channel stack */
-    while (ch != NULL && ch->handler.open == NULL) {
-        ch->state = L2_CHSTATE_OPENED;
-        ch = ch->downstream;
+    /* perform operation */
+    if (ch->handler.open != NULL)
+        rv = ch->handler.open(&ch->context, ch);
+    else
+        rv = L2_OK_PASS;
+   
+    /* optionally pass operation downstream */ 
+    if (rv == L2_OK_PASS) {
+        rv = L2_OK;
+        chD = NULL;
+        while (l2_channel_downstream(ch, &chD) == L2_OK)
+            if ((rvD = l2_channel_open(chD)) != L2_OK)
+                rv = rvD;
+        if (rv != L2_OK) {
+            chD = NULL;
+            while (l2_channel_downstream(ch, &chD) == L2_OK)
+                l2_channel_close(chD);
+        }
     }
-    if (ch == NULL)
-        return L2_ERR_USE;
 
-    /* pass operation to handler */
-    rv = ch->handler.open(&ch->context, ch);
+    /* mark channel as opened */
     if (rv == L2_OK)
         ch->state = L2_CHSTATE_OPENED;
 
     return rv;
 }
 
-/* write to channel (stack) */
+/* write to channel */
 l2_result_t l2_channel_write(l2_channel_t *ch, l2_level_t level, const char *buf, size_t bufsize)
 {
     l2_result_t rv;
+    l2_result_t rvD;
+    l2_channel_t *chD;
 
     /* argument sanity check */
-    if (ch == NULL || buf == NULL)
+    if (ch == NULL || level == 0 || buf == NULL)
         return L2_ERR_ARG;
 
     /* make sure channel is in state "opened" */
@@ -172,14 +269,20 @@
     if (bufsize == 0)
         return L2_OK;
 
-    /* walk to next available write handler */
-    while (ch != NULL && ch->handler.write == NULL)
-        ch = ch->downstream;
-    if (ch == NULL)
-        return L2_ERR_USE;
-
-    /* pass operation to handler */
-    rv = ch->handler.write(&ch->context, ch, level, buf, bufsize);
+    /* perform operation */
+    if (ch->handler.write != NULL)
+        rv = ch->handler.write(&ch->context, ch, level, buf, bufsize);
+    else
+        rv = L2_OK_PASS;
+   
+    /* optionally pass operation downstream */ 
+    if (rv == L2_OK_PASS) {
+        rv = L2_OK;
+        chD = NULL;
+        while (l2_channel_downstream(ch, &chD) == L2_OK)
+            if ((rvD = l2_channel_write(chD, level, buf, bufsize)) != L2_OK)
+                rv = rvD;
+    }
 
     return rv;
 }
@@ -188,6 +291,8 @@
 l2_result_t l2_channel_flush(l2_channel_t *ch)
 {
     l2_result_t rv;
+    l2_result_t rvD;
+    l2_channel_t *chD;
 
     /* argument sanity check */
     if (ch == NULL)
@@ -197,14 +302,20 @@
     if (ch->state != L2_CHSTATE_OPENED)
         return L2_ERR_USE;
 
-    /* walk to next available flush handler */
-    while (ch != NULL && ch->handler.flush == NULL)
-        ch = ch->downstream;
-    if (ch == NULL)
-        return L2_ERR_USE;
-
-    /* pass operation to handler */
-    rv = ch->handler.flush(&ch->context, ch);
+    /* perform operation */
+    if (ch->handler.flush != NULL)
+        rv = ch->handler.flush(&ch->context, ch);
+    else
+        rv = L2_OK_PASS;
+   
+    /* optionally pass operation downstream */ 
+    if (rv == L2_OK_PASS) {
+        rv = L2_OK;
+        chD = NULL;
+        while (l2_channel_downstream(ch, &chD) == L2_OK)
+            if ((rvD = l2_channel_flush(chD)) != L2_OK)
+                rv = rvD;
+    }
 
     return rv;
 }
@@ -213,6 +324,8 @@
 l2_result_t l2_channel_close(l2_channel_t *ch)
 {
     l2_result_t rv;
+    l2_result_t rvD;
+    l2_channel_t *chD;
 
     /* argument sanity check */
     if (ch == NULL)
@@ -222,16 +335,22 @@
     if (ch->state != L2_CHSTATE_OPENED)
         return L2_ERR_USE;
 
-    /* walk to next available close handler */
-    while (ch != NULL && ch->handler.close == NULL) {
-        ch->state = L2_CHSTATE_CREATED;
-        ch = ch->downstream;
+    /* perform operation */
+    if (ch->handler.close != NULL)
+        rv = ch->handler.close(&ch->context, ch);
+    else
+        rv = L2_OK_PASS;
+   
+    /* optionally pass operation downstream */ 
+    if (rv == L2_OK_PASS) {
+        rv = L2_OK;
+        chD = NULL;
+        while (l2_channel_downstream(ch, &chD) == L2_OK)
+            if ((rvD = l2_channel_close(chD)) != L2_OK)
+                rv = rvD;
     }
-    if (ch == NULL)
-        return L2_ERR_USE;
 
-    /* pass operation to handler */
-    rv = ch->handler.close(&ch->context, ch);
+    /* mark channel as closed */
     if (rv == L2_OK)
         ch->state = L2_CHSTATE_CREATED;
 
@@ -242,6 +361,8 @@
 l2_result_t l2_channel_destroy(l2_channel_t *ch)
 {
     l2_result_t rv;
+    l2_result_t rvD;
+    l2_channel_t *chD;
 
     /* argument sanity check */
     if (ch == NULL)
@@ -252,18 +373,24 @@
         if ((rv = l2_channel_close(ch)) != L2_OK)
             return rv;
 
-    /* walk to next available destroy handler */
-    while (ch != NULL && ch->handler.destroy == NULL)
-        ch = ch->downstream;
-    
-    /* pass operation to handler */
-    if (ch != NULL)
+    /* perform operation */
+    if (ch->handler.destroy != NULL)
         rv = ch->handler.destroy(&ch->context, ch);
     else
+        rv = L2_OK_PASS;
+   
+    /* optionally pass operation downstream */ 
+    if (rv == L2_OK_PASS) {
         rv = L2_OK;
+        chD = NULL;
+        while (l2_channel_downstream(ch, &chD) == L2_OK)
+            if ((rvD = l2_channel_destroy(chD)) != L2_OK)
+                rv = rvD;
+    }
 
     /* free channel structure */
-    free(ch);
+    if (rv == L2_OK)
+        free(ch);
 
     return rv;
 }
@@ -332,45 +459,3 @@
     return ch->szError;
 }
 
-/* stack channel on top of another channel */
-l2_result_t l2_channel_stack(l2_channel_t *ch, l2_channel_t *chTop)
-{
-    /* argument sanity check */
-    if (ch == NULL || chTop == NULL)
-        return L2_ERR_ARG;
-
-    /* make sure both channels are in state "created" */
-    if (   ch->state    != L2_CHSTATE_CREATED
-        || chTop->state != L2_CHSTATE_CREATED)
-        return L2_ERR_USE;
-
-    /* make sure top channel is a filter channel */
-    if (chTop->handler.type != L2_CHANNEL_FILTER)
-        return L2_ERR_USE;
-
-    /* stack the channels */
-    chTop->downstream = ch;
-
-    return L2_OK;
-}
-
-/* return downstream channel */
-l2_channel_t *l2_channel_downstream(l2_channel_t *ch)
-{
-    /* argument sanity check */
-    if (ch == NULL)
-        return NULL;
-
-    return ch->downstream;
-}
-
-/* return channel type */
-l2_chtype_t l2_channel_type(l2_channel_t *ch)
-{
-    /* argument sanity check */
-    if (ch == NULL)
-        return L2_CHANNEL_FILTER; /* FIXME */
-
-    return ch->handler.type;
-}
-

CVSTrac 2.0.1