OSSP CVS Repository

ossp - ossp-pkg/act/act_ctx.c
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/act/act_ctx.c
/*
**  OSSP act - Abstract Container Types
**  Copyright (c) 1999-2003 Ralf S. Engelschall <rse@engelschall.com>
**  Copyright (c) 1999-2003 The OSSP Project <http://www.ossp.org/>
**
**  This file is part of OSSP act, an abstract container type library
**  which can be found at http://www.ossp.org/pkg/lib/act/.
**
**  Permission to use, copy, modify, and distribute this software for
**  any purpose with or without fee is hereby granted, provided that
**  the above copyright notice and this permission notice appear in all
**  copies.
**
**  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
**  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
**  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
**  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
**  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
**  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
**  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
**  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
**  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
**  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
**  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
**  SUCH DAMAGE.
**
**  act_ctx.c: context structure (implementation)
*/

#include "act_p.h"

/* the value of a context entry */
typedef union act_ctx_value_un {
    void  *v_ptr;
    int    v_int;
    long   v_long;
    double v_double;
} act_ctx_value_t;

/* the context entry */
typedef struct act_ctx_entry_st {
    unsigned int    e_id;
    act_ctx_value_t e_value;
} act_ctx_entry_t;

/* the context (already typedef'd in public header) */
struct act_ctx_st {
    act_ctx_entry_t c_entry[ACT_CTX_ENTRY_MAX+1];
};

/* the default context */
act_ctx_t *act_ctx_default = NULL;

/* initialize the context module */
intern int act_ctx_init(void)
{
    if (act_ctx_default != NULL)
        act_ctx_free(act_ctx_default);
    act_ctx_default = act_ctx_new();
    return TRUE;
}

/* kill the context module */
intern int act_ctx_kill(void)
{
    if (act_ctx_default != NULL) {
        act_ctx_free(act_ctx_default);
        act_ctx_default = NULL;
    }
    return TRUE;
}

/* allocate a new context structure */
act_ctx_t *act_ctx_new(void)
{
    act_ctx_t *ctx;
    int i;

    if ((ctx = (act_ctx_t *)act_mem_alloc(sizeof(struct act_ctx_st))) == NULL)
        return NULL;
    for (i = 0; i < ACT_CTX_ENTRY_MAX; i++) {
        ctx->c_entry[i].e_id = ACT_CTX_ID_NULL;
        ctx->c_entry[i].e_value.v_long = 0;
    }
    return ctx;
}

/* duplicate a new context structure
   (optionally with the help of a template) */
act_ctx_t *act_ctx_dup(act_ctx_t *ctx, act_ctx_t *ctx_template)
{
    act_ctx_t *ctx_new;
    act_ctx_t *ctx_from;
    int sp, lk, ty, no;
    int i;

    if (ctx == NULL)
        return NULL;
    if (ctx_template != NULL)
        ctx_from = ctx_template;
    else
        ctx_from = ctx;
    if ((ctx_new = (act_ctx_t *)act_mem_alloc(sizeof(struct act_ctx_st))) == NULL)
        return NULL;
    act_mem_move(ctx_new->c_entry, ctx_from->c_entry,
                 sizeof(act_ctx_entry_t)*(ACT_CTX_ENTRY_MAX+1));
    if (ctx_template != NULL) {
        for (i = 0; i <= ACT_CTX_ENTRY_MAX; i++) {
            ACT_CTX_ID_SPLIT(sp, lk, ty, no, ctx_new->c_entry[i].e_id);
            if (!lk) {
                ctx_new->c_entry[i].e_id = ctx->c_entry[i].e_id;
                act_mem_move(&(ctx_new->c_entry[i].e_value), &(ctx->c_entry[i].e_value),
                             sizeof(act_ctx_value_t));
            }
        }
    }
    return ctx_new;
}

