]>
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
)
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
= realloc(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
);
143 if (maxsz
<= sz
+ 1) {
144 int rc
= ul_buffer_alloc_data(buf
, buf
->sz
+ sz
+ 1);
149 return -EINVAL
; /* make static analyzers happy */
151 buf
->end
= mempcpy(buf
->end
, data
, sz
);
152 *buf
->end
= '\0'; /* make sure it's terminated */
156 int ul_buffer_append_string(struct ul_buffer
*buf
, const char *str
)
161 return ul_buffer_append_data(buf
, str
, strlen(str
));
164 int ul_buffer_append_ntimes(struct ul_buffer
*buf
, size_t n
, const char *str
)
167 size_t len
= strlen(str
);
169 for (i
= 0; len
&& i
< n
; i
++) {
170 int rc
= ul_buffer_append_data(buf
, str
, len
);
177 int ul_buffer_set_data(struct ul_buffer
*buf
, const char *data
, size_t sz
)
179 ul_buffer_reset_data(buf
);
180 return ul_buffer_append_data(buf
, data
, sz
);
183 char *ul_buffer_get_data(struct ul_buffer
*buf
, size_t *sz
, size_t *width
)
186 *sz
= buf
->end
- buf
->begin
;
188 *width
= buf
->begin
&& *buf
->begin
? mbs_width(buf
->begin
) : 0;
192 /* size of allocated area (!= size of stored data */
193 size_t ul_buffer_get_bufsiz(struct ul_buffer
*buf
)
198 /* encode data by mbs_safe_encode() to avoid control and non-printable chars */
199 char *ul_buffer_get_safe_data(struct ul_buffer
*buf
, size_t *sz
, size_t *width
, const char *safechars
)
201 char *data
= ul_buffer_get_data(buf
, NULL
, NULL
);
202 size_t encsz
, wsz
= 0;
208 encsz
= mbs_safe_encode_size(buf
->sz
) + 1;
209 if (encsz
> buf
->encoded_sz
) {
210 char *tmp
= realloc(buf
->encoded
, encsz
);
214 buf
->encoded_sz
= encsz
;
217 res
= mbs_safe_encode_to_buffer(data
, &wsz
, buf
->encoded
, safechars
);
218 if (!res
|| !wsz
|| wsz
== (size_t) -1)
235 #ifdef TEST_PROGRAM_BUFFER
244 struct ul_buffer buf
= UL_INIT_BUFFER
;
248 ul_buffer_set_chunksize(&buf
, 16);
250 ul_buffer_append_string(&buf
, "AAA");
251 ul_buffer_append_data(&buf
, "=", 1);
252 ul_buffer_append_string(&buf
, "aaa");
253 ul_buffer_save_pointer(&buf
, PTR_AAA
);
255 ul_buffer_append_data(&buf
, ",", 1);
256 ul_buffer_append_string(&buf
, "BBB");
257 ul_buffer_append_string(&buf
, "=");
258 ul_buffer_append_string(&buf
, "bbb");
259 ul_buffer_save_pointer(&buf
, PTR_BBB
);
261 str
= ul_buffer_get_data(&buf
, &sz
, NULL
);
262 printf("data [%zu] '%s'\n", sz
, str
);
264 printf(" pointer data len: AAA=%zu, BBB=%zu\n",
265 ul_buffer_get_pointer_length(&buf
, PTR_AAA
),
266 ul_buffer_get_pointer_length(&buf
, PTR_BBB
));
267 printf(" pointer data width: AAA=%zu, BBB=%zu\n",
268 ul_buffer_get_safe_pointer_width(&buf
, PTR_AAA
),
269 ul_buffer_get_safe_pointer_width(&buf
, PTR_BBB
));
271 ul_buffer_reset_data(&buf
);
272 ul_buffer_append_string(&buf
, "This is really long string to test the buffer function.");
273 ul_buffer_save_pointer(&buf
, PTR_AAA
);
274 ul_buffer_append_string(&buf
, " YES!");
275 str
= ul_buffer_get_data(&buf
, &sz
, NULL
);
276 printf("data [%zu] '%s'\n", sz
, str
);
277 printf(" pointer data len: AAA=%zu\n", ul_buffer_get_pointer_length(&buf
, PTR_AAA
));
279 ul_buffer_free_data(&buf
);
281 ul_buffer_refer_string(&buf
, str
);
282 ul_buffer_append_data(&buf
, ",", 1);
283 ul_buffer_append_string(&buf
, "bar");
284 str
= ul_buffer_get_data(&buf
, &sz
, NULL
);
285 printf("data [%zu] '%s'\n", sz
, str
);
287 ul_buffer_free_data(&buf
);
291 #endif /* TEST_PROGRAM_BUFFER */