/* 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, long **val, size_t *size ) { struct xx_SLPAttributes *slp_attr = (struct xx_SLPAttributes *)attr_h; var_t *var; value_t *value; size_t i; var = attr_val_find_str(slp_attr, 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 = (long *)malloc( sizeof(long) * 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; }
SLPError generic_set_val(struct xx_SLPAttributes *slp_attr, const char *tag, 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)) == NULL) { /*** Couldn't find a value with this tag. Make a new one. ***/ var = var_new((char *)tag); 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; }
/*--------------------------------------------------------------------------*/ FilterResult opaque_op(SLPAttributes slp_attr, char *tag, int tag_len, char *rhs, int rhs_len, Operation op) /* Perform an opaque operation. */ /*--------------------------------------------------------------------------*/ { char *str_val; /* Converted value of rhs. */ int str_len; /* Length of converted value. */ var_t *var; assert(op != PRESENT); /***** 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; }
/*--------------------------------------------------------------------------*/ FilterResult int_op(SLPAttributes slp_attr, char *tag, int tag_len, char *rhs, Operation op) /* Perform an integer operation. */ /*--------------------------------------------------------------------------*/ { int rhs_val; /* The converted value of rhs. */ char *end; /* Pointer to the end of op. */ var_t *var; /* Pointer to the variable named by tag. */ value_t *value; /* A value in var. */ FilterResult result; /* Value to return. */ assert(op != PRESENT); result = FR_UNSET; /* For verification. */ /* TODO Only do this in debug. */ /***** Verify and convert rhs. *****/ rhs_val = strtol(rhs, &end, 10); if(*end != 0 && *end != BRACKET_CLOSE) { /* Trying to compare an int with a non-int. */ return FR_EVAL_FALSE; } /***** Get variable. *****/ 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_INTEGER) { return FR_EVAL_FALSE; } /***** Compare. *****/ value = var->list; assert(value != NULL); assert(op != PRESENT); switch(op) { case(EQUAL): result = FR_EVAL_FALSE; for(; value; value = value->next) { if(value->data.va_int == rhs_val) { result = FR_EVAL_TRUE; break; } } break; case(APPROX): assert(0); /* TODO: Figure out how this works later. */ result = FR_EVAL_FALSE; break; case(GREATER): result = FR_EVAL_FALSE; for(; value; value = value->next) { if(value->data.va_int >= rhs_val) { result = FR_EVAL_TRUE; break; } } break; case(LESS): result = FR_EVAL_FALSE; for(; value; value = value->next) { if(value->data.va_int <= rhs_val) { result = FR_EVAL_TRUE; break; } } break; default: assert(0); } assert(result != FR_UNSET); return result; }