aboutsummaryrefslogtreecommitdiffstats
path: root/lib/buffer.c
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2021-08-05 16:45:07 +0200
committerKarel Zak <kzak@redhat.com>2021-08-05 16:45:07 +0200
commitf55be401884d651350f15881cb5a9b8a8f120b24 (patch)
tree19b8d5446ef548b80e1d54bb80851212cefc42fa /lib/buffer.c
parentf60dc888489a0b8dcb24fe64659d3b7e8ebc778f (diff)
downloadutil-linux-f55be401884d651350f15881cb5a9b8a8f120b24.tar.gz
lib/buffer: add possibility to save position in the buffer
This is necessary to use lib/buffer.c in libsmart cols. Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'lib/buffer.c')
-rw-r--r--lib/buffer.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/buffer.c b/lib/buffer.c
index 80374e5a89..3c112dd9de 100644
--- a/lib/buffer.c
+++ b/lib/buffer.c
@@ -11,6 +11,7 @@ void ul_buffer_reset_data(struct ul_buffer *buf)
if (buf->begin)
buf->begin[0] = '\0';
buf->end = buf->begin;
+ memset(buf->ptrs, 0, buf->nptrs * sizeof(char *));
}
void ul_buffer_free_data(struct ul_buffer *buf)
@@ -21,6 +22,10 @@ void ul_buffer_free_data(struct ul_buffer *buf)
buf->begin = NULL;
buf->end = NULL;
buf->sz = 0;
+
+ free(buf->ptrs);
+ buf->ptrs = NULL;
+ buf->nptrs = 0;
}
void ul_buffer_set_chunksize(struct ul_buffer *buf, size_t sz)
@@ -33,6 +38,39 @@ int ul_buffer_is_empty(struct ul_buffer *buf)
return buf->begin == buf->end;
}
+int ul_buffer_save_pointer(struct ul_buffer *buf, unsigned short ptr_idx)
+{
+ if (ptr_idx >= buf->nptrs) {
+ char **tmp = realloc(buf->ptrs, (ptr_idx + 1) * sizeof(char *));
+
+ if (!tmp)
+ return -EINVAL;
+ buf->ptrs = tmp;
+ buf->nptrs = ptr_idx + 1;
+ }
+
+ buf->ptrs[ptr_idx] = buf->end;
+ return 0;
+}
+
+
+char *ul_buffer_get_pointer(struct ul_buffer *buf, unsigned short ptr_idx)
+{
+ if (ptr_idx < buf->nptrs)
+ return buf->ptrs[ptr_idx];
+ return NULL;
+}
+
+size_t ul_buffer_get_pointer_length(struct ul_buffer *buf, unsigned short ptr_idx)
+{
+ char *ptr = ul_buffer_get_pointer(buf, ptr_idx);
+
+ if (ptr)
+ return ptr - buf->begin;
+ return 0;
+}
+
+
void ul_buffer_refer_string(struct ul_buffer *buf, char *str)
{
if (buf->sz)
@@ -134,6 +172,12 @@ size_t ul_buffer_get_bufsiz(struct ul_buffer *buf)
#ifdef TEST_PROGRAM_BUFFER
+
+enum {
+ PTR_AAA = 0,
+ PTR_BBB,
+};
+
int main(void)
{
struct ul_buffer buf = UL_INIT_BUFFER;
@@ -145,19 +189,28 @@ int main(void)
ul_buffer_append_string(&buf, "AAA");
ul_buffer_append_data(&buf, "=", 1);
ul_buffer_append_string(&buf, "aaa");
+ ul_buffer_save_pointer(&buf, PTR_AAA);
+
ul_buffer_append_data(&buf, ",", 1);
ul_buffer_append_string(&buf, "BBB");
ul_buffer_append_string(&buf, "=");
ul_buffer_append_string(&buf, "bbb");
+ ul_buffer_save_pointer(&buf, PTR_BBB);
str = ul_buffer_get_data(&buf, &sz);
printf("data [%zu] '%s'\n", sz, str);
+ printf(" pointer data len: AAA=%zu, BBB=%zu\n",
+ ul_buffer_get_pointer_length(&buf, PTR_AAA),
+ ul_buffer_get_pointer_length(&buf, PTR_BBB));
+
ul_buffer_reset_data(&buf);
ul_buffer_append_string(&buf, "This is really long string to test the buffer function.");
+ ul_buffer_save_pointer(&buf, PTR_AAA);
ul_buffer_append_string(&buf, " YES!");
str = ul_buffer_get_data(&buf, &sz);
printf("data [%zu] '%s'\n", sz, str);
+ printf(" pointer data len: AAA=%zu\n", ul_buffer_get_pointer_length(&buf, PTR_AAA));
ul_buffer_free_data(&buf);
str = strdup("foo");