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

📄 libslpattr.c

📁 SLP协议在linux下的实现。此版本为1.2.1版。官方网站为www.openslp.org
💻 C
📖 第 1 页 / 共 5 页
字号:
    {        tag_cur = (char *)tags;    }    tag_end = tag_cur;    var = NULL;    /***** Find the size of string needed for the attribute string. *****/    while(var_iter(slp_attr, &tag_cur, &tag_end, &var))    {        /*** Skip bad tags? ***/        if(var == NULL)        {            continue;        }                /*** Skip old attributes. ***/        if(find_delta == SLP_TRUE && var->modified == SLP_FALSE)        {            continue;        }        /*** Get size of tag ***/        size += var->tag_len;        /*** Count the size needed for the value list ***/        if(var->type != SLP_KEYWORD)        {            value_t *value;            /** Get size of data **/            value = var->list;            while(value)            {                size += value->escaped_len;                value = value->next;            }            /** Count number of commas needed for multivalued attributes. **/            assert(var->list_size >= 0);            size += (var->list_size - 1) * VAR_SEPARATOR_LEN;            /** Count the semantics needed to store a multivalue list **/            size += VAR_NON_KEYWORD_SEMANTIC_LEN;        }        else        {            assert(var->list == NULL);        }        /*** Count number of variables ***/        var_count++;    }    /*** Count the number of characters between attributes. ***/    if(var_count > 0)    {        size += (var_count - 1) * VAR_SEPARATOR_LEN;    }    /***** Return the size needed/used. *****/    if(count != NULL)    {        *count = size + 1;    }    /***** Create the string. *****/    if(*out_buffer == NULL)    {        /* We have to locally alloc the string. */        build_str = (char *)malloc( size + 1);        if(build_str == NULL)        {            return SLP_MEMORY_ALLOC_FAILED;        }    }    else    {        /* We write into a pre-alloc'd buffer. */        /**** Check that out_buffer is big enough. ****/        if((int)size + 1 > bufferlen)        {            return SLP_BUFFER_OVERFLOW;        }        build_str = *out_buffer;    }    build_str[0] = '\0';    /***** Add values *****/    /**** Decide on our looping mode. ****/    if(tags == NULL || *tags == 0)    {        tag_cur = NULL;    }    else    {        tag_cur = (char *)tags;    }    tag_end = tag_cur;    var = NULL;    /**** Find the size of string needed for the attribute string. ****/    cur = build_str;    while(var_iter(slp_attr, &tag_cur, &tag_end, &var))    {        /*** Skip bad tags? ***/        if(var == NULL)        {            continue;        }                /*** Skip old attributes. ***/        if(find_delta == SLP_TRUE && var->modified == SLP_FALSE)        {            continue;        }        if(var->type == SLP_KEYWORD)        {            /**** Handle keywords. ****/            memcpy(cur, var->tag, var->tag_len);            cur += var->tag_len;        }        else        {            /**** Handle everything else. ****/            char *to_add;            int to_add_len;            value_t *value;            /*** Add the prefix. ***/            *cur = VAR_PREFIX;            cur += VAR_PREFIX_LEN;            /*** Add the tag. ***/            memcpy(cur, var->tag, var->tag_len);            cur += var->tag_len;            /*** Add the infix. ***/            *cur = VAR_INFIX;            cur += VAR_INFIX_LEN;            /*** Insert value (list) ***/            value = var->list;            assert(value);            while(value)            { /* foreach member value of an attribute. */                assert(var->type != SLP_KEYWORD);                switch(var->type)                {                case(SLP_BOOLEAN):                    assert(value->next == NULL); /* Can't be a multivalued list. */                    assert(value->data.va_bool == SLP_TRUE                            || value->data.va_bool == SLP_FALSE);                    if(value->data.va_bool == SLP_TRUE)                    {                        to_add = BOOL_TRUE_STR;                        to_add_len = BOOL_TRUE_STR_LEN;                    }                    else                    {                        to_add = BOOL_FALSE_STR;                        to_add_len = BOOL_FALSE_STR_LEN;                    }                    memcpy(cur, to_add, to_add_len);                    cur += to_add_len;                    break;                case(SLP_STRING):                    cur = escape_into(cur, value->data.va_str, value->unescaped_len);                    break;                case(SLP_INTEGER):                    sprintf(cur, "%d", value->data.va_int);                    cur += value->escaped_len;                    break;                case(SLP_OPAQUE):                    memcpy(cur, OPAQUE_PREFIX, OPAQUE_PREFIX_LEN);                    cur += OPAQUE_PREFIX_LEN;                    cur = escape_opaque_into(cur, value->data.va_str, value->unescaped_len);                    break;                default:                    printf("Unknown type (%s:%d).\n", __FILE__, __LINE__);                    /* TODO Clean up memory leak: the output string */                    return SLP_INTERNAL_SYSTEM_ERROR;                }                value = value->next;                /*** Add separator (if necessary) ***/                if(value != NULL)                {                    *cur = VAR_SEPARATOR;                    cur += VAR_SEPARATOR_LEN;                    *cur = 0;                }            }            /*** Add the suffix. ***/            *cur = VAR_SUFFIX;            cur += VAR_SUFFIX_LEN;            *cur = 0;        }        /*** Add separator. This is fixed for the last val outside the loop ***/        /* if (var->next != NULL) { */        if((unsigned)(cur - build_str) < size)        {            *cur = VAR_SEPARATOR;            cur += VAR_SEPARATOR_LEN;            *cur = 0;        }        /*** Reset the modified flag. ***/        var->modified = SLP_FALSE;    }    /**** Shift back to erase the last comma. ****/    /***** Append a null (This is actually done by strcpy, but its better to     * be safe than sorry =) *****/    *cur = '\0';    assert((unsigned)(cur - build_str) == size && size == strlen(build_str));    *out_buffer = build_str;    return SLP_OK;}   /* Stores an escaped value into an attribute. Determines type of attribute at  * the same time. * * tag must be null terminated.  * val must be of length len. * policy will only be respected where it can be (ints, strings, and opaques). * * the contents of tag are NOT verified.  *  * Returns:  *  SLP_PARAMETER_BAD - Syntax error in the value. *  SLP_MEMORY_ALLOC_FAILED */SLPError SLPAttrStore(struct xx_SLPAttributes *slp_attr,                       const char *tag,                      const char *val,                      int len,                      SLPInsertionPolicy policy                     ){    int i; /* Index into val. */    SLPBoolean is_str; /* Flag used for checking if given is string. */    char *unescaped;    int unescaped_len; /* Length of the unescaped text. */    /***** Check opaque. *****/    if(strncmp(val, OPAQUE_PREFIX, OPAQUE_PREFIX_LEN) == 0)    {        /*** Verify length (ie, that it is the multiple of the size of an         * escaped character). ***/        if(len % ESCAPED_LEN != 0)        {            return SLP_PARAMETER_BAD;        }        unescaped_len = (len / ESCAPED_LEN) - 1; /* -1 to drop the OPAQUE_PREFIX. */        /*** Verify that every character has been escaped. ***/        /* TODO */        /***** Unescape the value. *****/        unescaped = (char *)malloc(unescaped_len);        if(unescaped == NULL)        {            return SLP_MEMORY_ALLOC_FAILED; /* FIXME: Real error code. */        }        if(unescape_into(unescaped, (char *)(val + OPAQUE_PREFIX_LEN), len - OPAQUE_PREFIX_LEN, NULL) != NULL)        {            SLPError err;            err = SLPAttrSet_opaque((SLPAttributes)slp_attr, tag, unescaped, (len - OPAQUE_PREFIX_LEN) / 3, policy);            free(unescaped);/* FIXME This should be put into the val, and free()'d in val_destroy(). */            return err;        }        return SLP_PARAMETER_BAD; /* FIXME Verify. Is this really a bad parameter?*/    }    /***** Check boolean. *****/    if((BOOL_TRUE_STR_LEN == len) && (strncmp(val, BOOL_TRUE_STR, len) == 0))    {        return SLPAttrSet_bool((SLPAttributes)slp_attr, tag, SLP_TRUE);    }    if((BOOL_FALSE_STR_LEN == len) && strncmp(val, BOOL_FALSE_STR, len) == 0)    {        return SLPAttrSet_bool((SLPAttributes)slp_attr, tag, SLP_FALSE);    }    /***** Check integer *****/    if(*val == '-' || isdigit((int)*val))    {        /*** Verify. ***/        SLPBoolean is_int = SLP_TRUE; /* Flag true if the attr is an int. */        for(i = 1; i < len; i++)        { /* We start at 1 since first char has already been checked. */            if(!isdigit((int)val[i]))            {                is_int = SLP_FALSE;                break;            }        }        /*** Handle the int-ness. ***/        if(is_int == SLP_TRUE)        {            char *end; /* To verify that the correct length was read. */            SLPError err;            err = SLPAttrSet_int((SLPAttributes)slp_attr, tag, (int) strtol(val, &end, 10), policy);            assert(end == val + len);            return err;        }    }    /***** Check string. *****/    is_str = SLP_TRUE;    for(i = 0; i < len; i++)    {        if(IS_RESERVED(val[i]) && (val[i] != '\\'))        {            is_str = SLP_FALSE;            break;        }    }    if(is_str == SLP_TRUE)    {        unescaped_len = find_unescaped_size(val, len);        unescaped = (char *)malloc( unescaped_len + 1 );         if(unescape_into(unescaped, val, len, NULL) != NULL)        {            SLPError err;            unescaped[unescaped_len] = '\0';            err = SLPAttrSet_str((SLPAttributes)slp_attr, tag, unescaped, policy);            free(unescaped); /* FIXME This should be put into the val, and free()'d in val_destroy(). */            return err;         }        return SLP_PARAMETER_BAD;    }    /* We don't bother checking for a keyword attribute since it can't have a     * value.      */    return SLP_PARAMETER_BAD; /* Could not determine type. */}/* Converts an attribute string into an attr struct.  * * Note that the attribute string is trashed. * * Returns: *  SLP_PARAMETER_BAD -- If there is a parse error in the attribute string.  *  SLP_OK -- If everything went okay. */SLPError attr_destringify(                         struct xx_SLPAttributes *slp_attr,                          char const *str,                          SLPInsertionPolicy policy                         ){    char const *cur; /* Current index into str. */    enum    {        /* Note: everything contained in []s in this enum is a production from         * RFC 2608's grammar defining attribute lists.          */        START_ATTR /* The start of an individual [attribute]. */,        START_TAG /* The start of a [attr-tag]. */,        VALUE /* The start of an [attr-val]. */,        STOP_VALUE /* The end of an [attr-val]. */    } state = START_ATTR; /* The current state of the parse. */    char const *tag; /* A tag that has been parsed. (carries data across state changes)*/    int tag_len = 0; /* length of the tag (in bytes) */    assert(str != NULL);    if(strlen(str) == 0)    {        return SLP_OK;    }    tag = NULL;    cur = str;    /***** Pull apart str. *****/    while(*cur)    {        char const *end; /* The end of a parse entity. */        switch(state)        {        case(START_ATTR): /* At the beginning of an attribute. */            if(*cur == VAR_PREFIX)            {                /* At the start of a non-keyword. */                state = START_TAG;                cur += VAR_PREFIX_LEN;            }            else            {                /* At the start of a keyword:                 * Gobble up the keyword and set it.                  */                end = find_tag_end(cur);                if(end == NULL)                {                    /* FIXME Ummm, I dunno. */                    assert(0);                }                /*** Check that the tag ends on a legal ending char. ***/                if(*end == ',')                {                    /** Add the keyword. **/                    SLPAttrSet_keyw_len((SLPAttributes)slp_attr, cur, end - cur);                    cur = end + 1;                    break;                }                else if(*end == '\0')                {                    SLPAttrSet_keyw_len((SLPAttributes)slp_attr, cur, end - cur);                    return SLP_OK; /* FIXME Return success. */                    break;                }                else                {                    return SLP_PARAMETER_BAD; /* FIXME Return error code. -- Illegal tag char */                }            }            break;        case(START_TAG): /* At the beginning of a tag, in brackets. */            end = find_tag_end(cur);            if(end == NULL)            {                return SLP_PARAMETER_BAD; /* FIXME Err. code -- Illegal char. */            }            if(*end == '\0')            {                return SLP_PARAMETER_BAD; /* FIXME err: Premature end. */            }            /*** Check the the end character is valid. ***/            if(*end == VAR_INFIX)            {                tag_len = (int)(end - cur); /* Note that end is on the character _after_ the last character of the tag (the =). */                assert(tag == NULL);                tag = cur;                 cur = end + VAR_INFIX_LEN;                state = VALUE;            }            else            {                /** ERROR! **/                return SLP_PARAMETER_BAD; /* FIXME Err. code.-- Logic error. */            }            break;        case(VALUE): /*

⌨️ 快捷键说明

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