/src/util-linux/include/buffer.h
Line | Count | Source |
1 | | /* |
2 | | * No copyright is claimed. This code is in the public domain; do with |
3 | | * it what you wish. |
4 | | */ |
5 | | #ifndef UTIL_LINUX_BUFFER |
6 | | #define UTIL_LINUX_BUFFER |
7 | | |
8 | | #include <stddef.h> |
9 | | #include <stdarg.h> |
10 | | |
11 | | /* |
12 | | * The data is always zero-terminated at END, and the space between END and |
13 | | * BEGIN + SZ is kept zeroed; ul_buffer_alloc_data() zero-fills the newly |
14 | | * allocated space and the append functions always terminate the data. |
15 | | * |
16 | | * Keep this invariant in mind when adding a new ul_buffer_*() function, |
17 | | * ul_buffer_reset_data() depends on it to avoid clearing the whole |
18 | | * allocation. |
19 | | */ |
20 | | struct ul_buffer { |
21 | | char *begin; /* begin of the data */ |
22 | | char *end; /* current end of data */ |
23 | | |
24 | | size_t sz; /* allocated space for data */ |
25 | | size_t chunksize; |
26 | | |
27 | | char *encoded; /* encoded data (from mbs_safe_encode_to_buffer)) */ |
28 | | size_t encoded_sz; /* space allocated for encoded data */ |
29 | | |
30 | | size_t *ptrs; /* saved positions; offset from BEGIN plus 1, zero means unset */ |
31 | | size_t nptrs; /* number of saved positions */ |
32 | | }; |
33 | | |
34 | 31.5k | #define UL_INIT_BUFFER { .begin = NULL } |
35 | | |
36 | | void ul_buffer_reset_data(struct ul_buffer *buf); |
37 | | void ul_buffer_free_data(struct ul_buffer *buf); |
38 | | |
39 | | /* |
40 | | * This is a variant of ul_buffer_free_data(). Instead of freeing the |
41 | | * BEGIN member, this function transfers its ownership to the caller. |
42 | | * |
43 | | * If the BEGIN member points to an empty C string, |
44 | | * ul_buffer_steal_string() frees the buffer and returns NULL. |
45 | | */ |
46 | | char *ul_buffer_steal_string(struct ul_buffer *buf); |
47 | | |
48 | | int ul_buffer_is_empty(struct ul_buffer *buf); |
49 | | void ul_buffer_set_chunksize(struct ul_buffer *buf, size_t sz); |
50 | | void ul_buffer_refer_string(struct ul_buffer *buf, char *str); |
51 | | int ul_buffer_alloc_data(struct ul_buffer *buf, size_t sz); |
52 | | int ul_buffer_append_data(struct ul_buffer *buf, const char *data, size_t sz); |
53 | | int ul_buffer_append_char(struct ul_buffer *buf, const char c); |
54 | | int ul_buffer_append_string(struct ul_buffer *buf, const char *str); |
55 | | int ul_buffer_append_ntimes(struct ul_buffer *buf, size_t n, const char *str); |
56 | | int ul_buffer_appendf(struct ul_buffer *buf, const char *format, ...) |
57 | | __attribute__ ((__format__ (__printf__, 2, 3))); |
58 | | int ul_buffer_appendvf(struct ul_buffer *buf, const char *format, va_list ap) |
59 | | __attribute__ ((__format__ (__printf__, 2, 0))); |
60 | | int ul_buffer_set_data(struct ul_buffer *buf, const char *data, size_t sz); |
61 | | |
62 | | char *ul_buffer_get_data(struct ul_buffer *buf, size_t *sz, size_t *width); |
63 | | char *ul_buffer_get_string(struct ul_buffer *buf, size_t *sz, size_t *width); |
64 | | char *ul_buffer_get_safe_data(struct ul_buffer *buf, size_t *sz, size_t *width, const char *safechars); |
65 | | |
66 | | size_t ul_buffer_get_bufsiz(struct ul_buffer *buf); |
67 | | size_t ul_buffer_get_datasiz(struct ul_buffer *buf); |
68 | | |
69 | | int ul_buffer_save_pointer(struct ul_buffer *buf, unsigned short ptr_idx); |
70 | | char *ul_buffer_get_pointer(struct ul_buffer *buf, unsigned short ptr_idx); |
71 | | size_t ul_buffer_get_pointer_length(struct ul_buffer *buf, unsigned short ptr_idx); |
72 | | size_t ul_buffer_get_safe_pointer_width(struct ul_buffer *buf, unsigned short ptr_idx); |
73 | | |
74 | | /* |
75 | | * Include xalloc.h first to use the buffer_x*() functions. |
76 | | */ |
77 | | #ifdef XALLOC_EXIT_CODE |
78 | | static inline int ul_buffer_xappend_string(struct ul_buffer *buf, const char *str) |
79 | 0 | { |
80 | 0 | int r = ul_buffer_append_string(buf, str); |
81 | 0 | if (r < 0) |
82 | 0 | err(XALLOC_EXIT_CODE, "cannot allocate buffer"); |
83 | 0 | return r; |
84 | 0 | } |
85 | | |
86 | | static inline int ul_buffer_xappend_char(struct ul_buffer *buf, const char c) |
87 | 0 | { |
88 | 0 | int r = ul_buffer_append_char(buf, c); |
89 | 0 | if (r < 0) |
90 | 0 | err(XALLOC_EXIT_CODE, "cannot allocate buffer"); |
91 | 0 | return r; |
92 | 0 | } |
93 | | |
94 | | static inline |
95 | | __attribute__ ((__format__ (__printf__, 2, 0))) |
96 | | int ul_buffer_xappendvf(struct ul_buffer *buf, const char *format, va_list ap) |
97 | 0 | { |
98 | 0 | int r = ul_buffer_appendvf(buf, format, ap); |
99 | 0 | if (r < 0) |
100 | 0 | err(XALLOC_EXIT_CODE, "cannot allocate buffer"); |
101 | 0 | return r; |
102 | 0 | } |
103 | | |
104 | | static inline |
105 | | __attribute__ ((__format__ (__printf__, 2, 3))) |
106 | | int ul_buffer_xappendf(struct ul_buffer *buf, const char *format, ...) |
107 | 0 | { |
108 | 0 | va_list ap; |
109 | 0 | int res; |
110 | 0 |
|
111 | 0 | va_start(ap, format); |
112 | 0 | res = ul_buffer_xappendvf(buf, format, ap); |
113 | 0 | va_end(ap); |
114 | 0 |
|
115 | 0 | return res; |
116 | 0 | } |
117 | | #endif/* XALLOC_EXIT_CODE */ |
118 | | |
119 | | #endif /* UTIL_LINUX_BUFFER */ |