25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
27 */ |
27 */ |
28 |
28 |
29 /** |
29 /** |
30 * \file buffer.h |
30 * @file buffer.h |
31 * |
31 * |
32 * \brief Advanced buffer implementation. |
32 * @brief Advanced buffer implementation. |
33 * |
33 * |
34 * Instances of CxBuffer can be used to read from or to write to like one |
34 * Instances of CxBuffer can be used to read from or to write to like one |
35 * would do with a stream. |
35 * would do with a stream. |
36 * |
36 * |
37 * Some features for convenient use of the buffer |
37 * Some features for convenient use of the buffer |
38 * can be enabled. See the documentation of the macro constants for more |
38 * can be enabled. See the documentation of the macro constants for more |
39 * information. |
39 * information. |
40 * |
40 * |
41 * \author Mike Becker |
41 * @author Mike Becker |
42 * \author Olaf Wintermann |
42 * @author Olaf Wintermann |
43 * \copyright 2-Clause BSD License |
43 * @copyright 2-Clause BSD License |
44 */ |
44 */ |
45 |
45 |
46 #ifndef UCX_BUFFER_H |
46 #ifndef UCX_BUFFER_H |
47 #define UCX_BUFFER_H |
47 #define UCX_BUFFER_H |
48 |
48 |
109 size_t capacity; |
109 size_t capacity; |
110 /** Current size of the buffer content. */ |
110 /** Current size of the buffer content. */ |
111 size_t size; |
111 size_t size; |
112 /** |
112 /** |
113 * The buffer may not extend beyond this threshold before starting to flush. |
113 * The buffer may not extend beyond this threshold before starting to flush. |
114 * Default is \c SIZE_MAX (flushing disabled when auto extension is enabled). |
114 * Default is @c SIZE_MAX (flushing disabled when auto extension is enabled). |
115 */ |
115 */ |
116 size_t flush_threshold; |
116 size_t flush_threshold; |
117 /** |
117 /** |
118 * The block size for the elements to flush. |
118 * The block size for the elements to flush. |
119 * Default is 4096 bytes. |
119 * Default is 4096 bytes. |
120 */ |
120 */ |
121 size_t flush_blksize; |
121 size_t flush_blksize; |
122 /** |
122 /** |
123 * The maximum number of blocks to flush in one cycle. |
123 * The maximum number of blocks to flush in one cycle. |
124 * Zero disables flushing entirely (this is the default). |
124 * Zero disables flushing entirely (this is the default). |
125 * Set this to \c SIZE_MAX to flush the entire buffer. |
125 * Set this to @c SIZE_MAX to flush the entire buffer. |
126 * |
126 * |
127 * @attention if the maximum number of blocks multiplied with the block size |
127 * @attention if the maximum number of blocks multiplied with the block size |
128 * is smaller than the expected contents written to this buffer within one write |
128 * is smaller than the expected contents written to this buffer within one write |
129 * operation, multiple flush cycles are performed after that write. |
129 * operation, multiple flush cycles are performed after that write. |
130 * That means the total number of blocks flushed after one write to this buffer may |
130 * That means the total number of blocks flushed after one write to this buffer may |
131 * be larger than \c flush_blkmax. |
131 * be larger than @c flush_blkmax. |
132 */ |
132 */ |
133 size_t flush_blkmax; |
133 size_t flush_blkmax; |
134 |
134 |
135 /** |
135 /** |
136 * The write function used for flushing. |
136 * The write function used for flushing. |
137 * If NULL, the flushed content gets discarded. |
137 * If NULL, the flushed content gets discarded. |
138 */ |
138 */ |
139 cx_write_func flush_func; |
139 cx_write_func flush_func; |
140 |
140 |
141 /** |
141 /** |
142 * The target for \c flush_func. |
142 * The target for @c flush_func. |
143 */ |
143 */ |
144 void *flush_target; |
144 void *flush_target; |
145 |
145 |
146 /** |
146 /** |
147 * Flag register for buffer features. |
147 * Flag register for buffer features. |
149 * @see #CX_BUFFER_FREE_CONTENTS |
149 * @see #CX_BUFFER_FREE_CONTENTS |
150 * @see #CX_BUFFER_AUTO_EXTEND |
150 * @see #CX_BUFFER_AUTO_EXTEND |
151 * @see #CX_BUFFER_COPY_ON_WRITE |
151 * @see #CX_BUFFER_COPY_ON_WRITE |
152 */ |
152 */ |
153 int flags; |
153 int flags; |
154 } cx_buffer_s; |
154 }; |
155 |
155 |
156 /** |
156 /** |
157 * UCX buffer. |
157 * UCX buffer. |
158 */ |
158 */ |
159 typedef cx_buffer_s CxBuffer; |
159 typedef struct cx_buffer_s CxBuffer; |
160 |
160 |
161 /** |
161 /** |
162 * Initializes a fresh buffer. |
162 * Initializes a fresh buffer. |
163 * |
163 * |
164 * You may also provide a read-only \p space, in which case |
164 * You may also provide a read-only @p space, in which case |
165 * you will need to cast the pointer, and you should set the |
165 * you will need to cast the pointer, and you should set the |
166 * #CX_BUFFER_COPY_ON_WRITE flag. |
166 * #CX_BUFFER_COPY_ON_WRITE flag. |
167 * |
167 * |
168 * You need to set the size manually after initialization, if |
168 * You need to set the size manually after initialization, if |
169 * you provide \p space which already contains data. |
169 * you provide @p space which already contains data. |
170 * |
170 * |
171 * When you specify stack memory as \p space and decide to use |
171 * When you specify stack memory as @p space and decide to use |
172 * the auto-extension feature, you \em must use the |
172 * the auto-extension feature, you @em must use the |
173 * #CX_BUFFER_COPY_ON_EXTEND flag, instead of the |
173 * #CX_BUFFER_COPY_ON_EXTEND flag, instead of the |
174 * #CX_BUFFER_AUTO_EXTEND flag. |
174 * #CX_BUFFER_AUTO_EXTEND flag. |
175 * |
175 * |
176 * \note You may provide \c NULL as argument for \p space. |
176 * @note You may provide @c NULL as argument for @p space. |
177 * Then this function will allocate the space and enforce |
177 * Then this function will allocate the space and enforce |
178 * the #CX_BUFFER_FREE_CONTENTS flag. In that case, specifying |
178 * the #CX_BUFFER_FREE_CONTENTS flag. In that case, specifying |
179 * copy-on-write should be avoided, because the allocated |
179 * copy-on-write should be avoided, because the allocated |
180 * space will be leaking after the copy-on-write operation. |
180 * space will be leaking after the copy-on-write operation. |
181 * |
181 * |
182 * @param buffer the buffer to initialize |
182 * @param buffer the buffer to initialize |
183 * @param space pointer to the memory area, or \c NULL to allocate |
183 * @param space pointer to the memory area, or @c NULL to allocate |
184 * new memory |
184 * new memory |
185 * @param capacity the capacity of the buffer |
185 * @param capacity the capacity of the buffer |
186 * @param allocator the allocator this buffer shall use for automatic |
186 * @param allocator the allocator this buffer shall use for automatic |
187 * memory management |
187 * memory management |
188 * (if \c NULL, a default stdlib allocator will be used) |
188 * (if @c NULL, a default stdlib allocator will be used) |
189 * @param flags buffer features (see cx_buffer_s.flags) |
189 * @param flags buffer features (see cx_buffer_s.flags) |
190 * @return zero on success, non-zero if a required allocation failed |
190 * @return zero on success, non-zero if a required allocation failed |
191 */ |
191 */ |
192 cx_attr_nonnull_arg(1) |
192 cx_attr_nonnull_arg(1) |
193 int cxBufferInit( |
193 int cxBufferInit( |
212 |
212 |
213 /** |
213 /** |
214 * Deallocates the buffer. |
214 * Deallocates the buffer. |
215 * |
215 * |
216 * If the #CX_BUFFER_FREE_CONTENTS feature is enabled, this function also destroys |
216 * If the #CX_BUFFER_FREE_CONTENTS feature is enabled, this function also destroys |
217 * the contents. If you \em only want to destroy the contents, use cxBufferDestroy(). |
217 * the contents. If you @em only want to destroy the contents, use cxBufferDestroy(). |
218 * |
218 * |
219 * \remark As with all free() functions, this accepts \c NULL arguments in which |
219 * @remark As with all free() functions, this accepts @c NULL arguments in which |
220 * case it does nothing. |
220 * case it does nothing. |
221 * |
221 * |
222 * @param buffer the buffer to deallocate |
222 * @param buffer the buffer to deallocate |
223 * @see cxBufferCreate() |
223 * @see cxBufferCreate() |
224 */ |
224 */ |
225 void cxBufferFree(CxBuffer *buffer); |
225 void cxBufferFree(CxBuffer *buffer); |
226 |
226 |
227 /** |
227 /** |
228 * Allocates and initializes a fresh buffer. |
228 * Allocates and initializes a fresh buffer. |
229 * |
229 * |
230 * You may also provide a read-only \p space, in which case |
230 * You may also provide a read-only @p space, in which case |
231 * you will need to cast the pointer, and you should set the |
231 * you will need to cast the pointer, and you should set the |
232 * #CX_BUFFER_COPY_ON_WRITE flag. |
232 * #CX_BUFFER_COPY_ON_WRITE flag. |
233 * When you specify stack memory as \p space and decide to use |
233 * When you specify stack memory as @p space and decide to use |
234 * the auto-extension feature, you \em must use the |
234 * the auto-extension feature, you @em must use the |
235 * #CX_BUFFER_COPY_ON_EXTEND flag, instead of the |
235 * #CX_BUFFER_COPY_ON_EXTEND flag, instead of the |
236 * #CX_BUFFER_AUTO_EXTEND flag. |
236 * #CX_BUFFER_AUTO_EXTEND flag. |
237 * |
237 * |
238 * \note You may provide \c NULL as argument for \p space. |
238 * @note You may provide @c NULL as argument for @p space. |
239 * Then this function will allocate the space and enforce |
239 * Then this function will allocate the space and enforce |
240 * the #CX_BUFFER_FREE_CONTENTS flag. |
240 * the #CX_BUFFER_FREE_CONTENTS flag. |
241 * |
241 * |
242 * @param space pointer to the memory area, or \c NULL to allocate |
242 * @param space pointer to the memory area, or @c NULL to allocate |
243 * new memory |
243 * new memory |
244 * @param capacity the capacity of the buffer |
244 * @param capacity the capacity of the buffer |
245 * @param allocator the allocator to use for allocating the structure and the automatic |
245 * @param allocator the allocator to use for allocating the structure and the automatic |
246 * memory management within the buffer |
246 * memory management within the buffer |
247 * (if \c NULL, a default stdlib allocator will be used) |
247 * (if @c NULL, a default stdlib allocator will be used) |
248 * @param flags buffer features (see cx_buffer_s.flags) |
248 * @param flags buffer features (see cx_buffer_s.flags) |
249 * @return a pointer to the buffer on success, \c NULL if a required allocation failed |
249 * @return a pointer to the buffer on success, @c NULL if a required allocation failed |
250 */ |
250 */ |
251 cx_attr_malloc |
251 cx_attr_malloc |
252 cx_attr_dealloc(cxBufferFree, 1) |
252 cx_attr_dealloc(cxBufferFree, 1) |
253 cx_attr_nodiscard |
253 cx_attr_nodiscard |
254 CxBuffer *cxBufferCreate( |
254 CxBuffer *cxBufferCreate( |
267 * no contents are changed. |
267 * no contents are changed. |
268 * If auto extension is disabled, the contents that do not fit into the buffer |
268 * If auto extension is disabled, the contents that do not fit into the buffer |
269 * are discarded. |
269 * are discarded. |
270 * |
270 * |
271 * If the offset is negative, the contents are shifted to the left where the |
271 * If the offset is negative, the contents are shifted to the left where the |
272 * first \p shift bytes are discarded. |
272 * first @p shift bytes are discarded. |
273 * The new size of the buffer is the old size minus the absolute shift value. |
273 * The new size of the buffer is the old size minus the absolute shift value. |
274 * If this value is larger than the buffer size, the buffer is emptied (but |
274 * If this value is larger than the buffer size, the buffer is emptied (but |
275 * not cleared, see the security note below). |
275 * not cleared, see the security note below). |
276 * |
276 * |
277 * The buffer position gets shifted alongside with the content but is kept |
277 * The buffer position gets shifted alongside with the content but is kept |
278 * within the boundaries of the buffer. |
278 * within the boundaries of the buffer. |
279 * |
279 * |
280 * \note For situations where \c off_t is not large enough, there are specialized cxBufferShiftLeft() and |
280 * @note For situations where @c off_t is not large enough, there are specialized cxBufferShiftLeft() and |
281 * cxBufferShiftRight() functions using a \c size_t as parameter type. |
281 * cxBufferShiftRight() functions using a @c size_t as parameter type. |
282 * |
282 * |
283 * \attention |
283 * @attention |
284 * Security Note: The shifting operation does \em not erase the previously occupied memory cells. |
284 * Security Note: The shifting operation does @em not erase the previously occupied memory cells. |
285 * But you can easily do that manually, e.g. by calling |
285 * But you can easily do that manually, e.g. by calling |
286 * <code>memset(buffer->bytes, 0, shift)</code> for a right shift or |
286 * <code>memset(buffer->bytes, 0, shift)</code> for a right shift or |
287 * <code>memset(buffer->bytes + buffer->size, 0, buffer->capacity - buffer->size)</code> |
287 * <code>memset(buffer->bytes + buffer->size, 0, buffer->capacity - buffer->size)</code> |
288 * for a left shift. |
288 * for a left shift. |
289 * |
289 * |
290 * @param buffer the buffer |
290 * @param buffer the buffer |
291 * @param shift the shift offset (negative means left shift) |
291 * @param shift the shift offset (negative means left shift) |
292 * @return 0 on success, non-zero if a required auto-extension or copy-on-write fails |
292 * @retval zero success |
|
293 * @retval non-zero if a required auto-extension or copy-on-write fails |
|
294 * @see cxBufferShiftLeft() |
|
295 * @see cxBufferShiftRight() |
293 */ |
296 */ |
294 cx_attr_nonnull |
297 cx_attr_nonnull |
295 int cxBufferShift( |
298 int cxBufferShift( |
296 CxBuffer *buffer, |
299 CxBuffer *buffer, |
297 off_t shift |
300 off_t shift |
301 * Shifts the buffer to the right. |
304 * Shifts the buffer to the right. |
302 * See cxBufferShift() for details. |
305 * See cxBufferShift() for details. |
303 * |
306 * |
304 * @param buffer the buffer |
307 * @param buffer the buffer |
305 * @param shift the shift offset |
308 * @param shift the shift offset |
306 * @return 0 on success, non-zero if a required auto-extension or copy-on-write fails |
309 * @retval zero success |
|
310 * @retval non-zero if a required auto-extension or copy-on-write fails |
307 * @see cxBufferShift() |
311 * @see cxBufferShift() |
308 */ |
312 */ |
309 cx_attr_nonnull |
313 cx_attr_nonnull |
310 int cxBufferShiftRight( |
314 int cxBufferShiftRight( |
311 CxBuffer *buffer, |
315 CxBuffer *buffer, |
316 * Shifts the buffer to the left. |
320 * Shifts the buffer to the left. |
317 * See cxBufferShift() for details. |
321 * See cxBufferShift() for details. |
318 * |
322 * |
319 * @param buffer the buffer |
323 * @param buffer the buffer |
320 * @param shift the positive shift offset |
324 * @param shift the positive shift offset |
321 * @return usually zero, except the buffer uses copy-on-write and the allocation fails |
325 * @retval zero success |
|
326 * @retval non-zero if the buffer uses copy-on-write and the allocation fails |
322 * @see cxBufferShift() |
327 * @see cxBufferShift() |
323 */ |
328 */ |
324 cx_attr_nonnull |
329 cx_attr_nonnull |
325 int cxBufferShiftLeft( |
330 int cxBufferShiftLeft( |
326 CxBuffer *buffer, |
331 CxBuffer *buffer, |
329 |
334 |
330 |
335 |
331 /** |
336 /** |
332 * Moves the position of the buffer. |
337 * Moves the position of the buffer. |
333 * |
338 * |
334 * The new position is relative to the \p whence argument. |
339 * The new position is relative to the @p whence argument. |
335 * |
340 * |
336 * \li \c SEEK_SET marks the start of the buffer. |
341 * @li @c SEEK_SET marks the start of the buffer. |
337 * \li \c SEEK_CUR marks the current position. |
342 * @li @c SEEK_CUR marks the current position. |
338 * \li \c SEEK_END marks the end of the buffer. |
343 * @li @c SEEK_END marks the end of the buffer. |
339 * |
344 * |
340 * With an offset of zero, this function sets the buffer position to zero |
345 * With an offset of zero, this function sets the buffer position to zero |
341 * (\c SEEK_SET), the buffer size (\c SEEK_END) or leaves the buffer position |
346 * (@c SEEK_SET), the buffer size (@c SEEK_END) or leaves the buffer position |
342 * unchanged (\c SEEK_CUR). |
347 * unchanged (@c SEEK_CUR). |
343 * |
348 * |
344 * @param buffer the buffer |
349 * @param buffer the buffer |
345 * @param offset position offset relative to \p whence |
350 * @param offset position offset relative to @p whence |
346 * @param whence one of \c SEEK_SET, \c SEEK_CUR or \c SEEK_END |
351 * @param whence one of @c SEEK_SET, @c SEEK_CUR or @c SEEK_END |
347 * @return 0 on success, non-zero if the position is invalid |
352 * @retval zero success |
|
353 * @retval non-zero if the position is invalid |
348 * |
354 * |
349 */ |
355 */ |
350 cx_attr_nonnull |
356 cx_attr_nonnull |
351 int cxBufferSeek( |
357 int cxBufferSeek( |
352 CxBuffer *buffer, |
358 CxBuffer *buffer, |
358 * Clears the buffer by resetting the position and deleting the data. |
364 * Clears the buffer by resetting the position and deleting the data. |
359 * |
365 * |
360 * The data is deleted by zeroing it with a call to memset(). |
366 * The data is deleted by zeroing it with a call to memset(). |
361 * If you do not need that, you can use the faster cxBufferReset(). |
367 * If you do not need that, you can use the faster cxBufferReset(). |
362 * |
368 * |
363 * \note If the #CX_BUFFER_COPY_ON_WRITE flag is set, this function |
369 * @note If the #CX_BUFFER_COPY_ON_WRITE flag is set, this function |
364 * will not erase the data and behave exactly as cxBufferReset(). |
370 * will not erase the data and behave exactly as cxBufferReset(). |
365 * |
371 * |
366 * @param buffer the buffer to be cleared |
372 * @param buffer the buffer to be cleared |
367 * @see cxBufferReset() |
373 * @see cxBufferReset() |
368 */ |
374 */ |
418 * newly available space can be used to append as much data as possible. This |
426 * newly available space can be used to append as much data as possible. This |
419 * function only stops writing more elements, when the flush target and this |
427 * function only stops writing more elements, when the flush target and this |
420 * buffer are both incapable of taking more data or all data has been written. |
428 * buffer are both incapable of taking more data or all data has been written. |
421 * The number returned by this function is the total number of elements that |
429 * The number returned by this function is the total number of elements that |
422 * could be written during the process. It does not necessarily mean that those |
430 * could be written during the process. It does not necessarily mean that those |
423 * elements are still in this buffer, because some of them could have also be |
431 * elements are still in this buffer, because some of them could have also been |
424 * flushed already. |
432 * flushed already. |
425 * |
433 * |
426 * If automatic flushing is not enabled, the position of the buffer is increased |
434 * If automatic flushing is not enabled, the data is simply written into the |
|
435 * buffer at the current position and the position of the buffer is increased |
427 * by the number of bytes written. |
436 * by the number of bytes written. |
428 * |
437 * Use cxBufferAppend() if you want to add data to this buffer regardless of |
429 * \note The signature is compatible with the fwrite() family of functions. |
438 * the position. |
|
439 * |
|
440 * @note The signature is compatible with the fwrite() family of functions. |
430 * |
441 * |
431 * @param ptr a pointer to the memory area containing the bytes to be written |
442 * @param ptr a pointer to the memory area containing the bytes to be written |
432 * @param size the length of one element |
443 * @param size the length of one element |
433 * @param nitems the element count |
444 * @param nitems the element count |
434 * @param buffer the CxBuffer to write to |
445 * @param buffer the CxBuffer to write to |
435 * @return the total count of elements written |
446 * @return the total count of elements written |
|
447 * @see cxBufferAppend() |
|
448 * @see cxBufferRead() |
436 */ |
449 */ |
437 cx_attr_nonnull |
450 cx_attr_nonnull |
438 size_t cxBufferWrite( |
451 size_t cxBufferWrite( |
439 const void *ptr, |
452 const void *ptr, |
440 size_t size, |
453 size_t size, |
449 * regardless of the current position. |
462 * regardless of the current position. |
450 * This is especially useful when the buffer is primarily meant for reading |
463 * This is especially useful when the buffer is primarily meant for reading |
451 * while additional data is added to the buffer occasionally. |
464 * while additional data is added to the buffer occasionally. |
452 * Consequently, the position of the buffer is unchanged after this operation. |
465 * Consequently, the position of the buffer is unchanged after this operation. |
453 * |
466 * |
454 * \note The signature is compatible with the fwrite() family of functions. |
467 * @note The signature is compatible with the fwrite() family of functions. |
455 * |
468 * |
456 * @param ptr a pointer to the memory area containing the bytes to be written |
469 * @param ptr a pointer to the memory area containing the bytes to be written |
457 * @param size the length of one element |
470 * @param size the length of one element |
458 * @param nitems the element count |
471 * @param nitems the element count |
459 * @param buffer the CxBuffer to write to |
472 * @param buffer the CxBuffer to write to |
460 * @return the total count of elements written |
473 * @return the total count of elements written |
461 * @see cxBufferWrite() |
474 * @see cxBufferWrite() |
|
475 * @see cxBufferRead() |
462 */ |
476 */ |
463 cx_attr_nonnull |
477 cx_attr_nonnull |
464 size_t cxBufferAppend( |
478 size_t cxBufferAppend( |
465 const void *ptr, |
479 const void *ptr, |
466 size_t size, |
480 size_t size, |
471 /** |
485 /** |
472 * Reads data from a CxBuffer. |
486 * Reads data from a CxBuffer. |
473 * |
487 * |
474 * The position of the buffer is increased by the number of bytes read. |
488 * The position of the buffer is increased by the number of bytes read. |
475 * |
489 * |
476 * \note The signature is compatible with the fread() family of functions. |
490 * @note The signature is compatible with the fread() family of functions. |
477 * |
491 * |
478 * @param ptr a pointer to the memory area where to store the read data |
492 * @param ptr a pointer to the memory area where to store the read data |
479 * @param size the length of one element |
493 * @param size the length of one element |
480 * @param nitems the element count |
494 * @param nitems the element count |
481 * @param buffer the CxBuffer to read from |
495 * @param buffer the CxBuffer to read from |
482 * @return the total number of elements read |
496 * @return the total number of elements read |
|
497 * @see cxBufferWrite() |
|
498 * @see cxBufferAppend() |
483 */ |
499 */ |
484 cx_attr_nonnull |
500 cx_attr_nonnull |
485 size_t cxBufferRead( |
501 size_t cxBufferRead( |
486 void *ptr, |
502 void *ptr, |
487 size_t size, |
503 size_t size, |
493 * Writes a character to a buffer. |
509 * Writes a character to a buffer. |
494 * |
510 * |
495 * The least significant byte of the argument is written to the buffer. If the |
511 * The least significant byte of the argument is written to the buffer. If the |
496 * end of the buffer is reached and #CX_BUFFER_AUTO_EXTEND feature is enabled, |
512 * end of the buffer is reached and #CX_BUFFER_AUTO_EXTEND feature is enabled, |
497 * the buffer capacity is extended by cxBufferMinimumCapacity(). If the feature |
513 * the buffer capacity is extended by cxBufferMinimumCapacity(). If the feature |
498 * is disabled or buffer extension fails, \c EOF is returned. |
514 * is disabled or buffer extension fails, @c EOF is returned. |
499 * |
515 * |
500 * On successful write, the position of the buffer is increased. |
516 * On successful write, the position of the buffer is increased. |
|
517 * |
|
518 * If you just want to write a null-terminator at the current position, you |
|
519 * should use cxBufferTerminate() instead. |
501 * |
520 * |
502 * @param buffer the buffer to write to |
521 * @param buffer the buffer to write to |
503 * @param c the character to write |
522 * @param c the character to write |
504 * @return the byte that has been written or \c EOF when the end of the stream is |
523 * @return the byte that has been written or @c EOF when the end of the stream is |
505 * reached and automatic extension is not enabled or not possible |
524 * reached and automatic extension is not enabled or not possible |
|
525 * @see cxBufferTerminate() |
506 */ |
526 */ |
507 cx_attr_nonnull |
527 cx_attr_nonnull |
508 int cxBufferPut( |
528 int cxBufferPut( |
509 CxBuffer *buffer, |
529 CxBuffer *buffer, |
510 int c |
530 int c |
511 ); |
531 ); |
512 |
532 |
513 /** |
533 /** |
514 * Writes a terminating zero to a buffer. |
534 * Writes a terminating zero to a buffer at the current position. |
515 * |
535 * |
516 * On successful write, \em neither the position \em nor the size of the buffer is |
536 * On successful write, @em neither the position @em nor the size of the buffer is |
517 * increased. |
537 * increased. |
518 * |
538 * |
519 * The purpose of this function is to have the written data ready to be used as |
539 * The purpose of this function is to have the written data ready to be used as |
520 * a C string. |
540 * a C string. |
521 * |
541 * |