/* common function for both set and get context entries */
static int act_ctx_setget(act_ctx_t *ctx, int set, unsigned int id, va_list ap)
{
    int sp,lk,ty,no;
    int csp,clk,cty,cno;

    ACT_CTX_ID_SPLIT(sp, lk, ty, no, id);
    ACT_CTX_ID_SPLIT(csp, clk, cty, cno, ctx->c_entry[no].e_id);
    if (set && clk)
        return FALSE;
    switch (ty) {
        case act_type_ptr:
            if (set)
                ctx->c_entry[no].e_value.v_ptr = va_arg(ap, void *);
            else {
                void **v = va_arg(ap, void **);
                *v = ctx->c_entry[no].e_value.v_ptr;
            }
            break;
        case act_type_int:
            if (set)
                ctx->c_entry[no].e_value.v_int = va_arg(ap, int);
            else {
                int *v = va_arg(ap, int *);
                *v = ctx->c_entry[no].e_value.v_int;
            }
            break;
        case act_type_long:
            if (set)
                ctx->c_entry[no].e_value.v_long = va_arg(ap, long);
            else {
                long *v = va_arg(ap, long *);
                *v = ctx->c_entry[no].e_value.v_long;
            }
            break;
        case act_type_double:
            if (set)
                ctx->c_entry[no].e_value.v_double = va_arg(ap, double);
            else {
                double *v = va_arg(ap, double *);
                *v = ctx->c_entry[no].e_value.v_double;
            }
            break;
        default:
            return FALSE;
            break;
    }
    ctx->c_entry[no].e_id = id;
    return TRUE;
}

/* set an entry in a context structure */
int act_ctx_set(act_ctx_t *ctx, unsigned int id, ...)
{
    va_list ap;
    int rc;

    if (ctx == NULL)
        return FALSE;
    va_start(ap, id);
    rc = act_ctx_setget(ctx, TRUE, id, ap);
    va_end(ap);
    return rc;
}

/* get an entry from a context structure */
int act_ctx_get(act_ctx_t *ctx, unsigned int id, ...)
{
    va_list ap;
    int rc;

    if (ctx == NULL)
        return FALSE;
    va_start(ap, id);
    rc = act_ctx_setget(ctx, FALSE, id, ap);
    va_end(ap);
    return rc;
}

/* get the address of an entry from a context structure */
void *act_ctx_var(act_ctx_t *ctx, unsigned int id)
{
    int sp,lk,ty,no;

    if (ctx == NULL)
        return FALSE;
    ACT_CTX_ID_SPLIT(sp, lk, ty, no, id);
    return &(ctx->c_entry[no].e_value);
}

/* lock an entry of the context structure */
int act_ctx_lock(act_ctx_t *ctx, unsigned int id)
{
    int rsp,rlk,rty,rno;
    int csp,clk,cty,cno;

    if (ctx == NULL)
        return FALSE;
    ACT_CTX_ID_SPLIT(rsp,rlk,rty,rno,id);
    ACT_CTX_ID_SPLIT(csp,clk,cty,cno,ctx->c_entry[rno].e_id);
    ctx->c_entry[rno].e_id = ACT_CTX_ID_CONS(csp,1,cty,cno);
    return TRUE;
}

/* unlock an entry of the context structure */
int act_ctx_unlock(act_ctx_t *ctx, unsigned int id)
{
    int rsp,rlk,rty,rno;
    int csp,clk,cty,cno;

    if (ctx == NULL)
        return FALSE;
    ACT_CTX_ID_SPLIT(rsp,rlk,rty,rno,id);
    ACT_CTX_ID_SPLIT(csp,clk,cty,cno,ctx->c_entry[rno].e_id);
    ctx->c_entry[rno].e_id = ACT_CTX_ID_CONS(csp,0,cty,cno);
    return TRUE;
}

/* free a context structure */
int act_ctx_free(act_ctx_t *ctx)
{
    void *ptr;

    if (ctx == NULL)
        return FALSE;
    if (act_ctx_get(ctx, ACT_CTX_CTX_BINDING, &ptr))
        if (ptr != NULL)
            return FALSE;
    act_mem_free(ctx);
    return TRUE;
}


CVSTrac 2.0.1