📄 libslpattr.c
字号:
* 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_str( SLPAttributes attr_h, const char *tag, char ***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_STRING) { return SLP_TYPE_ERROR; } /***** Create return value. *****/ *size = var->list_size; *val = (char **)malloc( sizeof(char *) * 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] = strdup(value->data.va_str); */ (*val)[i] = malloc(value->unescaped_len + 1); assert((*val)[i] != NULL); memcpy((*val)[i], value->data.va_str, value->unescaped_len); (*val)[i][value->unescaped_len] = 0; } return SLP_OK;}/* Get opaque values. Since opaque attributes can be multivalued, an array * is returned that contains all values corresponding to the given tag. * * * Note: On success, an array of SLP_OPAQUEs is created. It is the caller's * responsibility to free the memory returned through val. Note that the array * referencing the opaques is allocated separately from each opaque struct, * and from the corresponding opaque value, meaning that each value must * explicitly be deallocated, as must each opaque struct. * * 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_opaque( SLPAttributes attr_h, const char *tag, SLPOpaque ***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_OPAQUE) { return SLP_TYPE_ERROR; } /***** Create return value. *****/ *size = var->list_size; *val = (SLPOpaque **)malloc( sizeof(SLPOpaque *) * 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] = (SLPOpaque *)malloc( sizeof(SLPOpaque) ); if((*val)[i]->data == NULL) { /* TODO Deallocate everything and return. */ return SLP_MEMORY_ALLOC_FAILED; } (*val)[i]->len = value->unescaped_len; (*val)[i]->data = (char *)malloc( value->unescaped_len ); if((*val)[i]->data == NULL) { /* TODO Deallocate everything and return. */ return SLP_MEMORY_ALLOC_FAILED; } memcpy((*val)[i]->data, value->data.va_str, value->unescaped_len); } return SLP_OK;}/* Finds the type of the given attribute. * * Returns: * SLP_OK * If the attribute is set. The type is returned through the type * parameter. * SLP_TAG_ERROR * If the attribute is not set. */SLPError SLPAttrGetType_len(SLPAttributes attr_h, const char *tag, int tag_len, SLPType *type){ struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; var_t *var; var = attr_val_find_str(slp_attr, tag, tag_len); /***** Check that the tag exists. *****/ if(var == NULL) { return SLP_TAG_ERROR; } if(type != NULL) { *type = var->type; } return SLP_OK;}SLPError SLPAttrGetType(SLPAttributes attr_h, const char *tag, SLPType *type){ return SLPAttrGetType_len(attr_h, tag, strlen(tag), type);}#if 1 /* Jim Meyer's byte allignment code *//****************************************************************************** * * Fix memory alignment ******************************************************************************/char *fix_memory_alignment(char *p){ unsigned long address = (unsigned long)p; address = (address + sizeof(long) - 1) & ~(sizeof(long) - 1); return (char *)address;}#endif/****************************************************************************** * * Attribute (En|De)coding * *****************************************************************************//* Stores a list of serialized attributes. Takes advantage of foreknowledge of * stuff string sizes, etc. * * Params: * tag -- (IN) the name of the attribute * tag_len -- (IN) the length of the tag in bytes * attr_start -- (IN) the start of the attribute string * attr_end -- (IN) the end of the attribute string * val_count -- (IN) the number of values in the string * type -- (IN) the type of the string * unescaped_len -- (IN) the length of the unescaped data * * Returns: * 0 - Out of mem. * 1 - Success. */int internal_store( struct xx_SLPAttributes *slp_attr, char const *tag, int tag_len, char const *attr_start, char const *attr_end, int val_count, SLPType type, int unescaped_len){ var_t *var; int block_size; char *mem_block; /* Pointer into allocated block. */ char const *cur_start; /* Pointer into attribute list (start of current data). */ char const *cur_end; /* Pointer into attribute list (end of current data). */ value_t *val = 0; value_t **next_val_ptr; /* Pointer from the previous val to the next val. */ assert(type == SLP_BOOLEAN || type == SLP_STRING || type == SLP_OPAQUE || type == SLP_INTEGER); /* Ensure that we're dealing with a known type. */ /***** Allocate space for the variable. *****/ block_size = sizeof(var_t) + (tag_len); /* The var_t */ var = (var_t *)malloc(block_size); if(var == NULL) { return 0; } /***** Allocate space for the values. *****/ block_size = (val_count * sizeof(value_t)) /* Size of each value */ + unescaped_len /* The size of the unescaped data. */#if 1 /* Jim Meyer's byte allignment code */ + val_count * (sizeof(long) - 1); /* Padding */#endif mem_block = (char *)malloc(block_size); if(mem_block == NULL) { free(val); return 0; } /***** Initialize var_t. *****/ var->tag_len = tag_len; var->tag = ((char *)var) + sizeof(var_t); memcpy((char *)var->tag, tag, var->tag_len); var->type = type; var->list_size = val_count; var->modified = SLP_TRUE; next_val_ptr = &var->list; /* Initialize next_val_ptr */ *next_val_ptr = NULL; /***** Initialize values. *****/ cur_end = cur_start = attr_start; while(cur_end < attr_end) { /**** Find the size of the data. ****/ cur_end = memchr(cur_start, VAR_SEPARATOR, attr_end - cur_start); if(cur_end == NULL) { cur_end = attr_end; } /**** Create the value. ****/ *next_val_ptr = val = (value_t *)mem_block; val->next = NULL; /* Set forward pointer to null. */ val->next_chunk = NULL; /* This is not the first. */ val->last_value_in_chunk = NULL; /**** Update kept data. ****/ next_val_ptr = &val->next; /* Book-keeping for next write. */ mem_block += sizeof(value_t); /* Move along. */ /**** FIXME Write the data. ****/ switch(type) { case(SLP_BOOLEAN): assert(val_count == 1); /* Set value. */ if(*cur_start == 't' || *cur_start == 'T') { assert(strncasecmp(cur_start, BOOL_TRUE_STR, BOOL_TRUE_STR_LEN) == 0); /* Make sure that we do, in actual fact, have the string "true". */ val->data.va_bool = SLP_TRUE; val->escaped_len = BOOL_TRUE_STR_LEN; } else if(*cur_start == 'f' || *cur_start == 'F') { assert(strncasecmp(cur_start, BOOL_FALSE_STR, BOOL_FALSE_STR_LEN) == 0); /* Make sure that we do, in actual fact, have the string "false". */ val->data.va_bool = SLP_FALSE; val->escaped_len = BOOL_FALSE_STR_LEN; } else { assert(0); } mem_block += val->unescaped_len; break; case(SLP_INTEGER): val->data.va_int = (int) strtol(cur_start, NULL, 0); val->escaped_len = count_digits(val->data.va_int); /* FIXME Check errno. */ break; case(SLP_OPAQUE): case(SLP_STRING): { char *err; val->data.va_str = mem_block; val->escaped_len = cur_end - cur_start; err = unescape_into(val->data.va_str, cur_start, val->escaped_len, &val->unescaped_len); if(err == NULL) { /* FIXME */ } mem_block += val->unescaped_len; } break; default: assert(0); /* Unknown type. */ }#if 1 /* Jim Meyer's byte allignment code */ mem_block = fix_memory_alignment(mem_block);#endif cur_start = cur_end + 1; /* +1 to move past comma. */ } /***** Set pointers for memory management. *****/ var->list->last_value_in_chunk = val; mem_block = mem_block + sizeof(value_t); attr_add(slp_attr, var); return 1; /* Success. */}/* Iterates across a set of variables. Either by using a given list of tag * names, or looping across all list members. * * Params: * slp_attr -- (IN) the attribute list we're working in * tag_cur -- (IN/OUT) the current position in the tag string. Must be * initialized to point to the start of a tag list. * tag_end -- (IN/OUT) the end of the current tag. Must be initialized to * the same value as tag_cur. * var -- (IN/OUT) the variable in question. Must be initialized to the first * variable in a list of attributes. * * Returns: * 1 if there are more vars to be iterated over * 0 if there are no more vars to be iterated over */int var_iter(struct xx_SLPAttributes *slp_attr, char **tag_cur, char **tag_end, var_t **var){ /*** Get the next var. ***/ if(*tag_cur) { /*** We're doing a tag perusal: find next tag name. ***/ if(**tag_end) { /* There are more tags to be looked at */ if(*tag_end != *tag_cur) { /* This is _not_ our first time thru the loop: push pointers ahead. */ *tag_cur = *tag_end + 1; } *tag_end = strchr(*tag_cur, ','); /* This is the last tag. */ if(*tag_end == NULL) { *tag_end = *tag_cur + strlen(*tag_cur); } } else { /* There are no more tags to be looked at. Stop looping. */ return 0; } /*** Get named var. ***/ *var = attr_val_find_str(slp_attr, *tag_cur, *tag_end - *tag_cur); return 1; } else { /*** We're getting all vars: get the next var. ***/ if(*var) { *var = (*var)->next; } else { /* First time into the iterator. */ *var = slp_attr->attrs; } if(*var == NULL) { /* Last var. Stop looping. */ return 0; } return 1; }}/* Gets the escaped stringified version of an attribute list. * * The string returned must be free()'d by the caller. * * Params: * attr_h -- (IN) Attribute handle to add serialize. * tags -- (IN) The tags to serialize. If NULL, all tags are serialized. * out_buffer -- (IN/OUT) A buffer to write the serialized string to. If * (*out_buffer == NULL), then a new buffer is allocated by * the API. * bufferlen -- (IN) The length of the buffer. Ignored if * (*out_buffer == NULL). * count -- (OUT) The size needed/used of out_buffer (includes trailing null). * find_delta -- (IN) If find_delta is set to true, only the attributes that * have changed since the last serialize are updated. * * Returns: * SLP_OK -- Serialization occured. * SLP_BUFFER_OVERFLOW -- If (*out_buffer) is defined, but bufferlen is * smaller than the amount of memory necessary to serialize * the attr. list. * SLP_MEMORY_ALLOC_FAILED -- Ran out of memory. */SLPError SLPAttrSerialize(SLPAttributes attr_h, const char* tags /* NULL terminated */, char **out_buffer /* Where to write. if *out_buffer == NULL, space is alloc'd */, int bufferlen, /* Size of buffer. */ int* count, /* Bytes needed/written. */ SLPBoolean find_delta ){ struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; var_t *var; /* For iterating over attributes to serialize. */ unsigned int size; /* Size of the string to allocate. */ unsigned int var_count; /* To count the number of variables. */ char *build_str; /* The string that is being built. */ char *cur; /* Current location within the already allocated str. */ char *tag_cur; /* Current position within tag string. */ char *tag_end; /* end of current position within tag string. */ size = 0; var_count = 0; /***** Decide on our looping mode. *****/ if(tags == NULL || *tags == 0) { tag_cur = NULL; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -