⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slpd_predicate.c

📁 SLP协议在linux下的实现。此版本为1.2.1版。官方网站为www.openslp.org
💻 C
📖 第 1 页 / 共 4 页
字号:
    /***** Verify and convert rhs. *****/    str_val = rhs;    str_len = rhs_len;    /***** Get tag value. *****/    var = attr_val_find_str((struct xx_SLPAttributes *)slp_attr, tag, tag_len);    if(var == NULL)    {        return FR_EVAL_FALSE;    }    /**** Check type. ****/    if(var->type != SLP_OPAQUE)    {        return FR_EVAL_FALSE;    }    /***** Compare. *****/    assert(op != PRESENT);     if(op == APPROX)    {        assert(0); /* TODO: Figure out how this works later. */    }    else if(op == EQUAL)    {        int result;        value_t *value;        for(value = var->list; value; value = value->next)        {            result = wildcard(str_val, str_len, value->data.va_str, value->unescaped_len);            /* We only keep going if the test fails. Let caller handle other problems. */            if(result != FR_EVAL_FALSE)            {                return result;            }        }    }    else    {        value_t *value;        /* We know that the op must be comparative. */        assert(op == LESS || op == GREATER);        for(value = var->list; value; value = value->next)        {            int result;            result = memcmp(value->data.va_str, str_val, MIN(str_len, value->unescaped_len));            if(              (result <= 0 && op == LESS)               || (result >= 0 && op == GREATER)               )            {                return FR_EVAL_TRUE;            }        }    }    return FR_EVAL_FALSE;}/*--------------------------------------------------------------------------*/int is_int_string(const char *str)/* Tests a string to see if it consists wholly of numeric characters.       *//*--------------------------------------------------------------------------*/{    int i;    for(i=0; str[i] != '\0'; i++)    {        if(!((!isdigit((int)str[i])) || str[i] == '-'))        {            return 0;        }    }    return 1;}/*--------------------------------------------------------------------------*/char *find_substr(char *src, int src_len, char *to_find)/* Returns ptr to start of substring, or null.                              *//*--------------------------------------------------------------------------*/{    int i;    for(i = 0; i < src_len; i++)    {        if(src[i] == *to_find)        {            int old_i = i; /* Save the old start. */            int find_index;            for(find_index = 0; (to_find[find_index] != '\0') && (i < src_len) && (to_find[find_index] == src[i]); to_find++, i++)            {            }            if(to_find[find_index] == '\0')            {                return src + i;            }            i = old_i; /* Restor the old start. */        }    }    return 0;}/*--------------------------------------------------------------------------*/char *find_bracket_end(const char *str)/* Finds a bracket matched to this one. Returns 0 if there isn't one.       *//*--------------------------------------------------------------------------*/{    int open_count;     const char *cur;    if(*str != BRACKET_OPEN)    {        return 0;    }    open_count = 0;    /***** Count brackets. *****/    for(cur = str; *cur != '\0'; cur++)    {        assert(open_count >= 0);        /**** Check current character. ****/        if(*cur == BRACKET_OPEN)        {            open_count++;        }        else if(*cur == BRACKET_CLOSE)        {            open_count--;        }        /**** Check if we've found bracket end. ****/        if(open_count == 0)        {            return(char *)cur;        }    }    return 0;}       /*--------------------------------------------------------------------------*/struct pair/* Represents a string and its length. */{    char *start;    char *end; /* Stop reading _BEFORE_ end. ie, at end-1. */};/*--------------------------------------------------------------------------*/#if defined(ENABLE_SLPv1)/*--------------------------------------------------------------------------*/FilterResult filterv1(const char *start,                       const char **end,                       SLPAttributes slp_attr,                       int recursion_depth)/* Parameters:                                                              *//* start -- (IN) The start of the string to work in.                        *//* end -- (OUT) The end of the string processed. After successful processing*//*              (ie, no PARSE_ERRORs), this will be pointed at the character*//*              following the last char in this level of the expression.    *//* slp_attr -- (IN) The attributes handle to compare on.                    *//* return_value -- (OUT) The result of the search. Only valid if SLP_OK was *//*                       returned.                                          *//*                                                                          *//* Returns: SLP_OK on successful search (ie, the search was do-able).       *//*          SLP_PARSE_ERROR on search error.  The end of the expression is  *//*          returned through end.                                           *//* NOTE: This attempt only implements one comparision operator (==)         *//*--------------------------------------------------------------------------*/{    char *operator; /* Pointer to the operator substring. */    const char *cur; /* Current working character. */    const char *last_char; /* The last character in the working string. */    FilterResult err = FR_UNSET; /* The result of an evaluation. */    FilterResult stop_condition = FR_UNSET;    if(recursion_depth <= 0)    {        return FR_PARSE_ERROR;    }    recursion_depth--;    if(*start == 0)    {        *end = start;        return FR_EVAL_TRUE;    }    if(*start != BRACKET_OPEN)    {        return FR_PARSE_ERROR;    }    /***** Get the current expression. *****/    last_char = *end = find_bracket_end(start);    if(*end == 0)    {        return FR_PARSE_ERROR;    }    (*end)++; /* Move the end pointer past the closing bracket. */    /****      * Check for the three legal characters that can follow an expression,     * if the following character isn't one of those, the following character      * is trash.     ****/    if(!(**end == BRACKET_OPEN || **end == BRACKET_CLOSE || **end == '\0'))    {        return FR_PARSE_ERROR;    }    /***** check for boolean op. *****/    cur = start;    cur++;    switch(*cur)    {    case('&'): /***** And. *****/    case('|'): /***** Or. *****/        {            if(*cur == '&')            {                stop_condition = FR_EVAL_FALSE;            }            else if(*cur == '|')            {                stop_condition = FR_EVAL_TRUE;            }            cur++; /* Move past operator. */            /*** Ensure that we have at least one operator. ***/            if(*cur != BRACKET_OPEN || cur >= last_char)            {                return FR_PARSE_ERROR;            }            /*** Evaluate each operand. ***/            /* NOTE: Due to the condition on the above "if", we are guarenteed that the first iteration of the loop is valid. */            do             {                err = filterv1(cur, &cur, slp_attr, recursion_depth);                /*** Propagate errors. ***/                if(err != FR_EVAL_TRUE && err != FR_EVAL_FALSE)                {                    return err;                }                /*** Short circuit. ***/                if(err == stop_condition)                {                    return stop_condition;                }            } while(*cur == BRACKET_OPEN && cur < last_char);             /*** If we ever get here, it means we've evaluated every operand without short circuiting -- meaning that the operation failed. ***/            return(stop_condition == FR_EVAL_TRUE ? FR_EVAL_FALSE : FR_EVAL_TRUE);        }    case('!'): /***** Not. *****/        /**** Child. ****/        cur++;        err = filterv1(cur, &cur, slp_attr, recursion_depth);        /*** Return errors. ***/        if(err != FR_EVAL_TRUE && err != FR_EVAL_FALSE)        {            return err;        }        /*** Perform "not". ***/        return(err == FR_EVAL_TRUE ? FR_EVAL_FALSE : FR_EVAL_TRUE);    default: /***** Unknown operator. *****/        ;        /* We don't do anything here because this will catch the first character of every leaf predicate. */    }    /***** Check for leaf operator. *****/    if(IS_VALID_TAG_CHAR(*cur))    {        Operation op;        char *lhs, *rhs; /* The two operands. */        char *val_start; /* The character after the operator. ie, the start of the rhs. */        int lhs_len, rhs_len; /* Length of the lhs/rhs. */        SLPType type;        SLPError slp_err;        /**** Demux leaf op. ****/        /* Support only "==", we look for the equals          * sign, and then poke around on either side of that for the real          * value.          */        operator = (char *)memchr(cur, '=', last_char - cur);        if(operator == 0 || *(operator + 1) != '=')        {            /**** No search operator. ****/            return FR_PARSE_ERROR;        }        /* The rhs always follows the operator. (This doesn't really make         sense for PRESENT ops, but ignore that). */        val_start = operator + 2;         if(operator == cur)        {/* Check that we can poke back one char. */            return FR_PARSE_ERROR;        }        op = EQUAL;        /***** Get operands. *****/        /**** Left. ****/        lhs_len = operator - cur;        lhs = (char *)cur;        /**** Right ****/        rhs_len = last_char - val_start;        rhs = val_start;        /***** Do leaf operation. *****/        /**** Check that tag exists. ****/        slp_err = SLPAttrGetType_len(slp_attr, lhs, lhs_len, &type);        if(slp_err == SLP_TAG_ERROR)        { /* Tag  doesn't exist. */            return FR_EVAL_FALSE;        }        else if(slp_err == SLP_OK)        { /* Tag exists. */            /**** Do operation. *****/            if(op == PRESENT)            {                /*** Since the PRESENT operation is the same for all types,                 do that now. ***/                return FR_EVAL_TRUE;            }            else            {                /*** A type-specific operation. ***/                switch(type)                {                case(SLP_BOOLEAN):                    err = bool_op(slp_attr, lhs, lhs_len, rhs, rhs_len, op);                     break;                case(SLP_INTEGER):                    err = int_op(slp_attr, lhs, lhs_len, rhs, op);                     break;                case(SLP_KEYWORD):                    err = keyw_op(slp_attr, lhs, rhs, op);                     break;                case(SLP_STRING):                    err = str_op(slp_attr, lhs, lhs_len, rhs, rhs_len, op);                     break;                case(SLP_OPAQUE):                    assert(0); /* Opaque is not yet supported. */                }            }        }        else        { /* Some other tag-related error. */            err = FR_INTERNAL_SYSTEM_ERROR;        }        assert(err != FR_UNSET);        return err;    }    /***** No operator. *****/    return FR_PARSE_ERROR;}#endif/*--------------------------------------------------------------------------*/FilterResult filter(const char *start,                     const char **end,                     SLPAttributes slp_attr,                     int recursion_depth)/* Parameters:                                                              *//* start -- (IN) The start of the string to work in.                        *//* end -- (OUT) The end of the string processed. After successful processing*//*              (ie, no PARSE_ERRORs), this will be pointed at the character*//*              following the last char in this level of the expression.    *//* slp_attr -- (IN) The attributes handle to compare on.                    *//* return_value -- (OUT) The result of the search. Only valid if SLP_OK was *//*                       returned.                                          *//*                                                                          *//* Returns: SLP_OK on successful search (ie, the search was do-able).       *//*          SLP_PARSE_ERROR on search error.  The end of the expression is  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -