]> git.ipfire.org Git - location/libloc.git/commitdiff
stringpool: Always add an empty string
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 19 May 2020 16:53:53 +0000 (16:53 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 19 May 2020 16:53:53 +0000 (16:53 +0000)
This will create an empty string at the first byte of the pool
and is helpful for our database metadata (vendor, license, de-
scription) which can be zero and would therefore return the
first string in the pool.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/stringpool.c

index e43c4cb3a7fa84b00c449dc49c261fe895a27294..ac0c1eb7da963667ae13a4bb8af30d1b2a42cedc 100644 (file)
@@ -44,6 +44,67 @@ struct loc_stringpool {
        char* pos;
 };
 
+static off_t loc_stringpool_get_offset(struct loc_stringpool* pool, const char* pos) {
+       if (pos < pool->data)
+               return -EFAULT;
+
+       if (pos > (pool->data + pool->length))
+               return -EFAULT;
+
+       return pos - pool->data;
+}
+
+static char* __loc_stringpool_get(struct loc_stringpool* pool, off_t offset) {
+       if (offset < 0 || offset >= pool->length)
+               return NULL;
+
+       return pool->data + offset;
+}
+
+static int loc_stringpool_grow(struct loc_stringpool* pool, size_t length) {
+       DEBUG(pool->ctx, "Growing string pool to %zu bytes\n", length);
+
+       // Save pos pointer
+       off_t pos = loc_stringpool_get_offset(pool, pool->pos);
+
+       // Reallocate data section
+       pool->data = realloc(pool->data, length);
+       if (!pool->data)
+               return -ENOMEM;
+
+       pool->length = length;
+
+       // Restore pos
+       pool->pos = __loc_stringpool_get(pool, pos);
+
+       return 0;
+}
+
+static off_t loc_stringpool_append(struct loc_stringpool* pool, const char* string) {
+       if (!string || !*string)
+               return -EINVAL;
+
+       DEBUG(pool->ctx, "Appending '%s' to string pool at %p\n", string, pool);
+
+       // Make sure we have enough space
+       int r = loc_stringpool_grow(pool, pool->length + strlen(string) + 1);
+       if (r) {
+               errno = r;
+               return -1;
+       }
+
+       off_t offset = loc_stringpool_get_offset(pool, pool->pos);
+
+       // Copy string byte by byte
+       while (*string)
+               *pool->pos++ = *string++;
+
+       // Terminate the string
+       *pool->pos++ = '\0';
+
+       return offset;
+}
+
 static int __loc_stringpool_new(struct loc_ctx* ctx, struct loc_stringpool** pool, enum loc_stringpool_mode mode) {
        struct loc_stringpool* p = calloc(1, sizeof(*p));
        if (!p)
@@ -61,7 +122,14 @@ static int __loc_stringpool_new(struct loc_ctx* ctx, struct loc_stringpool** poo
 }
 
 LOC_EXPORT int loc_stringpool_new(struct loc_ctx* ctx, struct loc_stringpool** pool) {
-       return __loc_stringpool_new(ctx, pool, STRINGPOOL_DEFAULT);
+       int r = __loc_stringpool_new(ctx, pool, STRINGPOOL_DEFAULT);
+       if (r)
+               return r;
+
+       // Add an empty string to new string pools
+       loc_stringpool_append(*pool, "");
+
+       return r;
 }
 
 static int loc_stringpool_mmap(struct loc_stringpool* pool, FILE* f, size_t length, off_t offset) {
@@ -138,29 +206,12 @@ LOC_EXPORT struct loc_stringpool* loc_stringpool_unref(struct loc_stringpool* po
        return NULL;
 }
 
-static off_t loc_stringpool_get_offset(struct loc_stringpool* pool, const char* pos) {
-       if (pos < pool->data)
-               return -EFAULT;
-
-       if (pos > (pool->data + pool->length))
-               return -EFAULT;
-
-       return pos - pool->data;
-}
-
 static off_t loc_stringpool_get_next_offset(struct loc_stringpool* pool, off_t offset) {
        const char* string = loc_stringpool_get(pool, offset);
 
        return offset + strlen(string) + 1;
 }
 
-static char* __loc_stringpool_get(struct loc_stringpool* pool, off_t offset) {
-       if (offset < 0 || offset >= pool->length)
-               return NULL;
-
-       return pool->data + offset;
-}
-
 LOC_EXPORT const char* loc_stringpool_get(struct loc_stringpool* pool, off_t offset) {
        return __loc_stringpool_get(pool, offset);
 }
@@ -189,50 +240,6 @@ static off_t loc_stringpool_find(struct loc_stringpool* pool, const char* s) {
        return -ENOENT;
 }
 
-static int loc_stringpool_grow(struct loc_stringpool* pool, size_t length) {
-       DEBUG(pool->ctx, "Growing string pool to %zu bytes\n", length);
-
-       // Save pos pointer
-       off_t pos = loc_stringpool_get_offset(pool, pool->pos);
-
-       // Reallocate data section
-       pool->data = realloc(pool->data, length);
-       if (!pool->data)
-               return -ENOMEM;
-
-       pool->length = length;
-
-       // Restore pos
-       pool->pos = __loc_stringpool_get(pool, pos);
-
-       return 0;
-}
-
-static off_t loc_stringpool_append(struct loc_stringpool* pool, const char* string) {
-       if (!string || !*string)
-               return -EINVAL;
-
-       DEBUG(pool->ctx, "Appending '%s' to string pool at %p\n", string, pool);
-
-       // Make sure we have enough space
-       int r = loc_stringpool_grow(pool, pool->length + strlen(string) + 1);
-       if (r) {
-               errno = r;
-               return -1;
-       }
-
-       off_t offset = loc_stringpool_get_offset(pool, pool->pos);
-
-       // Copy string byte by byte
-       while (*string)
-               *pool->pos++ = *string++;
-
-       // Terminate the string
-       *pool->pos++ = '\0';
-
-       return offset;
-}
-
 LOC_EXPORT off_t loc_stringpool_add(struct loc_stringpool* pool, const char* string) {
        off_t offset = loc_stringpool_find(pool, string);
        if (offset >= 0) {