Browse Source

faux.vec: Implementation of faux_vec_t

Serj Kalichev 3 years ago
parent
commit
5c04cc3ff5
3 changed files with 126 additions and 151 deletions
  1. 1 3
      faux/vec.h
  2. 1 0
      faux/vec/private.h
  3. 124 148
      faux/vec/vec.c

+ 1 - 3
faux/vec.h

@@ -11,9 +11,7 @@
 
 typedef struct faux_vec_s faux_vec_t;
 
-//typedef int (*faux_list_cmp_fn)(const void *new_item, const void *list_item);
-//typedef int (*faux_list_kcmp_fn)(const void *key, const void *list_item);
-//typedef void (*faux_list_free_fn)(void *list_item);
+typedef int (*faux_vec_kcmp_fn)(const void *key, const void *item);
 
 C_DECL_BEGIN
 

+ 1 - 0
faux/vec/private.h

@@ -4,4 +4,5 @@ struct faux_vec_s {
 	void *data;
 	size_t len;
 	size_t item_size;
+	faux_vec_kcmp_fn kcmpFn; // Function to compare key and vector's item
 };

+ 124 - 148
faux/vec/vec.c

@@ -1,5 +1,5 @@
 /** @file vec.c
- *
+ * Implementation of variable length vector of arbitrary structures.
  */
 
 
@@ -10,195 +10,171 @@
 #include <stdio.h>
 
 #include "private.h"
-#include "faux/str.h"
 
-#if 0
-/*--------------------------------------------------------- */
-static void lub_argv_init(lub_argv_t * this, const char *line, size_t off)
-{
-	size_t len = 0;
-	const char *word = NULL;
-	lub_arg_t *arg = NULL;
-	bool_t quoted = BOOL_FALSE;
-	bool_t alt_quoted = BOOL_FALSE;
-	const char *str = line + off; // Start on specified offset
-	const char *offset = NULL;
-
-	this->argv = NULL;
-	this->argc = 0;
-	if (!line)
-		return;
-	/* first of all count the words in the line */
-	this->argc = lub_string_wordcount(line);
-	if (0 == this->argc)
-		return;
-	/* allocate space to hold the vector */
-	arg = this->argv = malloc(sizeof(lub_arg_t) * this->argc);
-	assert(arg);
-
-	/* then fill out the array with the words */
-	for (word = lub_string_nextword(str, &len, &offset, &quoted, NULL, &alt_quoted);
-		word && (*word != '\0');
-		word = lub_string_nextword(str, &len, &offset, &quoted, NULL, &alt_quoted)) {
-		if (alt_quoted)
-			(*arg).arg = lub_string_dupn(word, len);
-		else
-			(*arg).arg = lub_string_ndecode(word, len);
-		(*arg).offset = offset - line;
-		(*arg).quoted = quoted;
-		str = offset;
-		arg++;
-	}
-}
 
-/*--------------------------------------------------------- */
-lub_argv_t *lub_argv_new(const char *line, size_t offset)
+faux_vec_t *faux_vec_new(size_t item_size, faux_vec_kcmp_fn matchFn)
 {
-	lub_argv_t *this;
+	faux_vec_t *faux_vec = NULL;
 
-	this = malloc(sizeof(lub_argv_t));
-	if (this)
-		lub_argv_init(this, line, offset);
+	faux_vec = faux_zmalloc(sizeof(*faux_vec));
+	assert(faux_vec);
+	if (!faux_vec)
+		return NULL;
+
+	// Init
+	faux_vec->data = NULL;
+	faux_vec->item_size = item_size;
+	faux_vec->len = 0;
+	faux_vec->kcmpFn = matchFn;
 
-	return this;
+	return faux_vec;
 }
 
