summaryrefslogtreecommitdiffstats
path: root/src/collectors/log2journal/log2journal-txt.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/collectors/log2journal/log2journal-txt.h')
-rw-r--r--src/collectors/log2journal/log2journal-txt.h90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/collectors/log2journal/log2journal-txt.h b/src/collectors/log2journal/log2journal-txt.h
new file mode 100644
index 000000000..f68b85a3d
--- /dev/null
+++ b/src/collectors/log2journal/log2journal-txt.h
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef NETDATA_LOG2JOURNAL_TXT_H
+#define NETDATA_LOG2JOURNAL_TXT_H
+
+#include "log2journal.h"
+
+// ----------------------------------------------------------------------------
+// A dynamically sized, reusable text buffer,
+// allowing us to be fast (no allocations during iterations) while having the
+// smallest possible allocations.
+
+typedef struct txt_l2j {
+ char *txt;
+ uint32_t size;
+ uint32_t len;
+} TXT_L2J;
+
+static inline void txt_l2j_cleanup(TXT_L2J *t) {
+ if(!t)
+ return;
+
+ if(t->txt)
+ freez(t->txt);
+
+ t->txt = NULL;
+ t->size = 0;
+ t->len = 0;
+}
+
+#define TXT_L2J_ALLOC_ALIGN 1024
+
+static inline size_t txt_l2j_compute_new_size(size_t old_size, size_t required_size) {
+ size_t size = (required_size % TXT_L2J_ALLOC_ALIGN == 0) ? required_size : required_size + TXT_L2J_ALLOC_ALIGN;
+ size = (size / TXT_L2J_ALLOC_ALIGN) * TXT_L2J_ALLOC_ALIGN;
+
+ if(size < old_size * 2)
+ size = old_size * 2;
+
+ return size;
+}
+
+static inline void txt_l2j_resize(TXT_L2J *dst, size_t required_size, bool keep) {
+ if(required_size <= dst->size)
+ return;
+
+ size_t new_size = txt_l2j_compute_new_size(dst->size, required_size);
+
+ if(keep && dst->txt)
+ dst->txt = reallocz(dst->txt, new_size);
+ else {
+ txt_l2j_cleanup(dst);
+ dst->txt = mallocz(new_size);
+ dst->len = 0;
+ }
+
+ dst->size = new_size;
+}
+
+static inline void txt_l2j_set(TXT_L2J *dst, const char *s, int32_t len) {
+ if(!s || !*s || len == 0) {
+ s = "";
+ len = 0;
+ }
+
+ if(len == -1)
+ len = (int32_t)strlen(s);
+
+ txt_l2j_resize(dst, len + 1, false);
+ memcpy(dst->txt, s, len);
+ dst->txt[len] = '\0';
+ dst->len = len;
+}
+
+static inline void txt_l2j_append(TXT_L2J *dst, const char *s, int32_t len) {
+ if(!dst->txt || !dst->len)
+ txt_l2j_set(dst, s, len);
+
+ else {
+ if(len == -1)
+ len = (int32_t)strlen(s);
+
+ txt_l2j_resize(dst, dst->len + len + 1, true);
+ memcpy(&dst->txt[dst->len], s, len);
+ dst->len += len;
+ dst->txt[dst->len] = '\0';
+ }
+}
+
+#endif //NETDATA_LOG2JOURNAL_TXT_H