📄 libslpattr.c
字号:
/* Find the size of an escaped string. * * The "optional" len argument is the length of the string. If it is * negative, the function treats the string as a null-terminated string. If it * is positive, the function will read exactly that number of characters. */int find_escaped_size(const char *str, int len){ int i; /* Index into str. */ int escaped_size; /* The size of the thingy. */ i =0; escaped_size = 0; if(len < 0) { /***** String is null-terminated. *****/ for(i = 0; str[i]; i++) { if(is_legal_slp_char(str[i]) == SLP_TRUE) { escaped_size++; } else { escaped_size += ESCAPED_LEN; } } } else { for(i = 0; i < len; i++) { if(is_legal_slp_char(str[i]) == SLP_TRUE) { escaped_size++; } else { escaped_size += ESCAPED_LEN; } } } return escaped_size;}/* Escape a single character. Writes the escaped value into dest, and * increments dest. * * NOTE: Most of this code is stolen from Dave McCormack's SLPEscape() code. * (For OpenSLP). */void escape(char to_escape, char **dest, SLPBoolean (test_fn)(const char)){ char hex_digit; if(test_fn(to_escape) == SLP_FALSE) { /* Insert the escape character. */ **dest = ESCAPE_CHARACTER; (*dest)++; /* Do the first digit. */ hex_digit = (to_escape & 0xF0)/0x0F; if((hex_digit >= 0) && (hex_digit <= 9)) **dest = hex_digit + '0'; else **dest = hex_digit + 'A' - 0x0A; (*dest)++; /* Do the last digit. */ hex_digit = to_escape & 0x0F; if((hex_digit >= 0) && (hex_digit <= 9)) **dest = hex_digit + '0'; else **dest = hex_digit + 'A' - 0x0A; (*dest)++; } else { /* It's legal. */ **dest = to_escape; (*dest)++; } }/* Escape the passed string (src), writing it into the other passed string * (dest). * * If the len argument is negative, the src is treated as null-terminated, * otherwise that length is escaped. * * Returns a pointer to where the addition has ended. */char *escape_into(char *dest, char *src, int len){ char *cur_dest; /* Current character in dest. */ cur_dest = dest; if(len < 0) { /* Treat as null terminated. */ char *cur_src; /* Current character in src. */ cur_src = src; for(; *cur_src; cur_src++) { escape(*cur_src, &cur_dest, is_legal_slp_char); } } else { /* known length. */ int i; /* Index into src. */ for(i = 0; i < len; i++) { escape(src[i], &cur_dest, is_legal_slp_char); } } return cur_dest;}/* Special case for escaping opaque strings. Escapes _every_ character in the * string. * * Note that the size parameter _must_ be defined. * * Returns a pointer to where the addition has ended. */char *escape_opaque_into(char *dest, char *src, int len){ int i; /* Index into src. */ char *cur_dest; cur_dest = dest; for(i = 0; i < len; i++) { escape(src[i], &cur_dest, opaque_test); } return cur_dest;}/****************************************************************************** * * Individual values * * What is a value? * * In SLP an individual attribute can be associated with a list of values. A * value is the data associated with a tag. Depending on the type of * attribute, there can be zero, one, or many values associated with a single * tag. *****************************************************************************//* See libslpattr_internal.h for implementation. *//* Create and initialize a new value. * * Params: * extra -- amount of memory to allocate in addition to that needed for the value. This memory can be found at (return_value + sizeof(value_t)) */value_t *value_new(int extra){ value_t *value = NULL; value = (value_t *)malloc(sizeof(value_t) + extra); if(value == NULL) return NULL; value->next = NULL; value->data.va_str = NULL; value->escaped_len = -1; value->unescaped_len = -1; value->next_chunk = NULL; value->last_value_in_chunk = value; return value;}/* Destroy a value. */void value_free(value_t *value){ assert(value->next == NULL); free(value);}/****************************************************************************** * * Individual attributes (vars) * * What is a var? * * A var is a variable tag that is associated with a list of values. Zero or * more vars are kept in a single SLPAttributes object. Each value stored in * a var is kept in a value struct. *****************************************************************************//* See libslpattr_internal.h for struct. *//* Create a new variable. * * FIXME should take tag_len as an argument */var_t *var_new(char *tag, int tag_len){ var_t *var; /* Variable being created. */ assert(tag != NULL); /***** Allocate. *****/ var = (var_t *)malloc(sizeof(var_t) + tag_len + 1); /* +1 for null. */ if(var == NULL) return NULL; /***** Initialize. *****/ var->next = NULL; var->tag_len = tag_len; var->tag = ((char *)var) + sizeof(var_t); memcpy((void *)var->tag, tag, var->tag_len); ((char *)(var->tag))[var->tag_len] = 0; var->type = -1; var->list = NULL; var->list_size = 0; var->modified = SLP_TRUE; return var;}/* Destroy a value list. Note that the var is not free()'d, only reset. */void var_list_destroy(var_t *var){ value_t *value; value_t *to_free; /* A pointer back in the value list to free. */ /***** Check for data. *****/ if(var->list == NULL) { assert(var->list_size == 0); return; } /***** Burrow through the value list deleting every chunk of memory behind us as we go. *****/ value = var->list; to_free = NULL; while(value) { to_free = value; value = value->next_chunk; free(to_free); } /***** Reset the list. *****/ var->list = NULL; var->list_size = 0;}/* Frees a variable. */void var_free(var_t *var){ /***** Sanity check. *****/ assert(var->next == NULL); /***** Free variable. *****/ var_list_destroy(var); free(var);}/* Adds a value to a variable. */SLPError var_insert(var_t *var, value_t *value, SLPInsertionPolicy policy){ assert(policy == SLP_ADD || policy == SLP_REPLACE); if(value == NULL) { return SLP_OK; } if(policy == SLP_REPLACE) { var_list_destroy(var); } /* Update list. */ value->last_value_in_chunk->next = var->list; value->next_chunk = var->list; /* Update the memory list too. */ var->list = value; var->list_size++; /* Set mod flag.*/ var->modified = SLP_TRUE; return SLP_OK;}/****************************************************************************** * * All the attributes. * *****************************************************************************//* * SLPAttrAlloc() creates and initializes a new instance of SLPAttributes. */SLPError SLPAttrAlloc( const char *lang, const FILE *template_h, const SLPBoolean strict, SLPAttributes *slp_attr_h ){ struct xx_SLPAttributes **slp_attr; slp_attr = (struct xx_SLPAttributes **)slp_attr_h; /***** Sanity check *****/ if(strict == SLP_FALSE && template_h != NULL) { /* We can't be strict if we don't have a template. */ return SLP_PARAMETER_BAD; } if(strict != SLP_FALSE) { return SLP_NOT_IMPLEMENTED; } if(template_h != NULL) { return SLP_NOT_IMPLEMENTED; } /***** Create. *****/ (*slp_attr) = (struct xx_SLPAttributes *)malloc( sizeof(struct xx_SLPAttributes) ); if(*slp_attr == NULL) { return SLP_MEMORY_ALLOC_FAILED; } /***** Initialize *****/ (*slp_attr)->strict = SLP_FALSE; /* FIXME Add templates. */ (*slp_attr)->lang = strdup(lang); /* free()'d in SLPAttrFree(). */ (*slp_attr)->attrs = NULL; (*slp_attr)->attr_count = 0; /***** Report. *****/ return SLP_OK;}SLPError attr_destringify(struct xx_SLPAttributes *slp_attr, const char *str, SLPInsertionPolicy); /* Allocates a new attribute list from a string. */SLPError SLPAttrAllocStr( const char *lang, const FILE *template_h, const SLPBoolean strict, SLPAttributes *slp_attr_h, const char *str ){ SLPError err; err = SLPAttrAlloc(lang, template_h, strict, slp_attr_h); if(err != SLP_OK) { return err; } err = attr_destringify((struct xx_SLPAttributes*)*slp_attr_h, str, SLP_ADD); if(err != SLP_OK) { SLPAttrFree(*slp_attr_h); } return err;}/* Destroys the passed SLPAttributes(). */void SLPAttrFree(SLPAttributes slp_attr_h){ struct xx_SLPAttributes *slp_attr; slp_attr = (struct xx_SLPAttributes *)slp_attr_h; /***** Free held resources. *****/ while(slp_attr->attrs) { var_t *attr = slp_attr->attrs; slp_attr->attrs = attr->next; attr->next = NULL; var_free(attr); } free(slp_attr->lang); slp_attr->lang = NULL; /***** Free the handle *****/ free(slp_attr); slp_attr = NULL;}/* Insert a variable into the var list. */void attr_add(struct xx_SLPAttributes *slp_attr, var_t *var){ var->next = slp_attr->attrs; slp_attr->attrs = var; slp_attr->attr_count++;}/* Find a variable by its tag. * * Returns a NULL if the value could not be found. */var_t *attr_val_find_str(struct xx_SLPAttributes *slp_attr, const char *tag, int tag_len){ var_t *var; var = slp_attr->attrs; while(var) { /* Per RFC 2165 (Section 20.5 para 1), RFC 2608 (Section 6.4 para 3), * attr-tags are supposed to be case insensitive. * Using strncasecmp() so that comparision of tags are case-insensitive * atleast inside the ASCII range. */ if(var->tag_len == (unsigned)tag_len && strncasecmp(var->tag, tag, tag_len) == 0) { return var; } var = var->next; } return NULL;}/* Test a variable's type. Returns SLP_OK if the match is alright, or some * other error code (meant to be forwarded to the application) if the match is * bad. */SLPError attr_type_verify(struct xx_SLPAttributes *slp_attr, var_t *var, SLPType type){ assert(var->type != -1); /* Check that it's been set. */ if(var->type == type) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -