sort attributes alphabetically

This commit is contained in:
Andreas Steffen
2007-08-15 22:58:15 +00:00
parent cd15679122
commit 6a85215809
+85 -2
View File
@@ -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 **)&current_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: