📄 libslpattr.c
字号:
return SLP_OK; } return SLP_TYPE_ERROR; /* FIXME: Check against template. */}/****************************************************************************** * * Setting attributes * *****************************************************************************//*****************************************************************************/SLPError generic_set_val(struct xx_SLPAttributes *slp_attr, const char *tag, int tag_len, value_t *value, SLPInsertionPolicy policy, SLPType attr_type) /* Finds and sets the value named in tag. *//* * slp_attr - the attr object to add to. * tag - the name of the tag to add to. * value - the already-allocated value object with fields set * policy - the policy to use when inserting. * attr_type - the type of the value being added. *****************************************************************************/{ var_t *var; /***** Create a new attribute. *****/ if((var = attr_val_find_str(slp_attr, tag, strlen(tag))) == NULL) { /*** Couldn't find a value with this tag. Make a new one. ***/ var = var_new((char *)tag, tag_len); if(var == NULL) { return SLP_MEMORY_ALLOC_FAILED; } var->type = attr_type; /** Add variable to list. **/ attr_add(slp_attr, var); } else { SLPError err; /*** The attribute already exists. ***/ /*** Verify type. ***/ err = attr_type_verify(slp_attr, var, attr_type); if(err == SLP_TYPE_ERROR && policy == SLP_REPLACE) { var_list_destroy(var); var->type = attr_type; } else if(err != SLP_OK) { value_free(value); return err; } } /***** Set value *****/ var_insert(var, value, policy); return SLP_OK;}/* Set a boolean attribute. */SLPError SLPAttrSet_bool( SLPAttributes attr_h, const char *tag, SLPBoolean val ){ struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; value_t *value = NULL; int escaped_len; /***** Sanity check. *****/ if(val != SLP_TRUE && val != SLP_FALSE) { return SLP_PARAMETER_BAD; } if(is_valid_tag(tag) == SLP_FALSE) { return SLP_TAG_BAD; } /***** Set the initial (and only) value. *****/ /**** Create ****/ value = value_new(0); assert(value); /**** Set escaped information. ****/ if(val == SLP_TRUE) { escaped_len = BOOL_TRUE_STR_LEN; } else { escaped_len = BOOL_FALSE_STR_LEN; } value->escaped_len = escaped_len; value->data.va_bool = val; /**** Set the value and return. ****/ return generic_set_val(slp_attr, tag, (int)strlen(tag), value, SLP_REPLACE, SLP_BOOLEAN);}/* Sets a string attribute. */SLPError SLPAttrSet_str( SLPAttributes attr_h, const char *tag, const char *val, SLPInsertionPolicy policy ){ struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; value_t *value; int unescaped_len; /***** Sanity check. *****/ if(is_valid_tag(tag) == SLP_FALSE) { return SLP_TAG_BAD; } if(val == NULL) { return SLP_PARAMETER_BAD; } /***** Create new value. *****/ unescaped_len = strlen(val); value = value_new(unescaped_len); assert(value); /**** Copy data. ****/ value->data.va_str = ((char *)value) + sizeof(value_t); memcpy(value->data.va_str, val, unescaped_len); /**** Set lengths. ****/ value->unescaped_len = unescaped_len; value->escaped_len = find_escaped_size(value->data.va_str, unescaped_len); return generic_set_val(slp_attr, tag, (int)strlen(tag), value, policy, SLP_STRING);}/* Sets a keyword attribute. Takes a non-null terminated string. */SLPError SLPAttrSet_keyw_len( SLPAttributes attr_h, const char *tag, int tag_len ){ struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; /***** Sanity check. *****/ if(is_valid_tag(tag) == SLP_FALSE) { return SLP_TAG_BAD; } return generic_set_val(slp_attr, tag, tag_len, NULL, SLP_REPLACE, SLP_KEYWORD);}SLPError SLPAttrSet_keyw( SLPAttributes attr_h, const char *tag ){ return SLPAttrSet_keyw_len(attr_h, tag, (int)strlen(tag));}/* Sets an integer attribute. */SLPError SLPAttrSet_int( SLPAttributes attr_h, const char *tag, int val, SLPInsertionPolicy policy ){ struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; value_t *value; /***** Sanity check. *****/ if(is_valid_tag(tag) == SLP_FALSE) { return SLP_TAG_BAD; } /***** Create new value. *****/ value = value_new(0); if(value == NULL) { return SLP_MEMORY_ALLOC_FAILED; } /**** Set ****/ value->data.va_int = val; value->escaped_len = count_digits(value->data.va_int); assert(value->escaped_len > 0); return generic_set_val(slp_attr, tag, (int)strlen(tag), value, policy, SLP_INTEGER);}/* Set an opaque attribute. */SLPError SLPAttrSet_opaque( SLPAttributes attr_h, const char *tag, const char *val, const unsigned int len, SLPInsertionPolicy policy ){ struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; value_t *value; /***** Sanity check. *****/ if(is_valid_tag(tag) == SLP_FALSE) { return SLP_TAG_BAD; } if(val == NULL) { return SLP_PARAMETER_BAD; } /***** Create a new attribute. *****/ value = value_new(len); if(value == NULL) { return SLP_MEMORY_ALLOC_FAILED; } memcpy((void *)value->data.va_str, val, len); value->unescaped_len = len; value->escaped_len = (len * ESCAPED_LEN) + OPAQUE_PREFIX_LEN; return generic_set_val(slp_attr, tag, (int)strlen(tag), value, policy, SLP_OPAQUE);}SLPError SLPAttrStore(struct xx_SLPAttributes *slp_attr, const char *tag, const char *val, int len, SLPInsertionPolicy policy );/* Set an attribute of unknown type. * * Note that the policy in this case is a special case: If the policy is * SLP_REPLACE, we delete the current list and replace it with the passed * value. If it's a multivalue list, we replace the current value with the * ENTIRE passed list. * * FIXME Should we "elide" whitespace? */SLPError SLPAttrSet_guess( SLPAttributes attr_h, const char *tag, const char *val, SLPInsertionPolicy policy ){ SLPError err; int len; const char *cur, *end; /***** Sanity check. *****/ if(is_valid_tag(tag) == SLP_FALSE) { return SLP_TAG_BAD; } if(val == NULL) { return SLP_PARAMETER_BAD; } /***** * If we have a replace policy and we're inserting a multivalued list, * the values will clobber each other. Therefore if we have a replace, we * delete the current list, and use an add policy. *****/ if(policy == SLP_REPLACE) { var_t *var; var = attr_val_find_str((struct xx_SLPAttributes *)attr_h, tag, strlen(tag)); if(var) { var_list_destroy(var); } } /***** Check for multivalue list. *****/ cur = val; do { end = strchr(cur, VAR_SEPARATOR); if(end == NULL) { len = strlen(cur); } else { /*** It's multivalue. ***/ len = end - cur; } err = SLPAttrStore((struct xx_SLPAttributes *)attr_h, tag, cur, len, SLP_ADD); if(err != SLP_OK) { /* FIXME Ummm. Should we return or ignore? */ return err; } cur = end + VAR_SEPARATOR_LEN; } while(end); /***** Return *****/ return SLP_OK;}/****************************************************************************** * * Getting attributes * *****************************************************************************//* Get the value of a boolean attribute. Note that it _cannot_ be multivalued. */SLPError SLPAttrGet_bool( SLPAttributes attr_h, const char *tag, SLPBoolean *val ){ struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; var_t *var; var = attr_val_find_str(slp_attr, tag, strlen(tag)); /***** Check that the tag exists. *****/ if(var == NULL) { return SLP_TAG_ERROR; } /* TODO Verify type against template. */ /***** Verify type. *****/ if(var->type != SLP_BOOLEAN) { return SLP_TYPE_ERROR; } assert(var->list != NULL); *val = var->list->data.va_bool; return SLP_OK;}/* Get the value of a keyword attribute. Since keywords either exist or don't * exist, no value is passed out. Instead, if the keyword exists, an SLP_OK is * returned, if it doesn't exist, an SLP_TAG_ERROR is returned. If the tag * does exist, but is associated with a non-keyword attribute, SLP_TYPE_ERROR * is returned. */SLPError SLPAttrGet_keyw( SLPAttributes attr_h, const char *tag ){ struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; var_t *var; var = attr_val_find_str(slp_attr, tag, strlen(tag)); /***** Check that the tag exists. *****/ if(var == NULL) { return SLP_TAG_ERROR; } /* TODO Verify type against template. */ /***** Verify type. *****/ if(var->type != SLP_KEYWORD) { return SLP_TYPE_ERROR; } assert(var->list == NULL); return SLP_OK;}/* Get an integer value. Since integer attributes can be multivalued, an array * is returned that contains all values corresponding to the given tag. * * * Note: On success, an array of SLP_INTEGERs is created. It is the caller's * responsibility to free the memory returned through val. * * Returns: * SLP_OK * Returned if the attribute is found. The array containing the values is * placed in val, and size is set to the number of values in val. * SLP_TYPE_ERROR * Returned if the tag exists, but the associated value is not of type * SLP_INTEGER. * SLP_MEMORY_ALLOC_FAILED * Memory allocation failed. */SLPError SLPAttrGet_int( SLPAttributes attr_h, const char *tag, int **val, int *size ){ struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; var_t *var; value_t *value; int i; var = attr_val_find_str(slp_attr, tag, strlen(tag)); /***** Check that the tag exists. *****/ if(var == NULL) { return SLP_TAG_ERROR; } /* TODO Verify type against template. */ /***** Verify type. *****/ if(var->type != SLP_INTEGER) { return SLP_TYPE_ERROR; } /***** Create return value. *****/ *size = var->list_size; *val = (int *)malloc( sizeof(int) * var->list_size ); if(*val == NULL) { return SLP_MEMORY_ALLOC_FAILED; } /***** Set values *****/ assert(var->list != NULL); value = var->list; for(i = 0; i < var->list_size; i++, value = value->next) { assert(value != NULL); (*val)[i] = value->data.va_int; } return SLP_OK;}/* Get string values. Since string attributes can be multivalued, an array * is returned that contains all values corresponding to the given tag. * * * Note: On success, an array of SLP_STRINGs is created. It is the caller's * responsibility to free the memory returned through val. Note that the array * referencing the strings is allocated separately from each string value, * meaning that each value must explicitly be deallocated. * * Returns:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -