--- 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);
+}
|