diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2014-06-04 17:21:15 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2014-06-04 17:21:15 +0200 |
commit | cf99716e175b6380bde113f415477948d70bdbda (patch) | |
tree | 94448037c0c3a16f77cffc4c5564dc3938be6e5b | |
parent | e7272b364e63548be8b92a6ae6236393a77d3cba (diff) | |
download | libtasn1-cf99716e175b6380bde113f415477948d70bdbda.tar.gz libtasn1-cf99716e175b6380bde113f415477948d70bdbda.tar.bz2 libtasn1-cf99716e175b6380bde113f415477948d70bdbda.zip |
Optimized _asn1_append_sequence_set() by caching the tail of the element to append on.
-rw-r--r-- | lib/decoding.c | 10 | ||||
-rw-r--r-- | lib/element.c | 18 | ||||
-rw-r--r-- | lib/element.h | 2 |
3 files changed, 22 insertions, 8 deletions
diff --git a/lib/decoding.c b/lib/decoding.c index c79a5c4..199580c 100644 --- a/lib/decoding.c +++ b/lib/decoding.c @@ -899,6 +899,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, asn1_node node, p, p2, p3; char temp[128]; int counter, len2, len3, len4, move, ris, tlen; + asn1_node ptail = NULL; unsigned char class; unsigned long tag; int indefinite, result, total_len = ider_len; @@ -1290,7 +1291,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, { /* indefinite length method */ if (!HAVE_TWO(ider_len) || ((der[counter]) || der[counter + 1])) { - _asn1_append_sequence_set (p); + _asn1_append_sequence_set (p, &ptail); p = p->down; while (p->right) p = p->right; @@ -1299,6 +1300,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, } p->tmp_ival = 0; + ptail = NULL; /* finished decoding this structure */ DECR_LEN(ider_len, 2); counter += 2; } @@ -1306,7 +1308,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, { /* definite length method */ if (len2 > counter) { - _asn1_append_sequence_set (p); + _asn1_append_sequence_set (p, &ptail); p = p->down; while (p->right) p = p->right; @@ -1315,6 +1317,8 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, } p->tmp_ival = 0; + ptail = NULL; /* finished decoding this structure */ + if (len2 != counter) { result = ASN1_DER_ERROR; @@ -1351,7 +1355,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, || (type_field (p2->type) == ASN1_ETYPE_SIZE)) p2 = p2->right; if (p2->right == NULL) - _asn1_append_sequence_set (p); + _asn1_append_sequence_set (p, &ptail); p = p2; } } diff --git a/lib/element.c b/lib/element.c index b45c3ec..66bd8fa 100644 --- a/lib/element.c +++ b/lib/element.c @@ -130,7 +130,7 @@ _asn1_convert_integer (const unsigned char *value, unsigned char *value_out, int -_asn1_append_sequence_set (asn1_node node) +_asn1_append_sequence_set (asn1_node node, asn1_node *ptail) { asn1_node p, p2; char temp[LTOSTR_MAX_SIZE]; @@ -144,9 +144,19 @@ _asn1_append_sequence_set (asn1_node node) || (type_field (p->type) == ASN1_ETYPE_SIZE)) p = p->right; p2 = _asn1_copy_structure3 (p); - while (p->right) - p = p->right; + + if (ptail == NULL || *ptail == NULL || (*ptail)->up != p->up) + while (p->right) { + p = p->right; + } + else + { + p = *ptail; + } + _asn1_set_right (p, p2); + if (ptail) + *ptail = p2; if (p->name[0] == 0) _asn1_str_cpy (temp, sizeof (temp), "?1"); @@ -608,7 +618,7 @@ asn1_write_value (asn1_node node_root, const char *name, case ASN1_ETYPE_SET_OF: if (_asn1_strcmp (value, "NEW")) return ASN1_VALUE_NOT_VALID; - _asn1_append_sequence_set (node); + _asn1_append_sequence_set (node, NULL); break; default: return ASN1_ELEMENT_NOT_FOUND; diff --git a/lib/element.h b/lib/element.h index fdecafb..65a4845 100644 --- a/lib/element.h +++ b/lib/element.h @@ -23,7 +23,7 @@ #define _ELEMENT_H -int _asn1_append_sequence_set (asn1_node node); +int _asn1_append_sequence_set (asn1_node node, asn1_node *pcached); int _asn1_convert_integer (const unsigned char *value, unsigned char *value_out, |