]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - lib/buffer.c
2 * No copyright is claimed. This code is in the public domain; do with
5 * Written by Karel Zak <kzak@redhat.com>
11 void ul_buffer_reset_data(struct ul_buffer
*buf
)
14 memset(buf
->begin
, 0, buf
->sz
);
15 buf
->end
= buf
->begin
;
17 if (buf
->ptrs
&& buf
->nptrs
)
18 memset(buf
->ptrs
, 0, buf
->nptrs
* sizeof(char *));
21 void ul_buffer_free_data(struct ul_buffer
*buf
)
39 void ul_buffer_set_chunksize(struct ul_buffer
*buf
, size_t sz
)
44 int ul_buffer_is_empty(struct ul_buffer
*buf
)
46 return buf
->begin
== buf
->end
;
49 int ul_buffer_save_pointer(struct ul_buffer
*buf
, unsigned short ptr_idx
)
51 if (ptr_idx
>= buf
->nptrs
) {
52 char **tmp
= reallocarray(buf
->ptrs
, ptr_idx
+ 1, sizeof(char *));
57 buf
->nptrs
= ptr_idx
+ 1;
60 buf
->ptrs
[ptr_idx
] = buf
->end
;
65 char *ul_buffer_get_pointer(struct ul_buffer
*buf
, unsigned short ptr_idx
)
67 if (ptr_idx
< buf
->nptrs
)
68 return buf
->ptrs
[ptr_idx
];
72 /* returns length from begin to the pointer */
73 size_t ul_buffer_get_pointer_length(struct ul_buffer
*buf
, unsigned short ptr_idx
)
75 char *ptr
= ul_buffer_get_pointer(buf
, ptr_idx
);
77 if (ptr
&& ptr
> buf
->begin
)
78 return ptr
- buf
->begin
;
82 /* returns width of data in safe encoding (from the begin to the pointer) */
83 size_t ul_buffer_get_safe_pointer_width(struct ul_buffer
*buf
, unsigned short ptr_idx
)
85 size_t len
= ul_buffer_get_pointer_length(buf
, ptr_idx
);
90 return mbs_safe_nwidth(buf
->begin
, len
, NULL
);
93 void ul_buffer_refer_string(struct ul_buffer
*buf
, char *str
)
96 ul_buffer_free_data(buf
);
98 buf
->sz
= str
? strlen(str
) : 0;
99 buf
->end
= buf
->begin
? buf
->begin
+ buf
->sz
: buf
->begin
;
102 int ul_buffer_alloc_data(struct ul_buffer
*buf
, size_t sz
)
112 if (buf
->end
&& buf
->begin
)
113 len
= buf
->end
- buf
->begin
;
116 sz
= ((sz
+ buf
->chunksize
) / buf
->chunksize
) * buf
->chunksize
+ 1;
118 tmp
= realloc(buf
->begin
, sz
);
123 buf
->end
= buf
->begin
+ len
;
126 memset(buf
->end
, '\0', sz
- len
);
131 int ul_buffer_append_data(struct ul_buffer
*buf
, const char *data
, size_t sz
)
140 if (buf
->begin
&& buf
->end
)
141 maxsz
= buf
->sz
- (buf
->end
- buf
->begin
);
142 if (maxsz
<= sz
+ 1) {
143 int rc
= ul_buffer_alloc_data(buf
, buf
->sz
+ sz
+ 1);
148 return -EINVAL
; /* make static analyzers happy */
150 buf
->end
= mempcpy(buf
->end
, data
, sz
);
151 *buf
->end
= '\0'; /* make sure it's terminated */
155 int ul_buffer_append_string(struct ul_buffer
*buf
, const char *str
)
160 return ul_buffer_append_data(buf
, str
, strlen(str
));
163 int ul_buffer_append_ntimes(struct ul_buffer
*buf
, size_t n
, const char *str
)
166 size_t len
= strlen(str
);
168 for (i
= 0; len
&& i
< n
; i
++) {
169 int rc
= ul_buffer_append_data(buf
, str
, len
);
176 int ul_buffer_set_data(struct ul_buffer
*buf
, const char *data
, size_t sz
)
178 ul_buffer_reset_data(buf
);
179 return ul_buffer_append_data(buf
, data
, sz
);
182 char *ul_buffer_get_data(struct ul_buffer
*buf
, size_t *sz
, size_t *width
)
185 *sz
= buf
->end
- buf
->begin
;
187 *width
= buf
->begin
&& *buf
->begin
? mbs_width(buf
->begin
) : 0;
191 /* size of allocated area (!= size of stored data */
192 size_t ul_buffer_get_bufsiz(struct ul_buffer
*buf
)
197 /* encode data by mbs_safe_encode() to avoid control and non-printable chars */
198 char *ul_buffer_get_safe_data(struct ul_buffer
*buf
, size_t *sz
, size_t *width
, const char *safechars
)
200 char *data
= ul_buffer_get_data(buf
, NULL
, NULL
);
201 size_t encsz
, wsz
= 0;
207 encsz
= mbs_safe_encode_size(buf
->sz
) + 1;
208 if (encsz
> buf
->encoded_sz
) {
209 char *tmp
= realloc(buf
->encoded
, encsz
);
213 buf
->encoded_sz
= encsz
;
216 res
= mbs_safe_encode_to_buffer(data
, &wsz
, buf
->encoded
, safechars
);
217 if (!res
|| !wsz
|| wsz
== (size_t) -1)
234 #ifdef TEST_PROGRAM_BUFFER
243 struct ul_buffer buf
= UL_INIT_BUFFER
;
247 ul_buffer_set_chunksize(&buf
, 16);
249 ul_buffer_append_string(&buf
, "AAA");
250 ul_buffer_append_data(&buf
, "=", 1);
251 ul_buffer_append_string(&buf
, "aaa");
252 ul_buffer_save_pointer(&buf
, PTR_AAA
);
254 ul_buffer_append_data(&buf
, ",", 1);
255 ul_buffer_append_string(&buf
, "BBB");
256 ul_buffer_append_string(&buf
, "=");
257 ul_buffer_append_string(&buf
, "bbb");
258 ul_buffer_save_pointer(&buf
, PTR_BBB
);
260 str
= ul_buffer_get_data(&buf
, &sz
, NULL
);
261 printf("data [%zu] '%s'\n", sz
, str
);
263 printf(" pointer data len: AAA=%zu, BBB=%zu\n",
264 ul_buffer_get_pointer_length(&buf
, PTR_AAA
),
265 ul_buffer_get_pointer_length(&buf
, PTR_BBB
));
266 printf(" pointer data width: AAA=%zu, BBB=%zu\n",
267 ul_buffer_get_safe_pointer_width(&buf
, PTR_AAA
),
268 ul_buffer_get_safe_pointer_width(&buf
, PTR_BBB
));
270 ul_buffer_reset_data(&buf
);
271 ul_buffer_append_string(&buf
, "This is really long string to test the buffer function.");
272 ul_buffer_save_pointer(&buf
, PTR_AAA
);
273 ul_buffer_append_string(&buf
, " YES!");
274 str
= ul_buffer_get_data(&buf
, &sz
, NULL
);
275 printf("data [%zu] '%s'\n", sz
, str
);
276 printf(" pointer data len: AAA=%zu\n", ul_buffer_get_pointer_length(&buf
, PTR_AAA
));
278 ul_buffer_free_data(&buf
);
280 ul_buffer_refer_string(&buf
, str
);
281 ul_buffer_append_data(&buf
, ",", 1);
282 ul_buffer_append_string(&buf
, "bar");
283 str
= ul_buffer_get_data(&buf
, &sz
, NULL
);
284 printf("data [%zu] '%s'\n", sz
, str
);
286 ul_buffer_free_data(&buf
);
290 #endif /* TEST_PROGRAM_BUFFER */