sort attributes alphabetically
This commit is contained in:
@@ -166,6 +166,18 @@ struct ietfAttr_t {
|
|||||||
*/
|
*/
|
||||||
chunk_t value;
|
chunk_t value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two ietfAttributes
|
||||||
|
*
|
||||||
|
* return -1 if this is earlier in the alphabet than other
|
||||||
|
* return 0 if this equals other
|
||||||
|
* return +1 if this is later in the alphabet than other
|
||||||
|
*
|
||||||
|
* @param this calling object
|
||||||
|
* @param other other object
|
||||||
|
*/
|
||||||
|
int (*compare) (const ietfAttr_t *this ,const ietfAttr_t *other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys the ietfAttr_t object.
|
* Destroys the ietfAttr_t object.
|
||||||
*
|
*
|
||||||
@@ -175,7 +187,66 @@ struct ietfAttr_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists a linked_list of ietfAttr_t objects
|
* Implements ietfAttr_t.compare.
|
||||||
|
*/
|
||||||
|
static int ietfAttr_compare(const ietfAttr_t *this ,const ietfAttr_t *other)
|
||||||
|
{
|
||||||
|
int cmp_len, len, cmp_value;
|
||||||
|
|
||||||
|
/* OID attributes are appended after STRING and OCTETS attributes */
|
||||||
|
if (this->kind != IETF_ATTRIBUTE_OID && other->kind == IETF_ATTRIBUTE_OID)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (this->kind == IETF_ATTRIBUTE_OID && other->kind != IETF_ATTRIBUTE_OID)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmp_len = this->value.len - other->value.len;
|
||||||
|
len = (cmp_len < 0)? this->value.len : other->value.len;
|
||||||
|
cmp_value = memcmp(this->value.ptr, other->value.ptr, len);
|
||||||
|
|
||||||
|
return (cmp_value == 0)? cmp_len : cmp_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an ietfAttr_t object to a sorted linked list
|
||||||
|
*/
|
||||||
|
static void ietfAttr_add(linked_list_t *list, ietfAttr_t *attr)
|
||||||
|
{
|
||||||
|
iterator_t *iterator = list->create_iterator(list, TRUE);
|
||||||
|
ietfAttr_t *current_attr;
|
||||||
|
bool found = FALSE;
|
||||||
|
|
||||||
|
while (iterator->iterate(iterator, (void **)¤t_attr))
|
||||||
|
{
|
||||||
|
int cmp = attr->compare(attr, current_attr);
|
||||||
|
|
||||||
|
if (cmp > 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cmp == 0)
|
||||||
|
{
|
||||||
|
attr->destroy(attr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iterator->insert_before(iterator, attr);
|
||||||
|
}
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iterator->destroy(iterator);
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
list->insert_last(list, attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists a linked list of ietfAttr_t objects
|
||||||
*/
|
*/
|
||||||
static void ietfAttr_list(linked_list_t *list, FILE *out)
|
static void ietfAttr_list(linked_list_t *list, FILE *out)
|
||||||
{
|
{
|
||||||
@@ -201,7 +272,18 @@ static void ietfAttr_list(linked_list_t *list, FILE *out)
|
|||||||
fprintf(out, "%.*s", (int)attr->value.len, attr->value.ptr);
|
fprintf(out, "%.*s", (int)attr->value.len, attr->value.ptr);
|
||||||
break;
|
break;
|
||||||
case IETF_ATTRIBUTE_OID:
|
case IETF_ATTRIBUTE_OID:
|
||||||
|
{
|
||||||
|
int oid = known_oid(attr->value);
|
||||||
|
|
||||||
|
if (oid = OID_UNKNOWN)
|
||||||
|
{
|
||||||
fprintf(out, "0x#B", &attr->value);
|
fprintf(out, "0x#B", &attr->value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(out, "%s", oid_names[oid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -231,6 +313,7 @@ ietfAttr_t *ietfAttr_create(ietfAttribute_t kind, chunk_t value)
|
|||||||
this->value = chunk_clone(value);
|
this->value = chunk_clone(value);
|
||||||
|
|
||||||
/* function */
|
/* function */
|
||||||
|
this->compare = ietfAttr_compare;
|
||||||
this->destroy = ietfAttr_destroy;
|
this->destroy = ietfAttr_destroy;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@@ -481,7 +564,7 @@ static void parse_ietfAttrSyntax(chunk_t blob, int level0, linked_list_t *list)
|
|||||||
{
|
{
|
||||||
ietfAttribute_t kind = (objectID - IETF_ATTR_OCTETS) / 2;
|
ietfAttribute_t kind = (objectID - IETF_ATTR_OCTETS) / 2;
|
||||||
ietfAttr_t *attr = ietfAttr_create(kind, object);
|
ietfAttr_t *attr = ietfAttr_create(kind, object);
|
||||||
list->insert_last(list, (void *)attr);
|
ietfAttr_add(list, attr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user