-/*--------------------------------------------------------- */
-void lub_argv_add(lub_argv_t * this, const char *text)
-{
-	lub_arg_t * arg;
 
-	if (!text)
+void faux_vec_free(faux_vec_t *faux_vec)
+{
+	if (!faux_vec)
 		return;
-
-	/* allocate space to hold the vector */
-	arg = realloc(this->argv, sizeof(lub_arg_t) * (this->argc + 1));
-	assert(arg);
-	this->argv = arg;
-	(this->argv[this->argc++]).arg = strdup(text);
+	faux_free(faux_vec->data);
+	faux_free(faux_vec);
 }
 
-/*--------------------------------------------------------- */
-static void lub_argv_fini(lub_argv_t * this)
+
+size_t faux_vec_len(const faux_vec_t *faux_vec)
 {
-	unsigned i;
+	assert(faux_vec);
+	if (!faux_vec)
+		return 0;
 
-	for (i = 0; i < this->argc; i++)
-		free(this->argv[i].arg);
-	free(this->argv);
-	this->argv = NULL;
+	return faux_vec->len;
 }
 
-/*--------------------------------------------------------- */
-void lub_argv_delete(lub_argv_t * this)
-{
-	lub_argv_fini(this);
-	free(this);
-}
 
-/*--------------------------------------------------------- */
-char *lub_argv__get_line(const lub_argv_t * this)
+size_t faux_vec_item_size(const faux_vec_t *faux_vec)
 {
-	int space = 0;
-	const char *p;
-	unsigned i;
-	char *line = NULL;
-
-	for (i = 0; i < this->argc; i++) {
-		if (i != 0)
-			lub_string_cat(&line, " ");
-		space = 0;
-		/* Search for spaces */
-		for (p = this->argv[i].arg; *p; p++) {
-			if (isspace(*p)) {
-				space = 1;
-				break;
-			}
-		}
-		if (space)
-			lub_string_cat(&line, "\"");
-		lub_string_cat(&line, this->argv[i].arg);
-		if (space)
-			lub_string_cat(&line, "\"");
-	}
+	assert(faux_vec);
+	if (!faux_vec)
+		return 0;
 
-	return line;
+	return faux_vec->item_size;
 }
 
-/*--------------------------------------------------------- */
-char **lub_argv__get_argv(const lub_argv_t * this, const char *argv0)
-{
-	char **result = NULL;
-	unsigned i;
-	unsigned a = 0;
-
-	if (argv0)
-		a = 1;
 
-	result = malloc(sizeof(char *) * (this->argc + 1 + a));
+void *faux_vec_item(const faux_vec_t *faux_vec, unsigned int index)
+{
+	assert(faux_vec);
+	if (!faux_vec)
+		return NULL;
 
-	if (argv0)
-		result[0] = strdup(argv0);
-	for (i = 0; i < this->argc; i++)
-		result[i + a] = strdup(this->argv[i].arg);
-	result[i + a] = NULL;
+	if ((index + 1) > faux_vec_len(faux_vec))
+		return NULL;
 
-	return result;
+	return (char *)faux_vec->data + index * faux_vec_item_size(faux_vec);
 }
 
-/*--------------------------------------------------------- */
-void lub_argv__free_argv(char **argv)
-{
-	unsigned i;
 
-	if (!argv)
-		return;
+void *faux_vec_data(const faux_vec_t *faux_vec)
+{
+	assert(faux_vec);
+	if (!faux_vec)
+		return NULL;
 
-	for (i = 0; argv[i]; i++)
-		free(argv[i]);
-	free(argv);
+	return faux_vec->data;
 }
 
-/*--------------------------------------------------------- */
-const char *lub_argv__get_arg(const lub_argv_t *this, unsigned int index)
+
+void *faux_vec_add(faux_vec_t *faux_vec)
 {
-	const char *result = NULL;
+	void *new_vector = NULL;
+	size_t new_data_len = 0;
 
-	if (!this)
+	assert(faux_vec);
+	if (!faux_vec)
 		return NULL;
-	if (this->argc > index)
-		result = this->argv[index].arg;
 
-	return result;
-}
+	// Allocate space to hold new vector
+	new_data_len = (faux_vec_len(faux_vec) + 1) * faux_vec_item_size(faux_vec);
+	new_vector = realloc(faux_vec->data, new_data_len);
+	assert(new_vector);
+	if (!new_vector)
+		return NULL;
+	faux_vec->len++;
+	faux_vec->data = new_vector;
 
-/*--------------------------------------------------------- */
-unsigned lub_argv__get_count(const lub_argv_t * this)
-{
-	return this->argc;
+	// Return newly created item (it's last one)
+	return faux_vec_item(faux_vec, faux_vec_len(faux_vec) - 1);
 }
 
-/*--------------------------------------------------------- */
-size_t lub_argv__get_offset(const lub_argv_t * this, unsigned index)
+
+ssize_t faux_vec_del(faux_vec_t *faux_vec, unsigned int index)
 {
-	size_t result = 0;
+	void *new_vector = NULL;
+	size_t new_data_len = 0;
+
+	assert(faux_vec);
+	if (!faux_vec)
+		return -1;
+
+	if ((index + 1) > faux_vec_len(faux_vec))
+		return -1;
+
+	// Move following items to fill the space of deleted item
+	if (index != (faux_vec_len(faux_vec) - 1)) { // Is it last item?
+		void *item_to_del = faux_vec_item(faux_vec, index);
+		void *next_item = faux_vec_item(faux_vec, index + 1);
+		unsigned int items_to_move =
+			faux_vec_len(faux_vec) - (index + 1);
+		memmove(item_to_del, next_item,
+			items_to_move * faux_vec_item_size(faux_vec));
+	}
 
-	if (this->argc > index)
-		result = this->argv[index].offset;
+	// Re-allocate space to hold new vector
+	faux_vec->len--;
+	new_data_len = faux_vec_len(faux_vec) * faux_vec_item_size(faux_vec);
+	new_vector = realloc(faux_vec->data, new_data_len);
+	assert(new_vector);
+	if (!new_vector)
+		return -1;
+	faux_vec->data = new_vector;
 
-	return result;
+	return faux_vec_len(faux_vec);
 }
 
-/*--------------------------------------------------------- */
-bool_t lub_argv__get_quoted(const lub_argv_t * this, unsigned index)
-{
-	bool_t result = BOOL_FALSE;
 
-	if (this->argc > index)
-		result = this->argv[index].quoted;
+int faux_vec_find_fn(const faux_vec_t *faux_vec, faux_vec_kcmp_fn matchFn,
+	const void *userkey, unsigned int start_index)
+{
+	unsigned int i = 0;
+
+	assert(faux_vec);
+	if (!faux_vec)
+		return -1;
+	assert(userkey);
+	if (!userkey)
+		return -1;
+	assert(matchFn);
+	if (!matchFn)
+		return -1;
+
+	for (i = start_index; i < faux_vec_len(faux_vec); i++) {
+		if (matchFn(userkey, faux_vec_item(faux_vec, i)) == 0)
+			return i;
+	}
 
-	return result;
+	return -1;
 }
 
-/*--------------------------------------------------------- */
-#endif
+
+int faux_vec_find(const faux_vec_t *faux_vec, const void *userkey,
+	unsigned int start_index)
+{
+	assert(faux_vec);
+	if (!faux_vec)
+		return -1;
+	assert(faux_vec->kcmpFn);
+	if (!faux_vec->kcmpFn)
+		return -1;
+
+	return faux_vec_find_fn(faux_vec, faux_vec->kcmpFn,
+		userkey, start_index);
+}