| 87 * buffers automatically admit the auto-extend flag when initialized with copy-on-extend enabled. |
88 * buffers automatically admit the auto-extend flag when initialized with copy-on-extend enabled. |
| 88 */ |
89 */ |
| 89 #define CX_BUFFER_COPY_ON_EXTEND 0x08 |
90 #define CX_BUFFER_COPY_ON_EXTEND 0x08 |
| 90 |
91 |
| 91 /** |
92 /** |
| |
93 * If this flag is enabled, the buffer will never free its contents regardless of #CX_BUFFER_FREE_CONTENTS. |
| |
94 * |
| |
95 * This is useful, for example, when you want to keep a pointer to the data after destroying the buffer. |
| |
96 */ |
| |
97 #define CX_BUFFER_DO_NOT_FREE 0x10 |
| |
98 |
| |
99 /** |
| 92 * Function pointer for cxBufferWrite that is compatible with cx_write_func. |
100 * Function pointer for cxBufferWrite that is compatible with cx_write_func. |
| 93 * @see cx_write_func |
101 * @see cx_write_func |
| 94 */ |
102 */ |
| 95 #define cxBufferWriteFunc ((cx_write_func) cxBufferWrite) |
103 #define cxBufferWriteFunc ((cx_write_func) cxBufferWrite) |
| 96 /** |
104 /** |
| 97 * Function pointer for cxBufferRead that is compatible with cx_read_func. |
105 * Function pointer for cxBufferRead that is compatible with cx_read_func. |
| 98 * @see cx_read_func |
106 * @see cx_read_func |
| 99 */ |
107 */ |
| 100 #define cxBufferReadFunc ((cx_read_func) cxBufferRead) |
108 #define cxBufferReadFunc ((cx_read_func) cxBufferRead) |
| 101 |
109 |
| 102 /** |
|
| 103 * Configuration for automatic flushing. |
|
| 104 */ |
|
| 105 struct cx_buffer_flush_config_s { |
|
| 106 /** |
|
| 107 * The buffer may not extend beyond this threshold before starting to flush. |
|
| 108 * |
|
| 109 * Only used when the buffer uses #CX_BUFFER_AUTO_EXTEND. |
|
| 110 * The threshold will be the maximum capacity the buffer is extended to |
|
| 111 * before flushing. |
|
| 112 */ |
|
| 113 size_t threshold; |
|
| 114 /** |
|
| 115 * The block size for the elements to flush. |
|
| 116 */ |
|
| 117 size_t blksize; |
|
| 118 /** |
|
| 119 * The maximum number of blocks to flush in one cycle. |
|
| 120 * |
|
| 121 * @attention while it is guaranteed that cxBufferFlush() will not flush |
|
| 122 * more blocks, this is not necessarily the case for cxBufferWrite(). |
|
| 123 * After performing a flush cycle, cxBufferWrite() will retry the write |
|
| 124 * operation and potentially trigger another flush cycle, until the |
|
| 125 * flush target accepts no more data. |
|
| 126 */ |
|
| 127 size_t blkmax; |
|
| 128 |
|
| 129 /** |
|
| 130 * The target for the write function. |
|
| 131 */ |
|
| 132 void *target; |
|
| 133 |
|
| 134 /** |
|
| 135 * The write-function used for flushing. |
|
| 136 * If NULL, the flushed content gets discarded. |
|
| 137 */ |
|
| 138 cx_write_func wfunc; |
|
| 139 }; |
|
| 140 |
|
| 141 /** |
|
| 142 * Type alias for the flush configuration struct. |
|
| 143 * |
|
| 144 * @code |
|
| 145 * struct cx_buffer_flush_config_s { |
|
| 146 * size_t threshold; |
|
| 147 * size_t blksize; |
|
| 148 * size_t blkmax; |
|
| 149 * void *target; |
|
| 150 * cx_write_func wfunc; |
|
| 151 * }; |
|
| 152 * @endcode |
|
| 153 */ |
|
| 154 typedef struct cx_buffer_flush_config_s CxBufferFlushConfig; |
|
| 155 |
110 |
| 156 /** Structure for the UCX buffer data. */ |
111 /** Structure for the UCX buffer data. */ |
| 157 struct cx_buffer_s { |
112 struct cx_buffer_s { |
| 158 /** A pointer to the buffer contents. */ |
113 /** A pointer to the buffer contents. */ |
| 159 union { |
114 union { |
| 166 */ |
121 */ |
| 167 unsigned char *bytes; |
122 unsigned char *bytes; |
| 168 }; |
123 }; |
| 169 /** The allocator to use for automatic memory management. */ |
124 /** The allocator to use for automatic memory management. */ |
| 170 const CxAllocator *allocator; |
125 const CxAllocator *allocator; |
| 171 /** |
|
| 172 * Optional flush configuration |
|
| 173 * |
|
| 174 * @see cxBufferEnableFlushing() |
|
| 175 */ |
|
| 176 CxBufferFlushConfig *flush; |
|
| 177 /** Current position of the buffer. */ |
126 /** Current position of the buffer. */ |
| 178 size_t pos; |
127 size_t pos; |
| 179 /** Current capacity (i.e. maximum size) of the buffer. */ |
128 /** Current capacity (i.e. maximum size) of the buffer. */ |
| 180 size_t capacity; |
129 size_t capacity; |
| |
130 /** Maximum capacity that this buffer may grow to. */ |
| |
131 size_t max_capacity; |
| 181 /** Current size of the buffer content. */ |
132 /** Current size of the buffer content. */ |
| 182 size_t size; |
133 size_t size; |
| 183 /** |
134 /** |
| 184 * Flag register for buffer features. |
135 * Flag register for buffer features. |
| 185 * @see #CX_BUFFER_DEFAULT |
136 * @see #CX_BUFFER_DEFAULT |
| 229 cx_attr_nonnull_arg(1) |
180 cx_attr_nonnull_arg(1) |
| 230 CX_EXPORT int cxBufferInit(CxBuffer *buffer, void *space, size_t capacity, |
181 CX_EXPORT int cxBufferInit(CxBuffer *buffer, void *space, size_t capacity, |
| 231 const CxAllocator *allocator, int flags); |
182 const CxAllocator *allocator, int flags); |
| 232 |
183 |
| 233 /** |
184 /** |
| 234 * Configures the buffer for flushing. |
|
| 235 * |
|
| 236 * Flushing can happen automatically when data is written |
|
| 237 * to the buffer (see cxBufferWrite()) or manually when |
|
| 238 * cxBufferFlush() is called. |
|
| 239 * |
|
| 240 * @param buffer the buffer |
|
| 241 * @param config the flush configuration |
|
| 242 * @retval zero success |
|
| 243 * @retval non-zero failure |
|
| 244 * @see cxBufferFlush() |
|
| 245 * @see cxBufferWrite() |
|
| 246 */ |
|
| 247 cx_attr_nonnull |
|
| 248 CX_EXPORT int cxBufferEnableFlushing(CxBuffer *buffer, CxBufferFlushConfig config); |
|
| 249 |
|
| 250 /** |
|
| 251 * Destroys the buffer contents. |
185 * Destroys the buffer contents. |
| 252 * |
186 * |
| 253 * Has no effect if the #CX_BUFFER_FREE_CONTENTS feature is not enabled. |
187 * Has no effect if the #CX_BUFFER_FREE_CONTENTS feature is not enabled. |
| 254 * If you want to free the memory of the entire buffer, use cxBufferFree(). |
188 * If you want to free the memory of the entire buffer, use cxBufferFree(). |
| 255 * |
189 * |
| 386 */ |
320 */ |
| 387 cx_attr_nonnull |
321 cx_attr_nonnull |
| 388 CX_EXPORT int cxBufferSeek(CxBuffer *buffer, off_t offset, int whence); |
322 CX_EXPORT int cxBufferSeek(CxBuffer *buffer, off_t offset, int whence); |
| 389 |
323 |
| 390 /** |
324 /** |
| |
325 * Discards items from the end of the buffer. |
| |
326 * |
| |
327 * When the current position points to a byte that gets discarded, |
| |
328 * the position is set to the buffer size. |
| |
329 * |
| |
330 * @param buffer the buffer |
| |
331 * @param size the size of one item |
| |
332 * @param nitems the number of items to discard |
| |
333 * @return the actual number of discarded items |
| |
334 */ |
| |
335 cx_attr_nonnull |
| |
336 CX_EXPORT size_t cxBufferPop(CxBuffer *buffer, size_t size, size_t nitems); |
| |
337 |
| |
338 /** |
| 391 * Clears the buffer by resetting the position and deleting the data. |
339 * Clears the buffer by resetting the position and deleting the data. |
| 392 * |
340 * |
| 393 * The data is deleted by zeroing it with a call to memset(). |
341 * The data is deleted by zeroing it with a call to memset(). |
| 394 * If you do not need that, you can use the faster cxBufferReset(). |
342 * If you do not need that, you can use the faster cxBufferReset(). |
| 395 * |
343 * |
| 423 * @retval false otherwise |
371 * @retval false otherwise |
| 424 */ |
372 */ |
| 425 cx_attr_nonnull cx_attr_nodiscard |
373 cx_attr_nonnull cx_attr_nodiscard |
| 426 CX_EXPORT bool cxBufferEof(const CxBuffer *buffer); |
374 CX_EXPORT bool cxBufferEof(const CxBuffer *buffer); |
| 427 |
375 |
| |
376 /** |
| |
377 * Ensures that the buffer has the required capacity. |
| |
378 * |
| |
379 * If the current capacity is not sufficient, the buffer will be extended. |
| |
380 * If the current capacity is larger, the buffer is shrunk and superfluous |
| |
381 * content is discarded. |
| |
382 * |
| |
383 * This function will reserve no more bytes than requested, in contrast to |
| |
384 * cxBufferMinimumCapacity(), which may reserve more bytes to improve the |
| |
385 * number of future necessary reallocations. |
| |
386 * |
| |
387 * @param buffer the buffer |
| |
388 * @param capacity the required capacity for this buffer |
| |
389 * @retval zero on success |
| |
390 * @retval non-zero on allocation failure |
| |
391 * @see cxBufferShrink() |
| |
392 * @see cxBufferMinimumCapacity() |
| |
393 */ |
| |
394 cx_attr_nonnull |
| |
395 CX_EXPORT int cxBufferReserve(CxBuffer *buffer, size_t capacity); |
| |
396 |
| |
397 /** |
| |
398 * Limits the buffer's capacity. |
| |
399 * |
| |
400 * If the current capacity is already larger, this function fails and returns |
| |
401 * non-zero. |
| |
402 * |
| |
403 * The capacity limit will affect auto-extension features, as well as future |
| |
404 * calls to cxBufferMinimumCapacity() and cxBufferReserve(). |
| |
405 * |
| |
406 * @param buffer the buffer |
| |
407 * @param capacity the maximum allowed capacity for this buffer |
| |
408 * @retval zero the limit is applied |
| |
409 * @retval non-zero the new limit is smaller than the current capacity |
| |
410 * @see cxBufferReserve() |
| |
411 * @see cxBufferMinimumCapacity() |
| |
412 */ |
| |
413 cx_attr_nonnull |
| |
414 CX_EXPORT int cxBufferMaximumCapacity(CxBuffer *buffer, size_t capacity); |
| 428 |
415 |
| 429 /** |
416 /** |
| 430 * Ensures that the buffer has a minimum capacity. |
417 * Ensures that the buffer has a minimum capacity. |
| 431 * |
418 * |
| 432 * If the current capacity is not sufficient, the buffer will be extended. |
419 * If the current capacity is not sufficient, the buffer will be generously |
| |
420 * extended. |
| 433 * |
421 * |
| 434 * The new capacity will be a power of two until the system's page size is reached. |
422 * The new capacity will be a power of two until the system's page size is reached. |
| 435 * Then, the new capacity will be a multiple of the page size. |
423 * Then, the new capacity will be a multiple of the page size. |
| 436 * |
424 * |
| 437 * @param buffer the buffer |
425 * @param buffer the buffer |
| 438 * @param capacity the minimum required capacity for this buffer |
426 * @param capacity the minimum required capacity for this buffer |
| 439 * @retval zero the capacity was already sufficient or successfully increased |
427 * @retval zero the capacity was already sufficient or successfully increased |
| 440 * @retval non-zero on allocation failure |
428 * @retval non-zero on allocation failure |
| |
429 * @see cxBufferMaximumCapacity() |
| |
430 * @see cxBufferReserve() |
| 441 * @see cxBufferShrink() |
431 * @see cxBufferShrink() |
| 442 */ |
432 */ |
| 443 cx_attr_nonnull |
433 cx_attr_nonnull |
| 444 CX_EXPORT int cxBufferMinimumCapacity(CxBuffer *buffer, size_t capacity); |
434 CX_EXPORT int cxBufferMinimumCapacity(CxBuffer *buffer, size_t capacity); |
| 445 |
435 |
| 455 * If the #CX_BUFFER_COPY_ON_WRITE or #CX_BUFFER_COPY_ON_EXTEND flag is set, |
445 * If the #CX_BUFFER_COPY_ON_WRITE or #CX_BUFFER_COPY_ON_EXTEND flag is set, |
| 456 * this function does nothing. |
446 * this function does nothing. |
| 457 * |
447 * |
| 458 * @param buffer the buffer |
448 * @param buffer the buffer |
| 459 * @param reserve the number of bytes that shall remain reserved |
449 * @param reserve the number of bytes that shall remain reserved |
| |
450 * @see cxBufferReserve() |
| 460 * @see cxBufferMinimumCapacity() |
451 * @see cxBufferMinimumCapacity() |
| 461 */ |
452 */ |
| 462 cx_attr_nonnull |
453 cx_attr_nonnull |
| 463 CX_EXPORT void cxBufferShrink(CxBuffer *buffer, size_t reserve); |
454 CX_EXPORT void cxBufferShrink(CxBuffer *buffer, size_t reserve); |
| 464 |
455 |
| 465 /** |
456 /** |
| 466 * Writes data to a CxBuffer. |
457 * Writes data to a CxBuffer. |
| 467 * |
458 * |
| 468 * If automatic flushing is not enabled, the data is simply written into the |
459 * If auto-extension is enabled, the buffer's capacity is automatically |
| 469 * buffer at the current position, and the position of the buffer is increased |
460 * increased when it is not large enough to hold all data. |
| 470 * by the number of bytes written. |
461 * By default, the capacity grows indefinitely, unless limited with |
| 471 * |
462 * cxBufferMaximumCapacity(). |
| 472 * If flushing is enabled and the buffer needs to flush, the data is flushed to |
463 * When auto-extension fails, this function writes no data and returns zero. |
| 473 * the target until the target signals that it cannot take more data by |
464 * |
| 474 * returning zero via the respective write function. In that case, the remaining |
465 * The position of the buffer is moved alongside the written data. |
| 475 * data in this buffer is shifted to the beginning of this buffer so that the |
|
| 476 * newly available space can be used to append as much data as possible. |
|
| 477 * |
|
| 478 * This function only stops writing more elements when the flush target and this |
|
| 479 * buffer are both incapable of taking more data or all data has been written. |
|
| 480 * |
|
| 481 * If, after flushing, the number of items that shall be written still exceeds |
|
| 482 * the capacity or flush threshold, this function tries to write all items directly |
|
| 483 * to the flush target, if possible. |
|
| 484 * |
|
| 485 * The number returned by this function is the number of elements from |
|
| 486 * @c ptr that could be written to either the flush target or the buffer. |
|
| 487 * That means it does @em not include the number of items that were already in |
|
| 488 * the buffer and were also flushed during the process. |
|
| 489 * |
|
| 490 * @attention |
|
| 491 * When @p size is larger than one and the contents of the buffer are not aligned |
|
| 492 * with @p size, flushing stops after all complete items have been flushed, leaving |
|
| 493 * the misaligned part in the buffer. |
|
| 494 * Afterward, this function only writes as many items as possible to the buffer. |
|
| 495 * |
466 * |
| 496 * @note The signature is compatible with the fwrite() family of functions. |
467 * @note The signature is compatible with the fwrite() family of functions. |
| 497 * |
468 * |
| 498 * @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 |
| 499 * @param size the length of one element |
470 * @param size the length of one element |
| 529 cx_attr_nonnull |
500 cx_attr_nonnull |
| 530 CX_EXPORT size_t cxBufferAppend(const void *ptr, size_t size, |
501 CX_EXPORT size_t cxBufferAppend(const void *ptr, size_t size, |
| 531 size_t nitems, CxBuffer *buffer); |
502 size_t nitems, CxBuffer *buffer); |
| 532 |
503 |
| 533 /** |
504 /** |
| 534 * Performs a single flush-run on the specified buffer. |
|
| 535 * |
|
| 536 * Does nothing when the position in the buffer is zero. |
|
| 537 * Otherwise, the data until the current position minus |
|
| 538 * one is considered for flushing. |
|
| 539 * Note carefully that flushing will never exceed the |
|
| 540 * current @em position, even when the size of the |
|
| 541 * buffer is larger than the current position. |
|
| 542 * |
|
| 543 * One flush run will try to flush @c blkmax many |
|
| 544 * blocks of size @c blksize until either the @p buffer |
|
| 545 * has no more data to flush or the write function |
|
| 546 * used for flushing returns zero. |
|
| 547 * |
|
| 548 * The buffer is shifted left for that many bytes |
|
| 549 * the flush operation has successfully flushed. |
|
| 550 * |
|
| 551 * @par Example 1 |
|
| 552 * Assume you have a buffer with size 340 and you are |
|
| 553 * at position 200. The flush configuration is |
|
| 554 * @c blkmax=4 and @c blksize=64 . |
|
| 555 * Assume that the entire flush operation is successful. |
|
| 556 * All 200 bytes on the left-hand-side from the current |
|
| 557 * position are written. |
|
| 558 * That means the size of the buffer is now 140 and the |
|
| 559 * position is zero. |
|
| 560 * |
|
| 561 * @par Example 2 |
|
| 562 * Same as Example 1, but now the @c blkmax is 1. |
|
| 563 * The size of the buffer is now 276, and the position is 136. |
|
| 564 * |
|
| 565 * @par Example 3 |
|
| 566 * Same as Example 1, but now assume the flush target |
|
| 567 * only accepts 100 bytes before returning zero. |
|
| 568 * That means the flush operation manages to flush |
|
| 569 * one complete block and one partial block, ending |
|
| 570 * up with a buffer with size 240 and position 100. |
|
| 571 * |
|
| 572 * @remark Just returns zero when flushing was not enabled with |
|
| 573 * cxBufferEnableFlushing(). |
|
| 574 * |
|
| 575 * @remark When the buffer uses copy-on-write, the memory |
|
| 576 * is copied first, before attempting any flush. |
|
| 577 * This is, however, considered an erroneous use of the |
|
| 578 * buffer because it makes little sense to put |
|
| 579 * readonly data into an UCX buffer for flushing instead |
|
| 580 * of writing it directly to the target. |
|
| 581 * |
|
| 582 * @param buffer the buffer |
|
| 583 * @return the number of successfully flushed bytes |
|
| 584 * @see cxBufferEnableFlushing() |
|
| 585 */ |
|
| 586 cx_attr_nonnull |
|
| 587 CX_EXPORT size_t cxBufferFlush(CxBuffer *buffer); |
|
| 588 |
|
| 589 /** |
|
| 590 * Reads data from a CxBuffer. |
505 * Reads data from a CxBuffer. |
| 591 * |
506 * |
| 592 * The position of the buffer is increased by the number of bytes read. |
507 * The position of the buffer is increased by the number of bytes read. |
| 593 * |
508 * |
| 594 * @note The signature is compatible with the fread() family of functions. |
509 * @note The signature is compatible with the fread() family of functions. |
| 608 /** |
523 /** |
| 609 * Writes a character to a buffer. |
524 * Writes a character to a buffer. |
| 610 * |
525 * |
| 611 * The least significant byte of the argument is written to the buffer. If the |
526 * The least significant byte of the argument is written to the buffer. If the |
| 612 * end of the buffer is reached and #CX_BUFFER_AUTO_EXTEND feature is enabled, |
527 * end of the buffer is reached and #CX_BUFFER_AUTO_EXTEND feature is enabled, |
| 613 * the buffer capacity is extended by cxBufferMinimumCapacity(). If the feature |
528 * the buffer capacity is extended, unless a limit set by |
| 614 * is disabled or the buffer extension fails, @c EOF is returned. |
529 * cxBufferMaximumCapacity() is reached. |
| |
530 * If the feature is disabled or the buffer extension fails, @c EOF is returned. |
| 615 * |
531 * |
| 616 * On successful writing, the position of the buffer is increased. |
532 * On successful writing, the position of the buffer is increased. |
| 617 * |
533 * |
| 618 * If you just want to write a null-terminator at the current position, you |
534 * If you just want to write a null-terminator at the current position, you |
| 619 * should use cxBufferTerminate() instead. |
535 * should use cxBufferTerminate() instead. |
| 620 * |
536 * |
| 621 * @param buffer the buffer to write to |
537 * @param buffer the buffer to write to |
| 622 * @param c the character to write |
538 * @param c the character to write |
| 623 * @return the byte that has been written or @c EOF when the end of the stream is |
539 * @return the byte that has been written or @c EOF when the end of the |
| 624 * reached, and automatic extension is not enabled or not possible |
540 * stream is reached, and automatic extension is not enabled or not possible |
| 625 * @see cxBufferTerminate() |
541 * @see cxBufferTerminate() |
| 626 */ |
542 */ |
| 627 cx_attr_nonnull |
543 cx_attr_nonnull |
| 628 CX_EXPORT int cxBufferPut(CxBuffer *buffer, int c); |
544 CX_EXPORT int cxBufferPut(CxBuffer *buffer, int c); |
| 629 |
545 |
| 630 /** |
546 /** |
| 631 * Writes a terminating zero to a buffer at the current position. |
547 * Writes a terminating zero to a buffer at the current position. |
| 632 * |
548 * |
| 633 * If successful, sets the size to the current position and advances the position by one. |
549 * If successful, also sets the size to the current position and shrinks the buffer. |
| 634 * |
550 * |
| 635 * The purpose of this function is to have the written data ready to be used as |
551 * The purpose of this function is to have the written data ready to be used as |
| 636 * a C string with the buffer's size being the length of that string. |
552 * a C string with the buffer's size being the length of that string. |
| 637 * |
553 * |
| 638 * @param buffer the buffer to write to |
554 * @param buffer the buffer to write to |
| 639 * @return zero, if the terminator could be written, non-zero otherwise |
555 * @return zero, if the terminator could be written, non-zero otherwise |
| |
556 * @see cxBufferShrink() |
| 640 */ |
557 */ |
| 641 cx_attr_nonnull |
558 cx_attr_nonnull |
| 642 CX_EXPORT int cxBufferTerminate(CxBuffer *buffer); |
559 CX_EXPORT int cxBufferTerminate(CxBuffer *buffer); |
| 643 |
560 |
| 644 /** |
561 /** |
| 645 * Writes a string to a buffer. |
562 * Internal function - do not use. |
| 646 * |
563 * |
| 647 * This is a convenience function for <code>cxBufferWrite(str, 1, strlen(str), buffer)</code>. |
564 * @param buffer the buffer |
| 648 * |
565 * @param str the string |
| 649 * @param buffer the buffer |
|
| 650 * @param str the zero-terminated string |
|
| 651 * @return the number of bytes written |
566 * @return the number of bytes written |
| 652 */ |
567 * @see cxBufferPutString() |
| 653 cx_attr_nonnull cx_attr_cstr_arg(2) |
568 */ |
| 654 CX_EXPORT size_t cxBufferPutString(CxBuffer *buffer, const char *str); |
569 cx_attr_nonnull |
| |
570 CX_EXPORT size_t cx_buffer_put_string(CxBuffer *buffer, cxstring str); |
| |
571 |
| |
572 /** |
| |
573 * Writes a string to a buffer with cxBufferWrite(). |
| |
574 * |
| |
575 * @param buffer (@c CxBuffer*) the buffer |
| |
576 * @param str (any string) the zero-terminated string |
| |
577 * @return (@c size_t) the number of bytes written |
| |
578 * @see cxBufferWrite() |
| |
579 * @see cx_strcast() |
| |
580 */ |
| |
581 #define cxBufferPutString(buffer, str) cx_buffer_put_string(buffer, cx_strcast(str)) |
| |
582 |
| |
583 /** |
| |
584 * Internal function - do not use. |
| |
585 * |
| |
586 * @param buffer the buffer |
| |
587 * @param str the string |
| |
588 * @return the number of bytes written |
| |
589 * @see cxBufferPutString() |
| |
590 */ |
| |
591 cx_attr_nonnull |
| |
592 CX_EXPORT size_t cx_buffer_append_string(CxBuffer *buffer, cxstring str); |
| |
593 |
| |
594 /** |
| |
595 * Appends a string to a buffer with cxBufferAppend(). |
| |
596 * |
| |
597 * @param buffer (@c CxBuffer*) the buffer |
| |
598 * @param str (any string) the zero-terminated string |
| |
599 * @return (@c size_t) the number of bytes written |
| |
600 * @see cxBufferAppend() |
| |
601 * @see cx_strcast() |
| |
602 */ |
| |
603 #define cxBufferAppendString(buffer, str) cx_buffer_append_string(buffer, cx_strcast(str)) |
| 655 |
604 |
| 656 /** |
605 /** |
| 657 * Gets a character from a buffer. |
606 * Gets a character from a buffer. |
| 658 * |
607 * |
| 659 * The current position of the buffer is increased after a successful read. |
608 * The current position of the buffer is increased after a successful read. |