1.. _buffer:
2
3************************
4Resizable binary buffers
5************************
6
7.. highlight:: c
8
9::
10
11  #include <libcork/ds.h>
12
13This section defines a resizable binary buffer type.  This class can
14also be used to construct C strings, when you don't know the size of
15the string in advance.
16
17This class is not reference counted; we assume that there's a single
18owner of the buffer.  The contents of a :c:type:`cork_buffer` are fully
19mutable.  If you want to turn the buffer into something that's safe to
20pass between threads, you can use the :c:func:`cork_buffer_to_slice()`
21or :c:func:`cork_buffer_to_managed_buffer()` functions to create an
22immutable managed wrapper around the buffer.
23
24You can read the contents of the buffer by accessing the :c:member:`buf
25<cork_buffer.buf>` and :c:member:`size <cork_buffer.size>` fields
26directly.  However, to modify the contents of a buffer, you should use
27the mutator functions described below, since they take care of
28automatically resizing the underlying buffer when necessary.
29
30.. note::
31
32   This class always creates its own copy of any data added to the
33   buffer; there aren't any methods for wrapping existing buffers
34   without copying.  If you want to do that, you should use
35   :ref:`managed-buffer` or :ref:`slice`.
36
37
38.. type:: struct cork_buffer
39
40   A resizable binary buffer.
41
42   .. member:: void \*buf
43
44      The current contents of the buffer.
45
46   .. member:: size_t  size
47
48      The current size of the buffer.
49
50
51.. function:: void cork_buffer_init(struct cork_buffer \*buffer)
52              struct cork_buffer CORK_BUFFER_INIT()
53
54   Initialize a new buffer instance that you've allocated yourself
55   (usually on the stack).  The ``CORK_BUFFER_INIT`` version can only be
56   used as a static initializer.
57
58   The preallocated ``cork_buffer`` instance that you provide doesn't
59   include space for the content of the buffer; this will be allocated
60   automatically as content is added.
61
62.. function:: struct cork_buffer \*cork_buffer_new(void)
63
64   Allocate and initialize a new buffer instance.
65
66.. function:: void cork_buffer_done(struct cork_buffer \*buffer)
67
68   Finalize a buffer, freeing any content that it contains.  This
69   function should only be used for buffers that you allocated yourself,
70   and initialized using :c:func:`cork_buffer_init()` or
71   :c:func:`CORK_BUFFER_INIT()`.  You must **not** use this function to
72   free a buffer allocated using :c:func:`cork_buffer_new()`.
73
74.. function:: void cork_buffer_free(struct cork_buffer \*buffer)
75
76   Finalize and deallocate a buffer, freeing any content that it
77   contains.  This function should only be used for buffers allocated
78   using :c:func:`cork_buffer_new()`.  You must **not** use this
79   function to free a buffer initialized using
80   :c:func:`cork_buffer_init()` or :c:func:`CORK_BUFFER_INIT()`.
81
82.. function:: bool cork_buffer_equal(const struct cork_buffer \*buffer1, const struct cork_buffer \*buffer2)
83
84   Compare two buffers for equality.
85
86.. function:: void cork_buffer_ensure_size(struct cork_buffer \*buffer, size_t desired_size)
87
88   Ensure that a buffer has allocated enough space to store at least
89   *desired_size* bytes.  We won't shrink the size of the buffer's
90   internal storage; if the buffer has already allocated at least
91   *desired_size* bytes, the function acts as a no-op.
92
93.. function:: uint8_t cork_buffer_byte(struct cork_buffer \*buffer, size_t index)
94              char cork_buffer_char(struct cork_buffer \*buffer, size_t index)
95
96   Return the byte or character at the given index in *buffer*.
97
98
99Mutator functions
100-----------------
101
102Most of the mutator functions defined in this section come in two
103variants: a ``_set`` function, which clears the buffer before adding new
104content, and an ``_append`` function, which retains the old content,
105adding the new content to the end of the buffer.
106
107Each mutator function will automatically append an extra ``NUL`` byte to
108the end of whatever content is placed into the buffer.  However, this
109``NUL`` byte will **not** be included in the :c:member:`size
110<cork_buffer.size>` of the buffer.  This ensures that the contents of
111any ``cork_buffer`` can be used as a ``NUL``\ -terminated C string
112(assuming that there aren't any internal ``NUL``\ s), even if the buffer
113is constructed from a data source that doesn't include ``NUL``
114terminators.
115
116.. function:: void cork_buffer_clear(struct cork_buffer \*buffer)
117
118   Clear a buffer.  This does not free any storage that the buffer has
119   allocated; this storage will be reused if you add contents back to the
120   buffer.
121
122.. function:: void cork_buffer_truncate(struct cork_buffer \*buffer, size_t length)
123
124   Truncate a buffer so that contains no more than *length* bytes.  If the
125   buffer is already shorter than this, it is not modified.
126
127.. function:: void cork_buffer_copy(struct cork_buffer \*dest, const struct cork_buffer \*src)
128              void cork_buffer_append_copy(struct cork_buffer \*dest, const struct cork_buffer \*src)
129
130   Copy the contents of the *src* buffer into *dest*.  The ``_set`` variant
131   clears the buffer first, while the ``_append`` variant adds *src* to whatever
132   content is already there.
133
134.. function:: void cork_buffer_set(struct cork_buffer \*buffer, const void \*src, size_t length)
135              void cork_buffer_append(struct cork_buffer \*buffer, const void \*src, size_t length)
136
137   Copy the contents of *src* into a buffer.  The ``_set`` variant
138   clears the buffer first, while the ``_append`` variant adds *src* to
139   whatever content is already there.
140
141.. function:: void cork_buffer_set_string(struct cork_buffer \*buffer, const char \*str)
142              void cork_buffer_append_string(struct cork_buffer \*buffer, const char \*str)
143              void cork_buffer_set_literal(struct cork_buffer \*buffer, const char \*str)
144              void cork_buffer_append_literal(struct cork_buffer \*buffer, const char \*str)
145
146   Copy the contents of *str* (which must be a ``NUL``\ -terminated C
147   string) into a buffer.  The ``_set`` variants clears the buffer first,
148   while the ``_append`` variants adds *str* to whatever content is
149   already there.  The ``_literal`` variants only work when *str* is a C string
150   literal; we use the ``sizeof`` operator to determine the length of the string
151   at compile time.  The ``_string`` variants work with any C string; we use the
152   builtin ``strlen`` function to determine the length of the string.
153
154.. function:: void cork_buffer_printf(struct cork_buffer \*buffer, const char \*format, ...)
155              void cork_buffer_vprintf(struct cork_buffer \*buffer, const char \*format, va_list args)
156              void cork_buffer_append_printf(struct cork_buffer \*buffer, const char \*format, ...)
157              void cork_buffer_append_vprintf(struct cork_buffer \*buffer, const char \*format, va_list args)
158
159   Format data according to a ``printf`` format string, placing the
160   result into a buffer.  The ``_append`` variants add the formatted
161   string to whatever content is already in the buffer; the non-\
162   ``_append`` variants clear the buffer first.  The ``_printf``
163   variants are vararg functions, and take in the format string's data
164   as direct parameters.  The ``_vprintf`` variants can be used within
165   another vararg function, and let you pass in the format string's data
166   as a C99-standard ``va_list`` instance.
167
168
169Pretty-printing
170---------------
171
172We also provide several helper functions for adding pretty-printed content to a
173``cork_buffer``.
174
175.. function:: void cork_buffer_append_indent(struct cork_buffer \*buffer, size_t indent)
176
177   Append *indent* spaces to *buffer*.
178
179.. function:: void cork_buffer_append_c_string(struct cork_buffer \*buffer, const char \*str, size_t length)
180
181   Append the C string literal representation of *str* to *buffer*.  This will
182   include opening and closing double quotes, and any non-printable characters
183   will be escaped.  (We will use the standard letter-based escapes where
184   possible, and fall back on ``"\xXX"`` hexadecimal escapes for other
185   non-printable characters.)  The result is guaranteed to stay on a single
186   line, since any embedded newlines will be converted to a ``\n`` escape
187   sequence.
188
189.. function:: void cork_buffer_append_hex_dump(struct cork_buffer \*buffer, size_t indent, const char \*str, size_t length)
190              void cork_buffer_append_multiline(struct cork_buffer \*buffer, size_t indent, const char \*str, size_t length)
191              void cork_buffer_append_binary(struct cork_buffer \*buffer, size_t indent, const char \*str, size_t length)
192
193   Append a pretty-printed representation of *str* to *buffer*.  All of these
194   functions can produce multiple lines of output.  All lines except for the
195   first will be prefaced with *indent* space characters.  The final line will
196   **not** have a trailing newline.
197
198   The ``hex_dump`` variant will output a hex-dump representation of *str*.
199   This will include the hexadecimal representation of each byte, and the actual
200   character of any printable byte.
201
202   The ``multiline`` variant appends the raw content of *str* to the buffer,
203   without making any attempt to sanitize non-printable characters.  (That means
204   you should only call this variant if you know that *str* contains only
205   printable characters.)  If *str* itself spans multiple lines, then we'll
206   insert indentation to make sure that we satisfy the indentation rules
207   described above.
208
209   The ``binary`` variant autodetects how to best render *str*.  If it contains
210   any non-printable characters, then we'll use the ``hex_dump`` representation.
211   If it spans multiple lines, we'll use the ``multiline`` representation.
212   Otherwise, we'll append the content directly without any modification.
213
214
215Other binary data structures
216----------------------------
217
218The ``cork_buffer`` class is the only binary data class that is mutable;
219this comes at the cost of only being usable by a single owner thread or
220function at a time.  Once you have constructed a binary string or
221payload using a ``cork_buffer``, you can use the functions in this
222section to produce a corresponding instance of one of libcork's
223sharable, immutable binary data types.
224
225.. function:: struct cork_managed_buffer \*cork_buffer_to_managed_buffer(struct cork_buffer \*buffer)
226
227   Create a new :ref:`managed buffer <managed-buffer>` to manage the
228   contents of a ``cork_buffer`` instance.  *buffer* must have been
229   allocated on the heap (i.e., using :c:func:`cork_buffer_new()`, and
230   not :c:func:`cork_buffer_init()`).  We take ownership of *buffer*,
231   regardless of whether we're able to successfully create a new
232   :c:type:`cork_managed_buffer` instance.  You must **not** try to free
233   *buffer* yourself.
234
235.. function:: int cork_buffer_to_slice(struct cork_buffer \*buffer, struct cork_slice \*slice)
236
237   Initialize a new :ref:`slice <slice>` to manage the contents of
238   *buffer*.  *buffer* must have been allocated on the heap (i.e., using
239   :c:func:`cork_buffer_new()`, and not :c:func:`cork_buffer_init()`).
240   We take ownership of *buffer*, regardless of whether we're able to
241   successfully create a new :c:type:`cork_managed_buffer` instance.
242   You must **not** try to free *buffer* yourself.
243
244   The slice will point into the contents of a new :ref:`managed buffer
245   <managed-buffer>` instance.  The managed buffer isn't returned
246   directly, though you can create additional slices into it using the
247   usual :c:type:`cork_slice` methods.
248
249   Regardless of whether we can initialize the slice successfully, you
250   **must** call :c:func:`cork_slice_finish()` on *slice* when you're
251   done with the slice.
252
253.. function:: struct cork_stream_consumer \*cork_buffer_to_stream_consumer(struct cork_buffer \*buffer)
254
255   Create a new stream consumer that appends any received data into
256   *buffer*.
257
258   We do **not** take control of *buffer*.  You retain responsibility
259   for freeing the buffer, and you must ensure that it remains allocated
260   and valid for the entire lifetime of the stream consumer that we
261   return.
262