summaryrefslogtreecommitdiffstats
path: root/src/utils
diff options
context:
space:
mode:
authorNicolas Pitre <nico@fluxnic.net>2021-03-19 17:22:53 -0400
committerNicolas Pitre <nico@fluxnic.net>2021-03-20 15:54:32 -0400
commitdb35f3bfb7cc256f7e2fcad27bb658370091128f (patch)
tree132374ef04b504e039e265a6339ff0761dd8f5c2 /src/utils
parent73d945f9f13d1a5a15590ace7f2740f16c2ae232 (diff)
clean up and optimize the dictionary code
This code was way too complicated and suboptimal.
Diffstat (limited to 'src/utils')
-rwxr-xr-xsrc/utils/dictionary.c199
-rwxr-xr-xsrc/utils/dictionary.h4
2 files changed, 58 insertions, 145 deletions
diff --git a/src/utils/dictionary.c b/src/utils/dictionary.c
index 68ba04b..10ef25a 100755
--- a/src/utils/dictionary.c
+++ b/src/utils/dictionary.c
@@ -44,9 +44,7 @@
#include <stdlib.h>
#include <string.h>
-#include "string.h"
#include "dictionary.h"
-#include "../macros.h"
/**
* \brief TODO Document create_dictionary()
@@ -54,8 +52,8 @@
* \return dictionary
*/
- struct dictionary * create_dictionary() {
- struct dictionary * d = (struct dictionary *) malloc (sizeof (struct dictionary));
+struct dictionary * create_dictionary() {
+ struct dictionary * d = malloc(sizeof(struct dictionary));
d->len = 0;
d->list = NULL;
@@ -73,63 +71,31 @@
*/
void put(struct dictionary * d, char * k, char * v) {
- if ( ! strlen (k) || ! strlen(v) ) return;
- //if ( ! strlen (k) ) return;
-
- struct nlist * nl;
- char * cl;
-
- // Insert the first element
- if (d->list == NULL) {
- nl = (struct nlist *) malloc(sizeof(struct nlist));
- nl->next = NULL;
- d->list = nl;
-
- d->len++;
- char * key = (char *) malloc(sizeof(char) * strlen(k)+1);
- key[0] = '\0';
- strcpy(key, k);
- nl->key = key;
-
- // Duplicated keys are not allowed.
- // If an existent key is inserted, the value is overwritten.
- } else if ( (cl = get(d, k)) != NULL && cl[0] != '\0' ) {
- nl = get_nl(d, k);
- free(nl->val);
-
- // If the key doesn't exists, Create it.
- } else {
- nl = (struct nlist *) malloc(sizeof(struct nlist));
-
- // Insert at the beginning
- if (strcmp(k, d->list->key) < 0) {
- nl->next = d->list;
- d->list = nl;
- // Traverse and insert in the middle or at the end
- } else {
- struct nlist * nant = d->list;
- struct nlist * nact = d->list->next;
- while ( nact != NULL && strcmp(k, nact->key) > 0 ) {
- nant = nact;
- nact = nact->next;
- }
- nl->next = nact;
- nant->next = nl;
- }
-
- d->len++;
- char * key = (char *) malloc(sizeof(char) * strlen(k)+1);
- key[0] = '\0';
- strcpy(key, k);
- nl->key = key;
+ struct nlist *nl, **p_nl;
+
+ if (*k == 0) return;
+
+ // locate the key position
+ for (p_nl = &d->list; *p_nl; p_nl = &(*p_nl)->next) {
+ nl = *p_nl;
+ int cmp = strcmp(k, nl->key);
+ if (cmp > 0) continue;
+ if (cmp < 0) break;
+
+ // Duplicated keys are not allowed.
+ // If an existing key is inserted, the value is overwritten.
+ free(nl->val);
+ nl->val = strdup(v);
+ return;
}
- // Always save the value
- char * val = (char *) malloc(sizeof(char) * strlen(v)+1);
- val[0] = '\0';
- strcpy(val, v);
- nl->val = val;
- return;
+ // The key doesn't exists, Create it.
+ nl = malloc(sizeof(struct nlist));
+ nl->key = strdup(k);
+ nl->val = strdup(v);
+ nl->next = *p_nl;
+ *p_nl = nl;
+ d->len++;
}
/**
@@ -141,7 +107,6 @@ void put(struct dictionary * d, char * k, char * v) {
*/
void destroy_dictionary(struct dictionary * d) {
- //if (d == NULL) return;
struct nlist * nl;
struct nlist * n_next;
@@ -159,61 +124,20 @@ void destroy_dictionary(struct dictionary * d) {
}
/**
- * \brief TODO Document get_nl()
- *
- * \param[in] d
- * \param[in] key
- *
- * \return nl
- */
-
-struct nlist * get_nl(struct dictionary * d, char * key) {
- int i=0;
- struct nlist * nl = d->list;
- while ( i++ < d->len && strcmp(key, nl->key) >= 0 ) {
- if (strcmp(nl->key, key) == 0)
- return nl;
- nl = nl->next;
- }
- return nl; // just in case d->list == NULL
-}
-
-/**
- * \brief Get max length of keys in a dictionary
- *
- * \param[in] d
- *
- * \return count
- */
-
-int get_maxkey_length(struct dictionary * d) {
- int i = 0, len, count = 0;
- if (d == NULL || d->list == NULL) return count;
-
- struct nlist * nl = d->list;
- while ( i++ < d->len ) {
- if ((len = strlen(nl->key)) > count) count = len;
- nl = nl->next;
- }
- return count;
-}
-
-/**
- * \brief Get max length of value of dictionary
+ * \brief Get the size in bytes needed to export a dictionary
*
* \param[in] d
*
* \return count
*/
-int get_maxvalue_length(struct dictionary * d) {
- int i = 0, len, count = 0;
- if (d == NULL || d->list == NULL) return count;
+int get_dict_buffer_size(struct dictionary * d) {
+ struct nlist * nl;
+ int count = 0;
- struct nlist * nl = d->list;
- while ( i++ < d->len ) {
- if ((len = strlen(nl->val)) > count) count = len;
- nl = nl->next;
+ for (nl = d->list; nl != NULL; nl = nl->next) {
+ /* <key> + '=' + <val> + '\n' */
+ count += strlen(nl->key) + 1 + strlen(nl->val) + 1;
}
return count;
}
@@ -228,27 +152,24 @@ int get_maxvalue_length(struct dictionary * d) {
*/
char * get(struct dictionary * d, char * key) {
- int i=0;
- if (d == NULL || d->list == NULL) return NULL;
+ struct nlist * nl;
- struct nlist * nl = d->list;
- while ( i++ < d->len ) { // && strcmp(key, nl->key) >= 0 ) {
- if (strcmp(nl->key, key) == 0)
- return nl->val;
- nl = nl->next;
+ for (nl = d->list; nl != NULL; nl = nl->next) {
+ int cmp = strcmp(key, nl->key);
+ if (cmp > 0) continue;
+ if (cmp < 0) break;
+ return nl->val;
}
return NULL;
}
/* Get the key name from a value
char * get_key_name(struct dictionary * d, char * value) {
- int i=0;
- if (d == NULL || d->list == NULL) return NULL;
- struct nlist * nl = d->list;
- while ( i++ < d->len ) {
+ struct nlist * nl;
+
+ for (nl = d->list; nl != NULL; nl = nl->next) {
if (! strcmp(nl->val, value))
return nl->key;
- nl = nl->next;
}
return NULL;
}
@@ -265,31 +186,25 @@ char * get_key_name(struct dictionary * d, char * value) {
* \return dictionary
*/
-void parse_str(struct dictionary * d, char * str, int blank_space) {
- char c = str[0];
+void parse_str(struct dictionary * d, char * str, int no_blanks) {
char key[90];
char value[90];
- key[0] = '\0';
- value[0] = '\0';
+ int i;
- // Create the dictionary
- while (c != '\0') {
- while (c != '=' && c != '\0') {
- add_char(key, c, strlen(key));
- c = *++str;
- }
- if (c == '\0') break;
- c = *++str;
- while (c != '\0') {
- if (blank_space && c == ' ') break;
- add_char(value, c, strlen(value));
- c = *++str;
- }
- if (c != '\0') c = *++str;
-
- put(d, key, value);
+ i = 0;
+ while (*str != 0 && *str != '=' && i < sizeof(key)) {
+ key[i++] = *str++;
+ }
+ if (i >= sizeof(key) || *str++ != '=') return;
+ key[i] = 0;
- key[0] = '\0';
- value[0] = '\0';
+ i = 0;
+ while (*str != 0 && i < sizeof(value) && !(no_blanks && *str == ' ')) {
+ value[i++] = *str++;
}
+ if (i >= sizeof(value)) return;
+ value[i] = 0;
+
+ // Create the dictionary
+ put(d, key, value);
}
diff --git a/src/utils/dictionary.h b/src/utils/dictionary.h
index 47a7f55..af866a3 100755
--- a/src/utils/dictionary.h
+++ b/src/utils/dictionary.h
@@ -58,7 +58,5 @@ void put(struct dictionary * d, char * k, char * v);
void destroy_dictionary(struct dictionary * d);
char * get(struct dictionary * d, char * key);
//char * get_key_name(struct dictionary * d, char * value);
-struct nlist * get_nl(struct dictionary * d, char * key);
void parse_str(struct dictionary * d, char * str, int blank_space);
-int get_maxkey_length(struct dictionary * d);
-int get_maxvalue_length(struct dictionary * d);
+int get_dict_buffer_size(struct dictionary * d);