Blender V5.0
BLI_dynstr.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9
10#include <cstdio>
11#include <cstdlib> /* malloc */
12#include <cstring>
13
14#include "BLI_dynstr.h"
15#include "BLI_memarena.h"
16#include "BLI_string.h"
17#include "BLI_utildefines.h"
18
19#include "MEM_guardedalloc.h"
20
21/***/
22
23struct DynStrElem {
25
26 char *str;
27};
28
34
35/***/
36
38{
39 return MEM_callocN<DynStr>("DynStr");
40}
41
43{
44 DynStr *ds = MEM_callocN<DynStr>("DynStr");
46
47 return ds;
48}
49
50template<typename T> inline T *dynstr_alloc(DynStr *__restrict ds, size_t num = 1)
51{
52 return ds->memarena ? BLI_memarena_alloc<T>(ds->memarena, num) :
53 static_cast<T *>(malloc(num * sizeof(T)));
54}
55
56void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr)
57{
59 int cstrlen = strlen(cstr);
60
61 dse->str = dynstr_alloc<char>(ds, cstrlen + 1);
62 memcpy(dse->str, cstr, cstrlen + 1);
63 dse->next = nullptr;
64
65 if (!ds->last) {
66 ds->last = ds->elems = dse;
67 }
68 else {
69 ds->last = ds->last->next = dse;
70 }
71
72 ds->curlen += cstrlen;
73}
74
75void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len)
76{
78 int cstrlen = BLI_strnlen(cstr, len);
79
80 dse->str = dynstr_alloc<char>(ds, cstrlen + 1);
81 memcpy(dse->str, cstr, cstrlen);
82 dse->str[cstrlen] = '\0';
83 dse->next = nullptr;
84
85 if (!ds->last) {
86 ds->last = ds->elems = dse;
87 }
88 else {
89 ds->last = ds->last->next = dse;
90 }
91
92 ds->curlen += cstrlen;
93}
94
95void BLI_dynstr_vappendf(DynStr *__restrict ds, const char *__restrict format, va_list args)
96{
97 char *str, fixed_buf[256];
98 size_t str_len;
99 str = BLI_vsprintfN_with_buffer(fixed_buf, sizeof(fixed_buf), &str_len, format, args);
101 if (str != fixed_buf) {
102 MEM_freeN(str);
103 }
104}
105
106void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format, ...)
107{
108 va_list args;
109 char *str, fixed_buf[256];
110 size_t str_len;
111 va_start(args, format);
112 str = BLI_vsprintfN_with_buffer(fixed_buf, sizeof(fixed_buf), &str_len, format, args);
113 va_end(args);
114 if (LIKELY(str)) {
116 if (str != fixed_buf) {
117 MEM_freeN(str);
118 }
119 }
120}
121
123{
124 return ds->curlen;
125}
126
127void BLI_dynstr_get_cstring_ex(const DynStr *__restrict ds, char *__restrict rets)
128{
129 char *s;
130 const DynStrElem *dse;
131
132 for (s = rets, dse = ds->elems; dse; dse = dse->next) {
133 int slen = strlen(dse->str);
134
135 memcpy(s, dse->str, slen);
136
137 s += slen;
138 }
139 BLI_assert((s - rets) == ds->curlen);
140 rets[ds->curlen] = '\0';
141}
142
144{
145 char *rets = MEM_malloc_arrayN<char>(size_t(ds->curlen) + 1, "dynstr_cstring");
147 return rets;
148}
149
151{
152 if (ds->memarena) {
154 }
155 else {
156 for (DynStrElem *dse_next, *dse = ds->elems; dse; dse = dse_next) {
157 dse_next = dse->next;
158
159 free(dse->str);
160 free(dse);
161 }
162 }
163
164 ds->elems = ds->last = nullptr;
165 ds->curlen = 0;
166}
167
169{
170 if (ds->memarena) {
172 }
173 else {
175 }
176
177 MEM_freeN(ds);
178}
#define BLI_assert(a)
Definition BLI_assert.h:46
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...)
DynStr * BLI_dynstr_new_memarena()
Definition BLI_dynstr.cc:42
char * BLI_dynstr_get_cstring(const DynStr *ds)
DynStr * BLI_dynstr_new()
Definition BLI_dynstr.cc:37
void BLI_dynstr_free(DynStr *ds)
void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len)
Definition BLI_dynstr.cc:75
void BLI_dynstr_get_cstring_ex(const DynStr *__restrict ds, char *__restrict rets)
void BLI_dynstr_clear(DynStr *ds)
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr)
Definition BLI_dynstr.cc:56
T * dynstr_alloc(DynStr *__restrict ds, size_t num=1)
Definition BLI_dynstr.cc:50
void BLI_dynstr_vappendf(DynStr *__restrict ds, const char *__restrict format, va_list args)
Definition BLI_dynstr.cc:95
int BLI_dynstr_get_len(const DynStr *ds)
A dynamically sized string ADT.
void BLI_kdtree_nd_ free(KDTree *tree)
#define BLI_MEMARENA_STD_BUFSIZE
MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
void BLI_memarena_free(MemArena *ma) ATTR_NONNULL(1)
void * BLI_memarena_alloc(MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1)
ATTR_WARN_UNUSED_RESULT const size_t num
char * BLI_vsprintfN_with_buffer(char *fixed_buf, size_t fixed_buf_size, size_t *result_len, const char *__restrict format, va_list args) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
int char char int int int int size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition string.cc:913
#define LIKELY(x)
Read Guarded memory(de)allocation.
#define str(s)
format
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define T
DynStrElem * next
Definition BLI_dynstr.cc:24
char * str
Definition BLI_dynstr.cc:26
MemArena * memarena
Definition BLI_dynstr.cc:32
DynStrElem * last
Definition BLI_dynstr.cc:30
int curlen
Definition BLI_dynstr.cc:31
DynStrElem * elems
Definition BLI_dynstr.cc:30
uint len