OSSP CVS Repository

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

ossp-pkg/lmtp2nntp/lmtp2nntp_val.c 1.2 -> 1.3

--- lmtp2nntp_val.c      2002/01/16 09:46:52     1.2
+++ lmtp2nntp_val.c      2002/01/16 14:19:07     1.3
@@ -276,50 +276,101 @@
 #define VAL_MAXNAME 1024
 
 typedef struct {
+    val_t *val;
+    char *name;
+    int prefixlen;
+    int depth;
     val_cb_t cb;
     void *ctx;
     val_rc_t rc;
 } val_apply_ctx_t;
 
+static val_rc_t val_apply_internal(val_t *, const char *, int, int, val_cb_t, void *);
+
 static int (val_apply_cb)(void *_ctx, const void *keyptr, int keylen, const void *datptr, int datlen)
 {
     val_apply_ctx_t *ctx = (val_apply_ctx_t *)_ctx;
-    val_object_t *obj;
     char name[VAL_MAXNAME+1];
+    int prefixlen;
 
     /* on-the-fly create NUL-terminated name string */
-    if (keylen > VAL_MAXNAME) {
+    if ((strlen(ctx->name) + 1 + keylen) > VAL_MAXNAME) {
         ctx->rc = VAL_ERR_MEM;
         return FALSE;
     }
-    strncpy(name, (char *)keyptr, keylen);
-    *((char *)name+keylen) = '\0';
-
-    /* take object */
-    if (datlen != sizeof(val_object_t)) {
-        ctx->rc = VAL_ERR_ARG;
-        return FALSE;
+    if (strlen(ctx->name) > 0) {
+        strcpy(name, ctx->name);
+        strcat(name, ".");
+        prefixlen = ctx->prefixlen + 1;
     }
-    obj = (val_object_t *)datptr;
-
-    /* execute VAL callback */
-    if ((ctx->rc = ctx->cb(ctx->ctx, name, (obj->type & ~VAL_INLINE), obj->desc, val_storage(obj))) != VAL_OK)
+    else {
+        *name = '\0';
+        prefixlen = ctx->prefixlen;
+    }
+    strncat(name, (char *)keyptr, keylen);
+    if ((ctx->rc = val_apply_internal(ctx->val, name, prefixlen, ctx->depth, ctx->cb, ctx->ctx)) != VAL_OK)
         return FALSE;
-
     return TRUE;
 }
 
-val_rc_t val_apply(val_t *val, val_cb_t cb, void *ctx)
+static val_rc_t val_apply_internal(val_t *val, const char *name, int prefixlen, int depth, val_cb_t cb, void *ctx)
 {
+    val_object_t *obj;
+    val_t *child;
+    char *cp;
+    val_rc_t rc;
     val_apply_ctx_t val_ctx;
 
-    if (val == NULL || cb == NULL)
-        return VAL_ERR_ARG;
-    val_ctx.cb  = cb;
-    val_ctx.ctx = ctx;
-    val_ctx.rc  = VAL_OK;
-    if (!lh_apply(val->lh, val_apply_cb, &val_ctx))
-        return VAL_ERR_SYS;
-    return val_ctx.rc;
+fprintf(stderr, "DEBUG: val_apply_internal name=<%s>, prefixlen=%d, depth=%d\n", name, prefixlen, depth);
+    if (name[prefixlen] == '\0') {
+        /* prefix="foo.bar.", remainder="" */
+        //if (--depth > 0) {
+            val_ctx.val       = val;
+            val_ctx.name      = (char *)name;
+            val_ctx.prefixlen = prefixlen;
+            val_ctx.depth     = depth;
+            val_ctx.cb        = cb;
+            val_ctx.ctx       = ctx;
+            val_ctx.rc        = VAL_OK;
+            if (!lh_apply(val->lh, val_apply_cb, &val_ctx))
+                return VAL_ERR_SYS;
+        //}
+    }
+    else {
+        if ((cp = strchr(name+prefixlen, '.')) != NULL) {
+            /* prefix="foo.bar.", remainder="quux.baz" */
+            if (!lh_lookup(val->lh, name+prefixlen, cp-(name+prefixlen), (void **)&obj, NULL))
+                return VAL_ERR_ARG;
+            if (!(obj->type & VAL_TYPE_VAL))
+                return VAL_ERR_USE;
+            child = *(val_t **)(val_storage(obj));
+            if (depth == 0)
+                return VAL_OK;
+            return val_apply_internal(child, name, cp-name+1, --depth, cb, ctx);
+        }
+        else {
+            /* prefix="foo.bar.quux.", remainder="baz" */
+            if (!lh_lookup(val->lh, name+prefixlen, strlen(name+prefixlen), (void **)&obj, NULL))
+                return VAL_ERR_ARG;
+            /* execute VAL callback */
+            if ((rc = cb(ctx, name, (obj->type & ~VAL_INLINE), obj->desc, val_storage(obj))) != VAL_OK)
+                return rc;
+//fprintf(stderr, "DEBUG: depth=%d obj->type=%.8lx\n", depth, obj->type);
+            if (obj->type & VAL_TYPE_VAL) {
+                if (depth == 0)
+                    return VAL_OK;
+                child = *(val_t **)(val_storage(obj));
+                return val_apply_internal(child, name, strlen(name), --depth, cb, ctx);
+            }
+        }
+    }
+    return VAL_OK;
 }
 
+val_rc_t val_apply(val_t *val, const char *name, int depth, val_cb_t cb, void *ctx)
+{
+    if (val == NULL || name == NULL || depth < 0 || cb == NULL)
+        return VAL_ERR_ARG;
+
+    return val_apply_internal(val, name, 0, depth, cb, ctx);
+}

CVSTrac 2.0.1