src/cx/buffer.h

changeset 1675
36c0fb2b60b2
parent 1654
5ab3fe0b7859
equal deleted inserted replaced
1674:8b0f162ac88e 1675:36c0fb2b60b2
47 #define UCX_BUFFER_H 47 #define UCX_BUFFER_H
48 48
49 #include "common.h" 49 #include "common.h"
50 #include "allocator.h" 50 #include "allocator.h"
51 #include "string.h" 51 #include "string.h"
52
53 #ifdef __cplusplus
54 extern "C" {
55 #endif
56 52
57 /** 53 /**
58 * No buffer features enabled (all flags cleared). 54 * No buffer features enabled (all flags cleared).
59 */ 55 */
60 #define CX_BUFFER_DEFAULT 0x00 56 #define CX_BUFFER_DEFAULT 0x00
175 * new memory 171 * new memory
176 * @param capacity the capacity of the buffer 172 * @param capacity the capacity of the buffer
177 * @param flags buffer features (see cx_buffer_s.flags) 173 * @param flags buffer features (see cx_buffer_s.flags)
178 * @return zero on success, non-zero if a required allocation failed 174 * @return zero on success, non-zero if a required allocation failed
179 */ 175 */
180 cx_attr_nonnull_arg(1) 176 CX_EXTERN CX_NONNULL_ARG(1)
181 CX_EXPORT int cxBufferInit(CxBuffer *buffer, const CxAllocator *allocator, 177 int cxBufferInit(CxBuffer *buffer, const CxAllocator *allocator,
182 void *space, size_t capacity, int flags); 178 void *space, size_t capacity, int flags);
183 179
184 /** 180 /**
185 * Destroys the buffer contents. 181 * Destroys the buffer contents.
186 * 182 *
188 * If you want to free the memory of the entire buffer, use cxBufferFree(). 184 * If you want to free the memory of the entire buffer, use cxBufferFree().
189 * 185 *
190 * @param buffer the buffer which contents shall be destroyed 186 * @param buffer the buffer which contents shall be destroyed
191 * @see cxBufferInit() 187 * @see cxBufferInit()
192 */ 188 */
193 cx_attr_nonnull 189 CX_EXTERN CX_NONNULL
194 CX_EXPORT void cxBufferDestroy(CxBuffer *buffer); 190 void cxBufferDestroy(CxBuffer *buffer);
195 191
196 /** 192 /**
197 * Deallocates the buffer. 193 * Deallocates the buffer.
198 * 194 *
199 * If the #CX_BUFFER_FREE_CONTENTS feature is enabled, this function also destroys 195 * If the #CX_BUFFER_FREE_CONTENTS feature is enabled, this function also destroys
200 * the contents. If you @em only want to destroy the contents, use cxBufferDestroy(). 196 * the contents. If you @em only want to destroy the contents, use cxBufferDestroy().
201 * 197 *
202 * @param buffer the buffer to deallocate 198 * @param buffer the buffer to deallocate
203 * @see cxBufferCreate() 199 * @see cxBufferCreate()
204 */ 200 */
205 CX_EXPORT void cxBufferFree(CxBuffer *buffer); 201 CX_EXTERN
202 void cxBufferFree(CxBuffer *buffer);
206 203
207 /** 204 /**
208 * Allocates and initializes a fresh buffer. 205 * Allocates and initializes a fresh buffer.
209 * 206 *
210 * You may also provide a read-only @p space, in which case 207 * You may also provide a read-only @p space, in which case
226 * new memory 223 * new memory
227 * @param capacity the capacity of the buffer 224 * @param capacity the capacity of the buffer
228 * @param flags buffer features (see cx_buffer_s.flags) 225 * @param flags buffer features (see cx_buffer_s.flags)
229 * @return a pointer to the buffer on success, @c NULL if a required allocation failed 226 * @return a pointer to the buffer on success, @c NULL if a required allocation failed
230 */ 227 */
231 cx_attr_malloc cx_attr_dealloc(cxBufferFree, 1) cx_attr_nodiscard 228 CX_EXTERN CX_MALLOC CX_DEALLOC(cxBufferFree, 1) CX_NODISCARD
232 CX_EXPORT CxBuffer *cxBufferCreate(const CxAllocator *allocator, void *space, 229 CxBuffer *cxBufferCreate(const CxAllocator *allocator, void *space,
233 size_t capacity, int flags); 230 size_t capacity, int flags);
234 231
235 /** 232 /**
236 * Shifts the contents of the buffer by the given offset. 233 * Shifts the contents of the buffer by the given offset.
237 * 234 *
266 * @retval zero success 263 * @retval zero success
267 * @retval non-zero if a required auto-extension or copy-on-write fails 264 * @retval non-zero if a required auto-extension or copy-on-write fails
268 * @see cxBufferShiftLeft() 265 * @see cxBufferShiftLeft()
269 * @see cxBufferShiftRight() 266 * @see cxBufferShiftRight()
270 */ 267 */
271 cx_attr_nonnull 268 CX_EXTERN CX_NONNULL
272 CX_EXPORT int cxBufferShift(CxBuffer *buffer, off_t shift); 269 int cxBufferShift(CxBuffer *buffer, off_t shift);
273 270
274 /** 271 /**
275 * Shifts the buffer to the right. 272 * Shifts the buffer to the right.
276 * See cxBufferShift() for details. 273 * See cxBufferShift() for details.
277 * 274 *
279 * @param shift the shift offset 276 * @param shift the shift offset
280 * @retval zero success 277 * @retval zero success
281 * @retval non-zero if a required auto-extension or copy-on-write fails 278 * @retval non-zero if a required auto-extension or copy-on-write fails
282 * @see cxBufferShift() 279 * @see cxBufferShift()
283 */ 280 */
284 cx_attr_nonnull 281 CX_EXTERN CX_NONNULL
285 CX_EXPORT int cxBufferShiftRight(CxBuffer *buffer, size_t shift); 282 int cxBufferShiftRight(CxBuffer *buffer, size_t shift);
286 283
287 /** 284 /**
288 * Shifts the buffer to the left. 285 * Shifts the buffer to the left.
289 * See cxBufferShift() for details. 286 * See cxBufferShift() for details.
290 * 287 *
292 * @param shift the positive shift offset 289 * @param shift the positive shift offset
293 * @retval zero success 290 * @retval zero success
294 * @retval non-zero if the buffer uses copy-on-write and the allocation fails 291 * @retval non-zero if the buffer uses copy-on-write and the allocation fails
295 * @see cxBufferShift() 292 * @see cxBufferShift()
296 */ 293 */
297 cx_attr_nonnull 294 CX_EXTERN CX_NONNULL
298 CX_EXPORT int cxBufferShiftLeft(CxBuffer *buffer, size_t shift); 295 int cxBufferShiftLeft(CxBuffer *buffer, size_t shift);
299 296
300 297
301 /** 298 /**
302 * Moves the position of the buffer. 299 * Moves the position of the buffer.
303 * 300 *
316 * @param whence one of @c SEEK_SET, @c SEEK_CUR or @c SEEK_END 313 * @param whence one of @c SEEK_SET, @c SEEK_CUR or @c SEEK_END
317 * @retval zero success 314 * @retval zero success
318 * @retval non-zero if the position is invalid 315 * @retval non-zero if the position is invalid
319 * 316 *
320 */ 317 */
321 cx_attr_nonnull 318 CX_EXTERN CX_NONNULL
322 CX_EXPORT int cxBufferSeek(CxBuffer *buffer, off_t offset, int whence); 319 int cxBufferSeek(CxBuffer *buffer, off_t offset, int whence);
323 320
324 /** 321 /**
325 * Discards items from the end of the buffer. 322 * Discards items from the end of the buffer.
326 * 323 *
327 * When the current position points to a byte that gets discarded, 324 * When the current position points to a byte that gets discarded,
330 * @param buffer the buffer 327 * @param buffer the buffer
331 * @param size the size of one item 328 * @param size the size of one item
332 * @param nitems the number of items to discard 329 * @param nitems the number of items to discard
333 * @return the actual number of discarded items 330 * @return the actual number of discarded items
334 */ 331 */
335 cx_attr_nonnull 332 CX_EXTERN CX_NONNULL
336 CX_EXPORT size_t cxBufferPop(CxBuffer *buffer, size_t size, size_t nitems); 333 size_t cxBufferPop(CxBuffer *buffer, size_t size, size_t nitems);
337 334
338 /** 335 /**
339 * Clears the buffer by resetting the position and deleting the data. 336 * Clears the buffer by resetting the position and deleting the data.
340 * 337 *
341 * The data is deleted by zeroing it with a call to memset(). 338 * The data is deleted by zeroing it with a call to memset().
345 * will not erase the data and behave exactly as cxBufferReset(). 342 * will not erase the data and behave exactly as cxBufferReset().
346 * 343 *
347 * @param buffer the buffer to be cleared 344 * @param buffer the buffer to be cleared
348 * @see cxBufferReset() 345 * @see cxBufferReset()
349 */ 346 */
350 cx_attr_nonnull 347 CX_EXTERN CX_NONNULL
351 CX_EXPORT void cxBufferClear(CxBuffer *buffer); 348 void cxBufferClear(CxBuffer *buffer);
352 349
353 /** 350 /**
354 * Resets the buffer by resetting the position and size to zero. 351 * Resets the buffer by resetting the position and size to zero.
355 * 352 *
356 * The data in the buffer is not deleted. If you need a safe 353 * The data in the buffer is not deleted. If you need a safe
357 * reset of the buffer, use cxBufferClear(). 354 * reset of the buffer, use cxBufferClear().
358 * 355 *
359 * @param buffer the buffer to be cleared 356 * @param buffer the buffer to be cleared
360 * @see cxBufferClear() 357 * @see cxBufferClear()
361 */ 358 */
362 cx_attr_nonnull 359 CX_EXTERN CX_NONNULL
363 CX_EXPORT void cxBufferReset(CxBuffer *buffer); 360 void cxBufferReset(CxBuffer *buffer);
364 361
365 /** 362 /**
366 * Tests, if the buffer position has exceeded the buffer size. 363 * Tests, if the buffer position has exceeded the buffer size.
367 * 364 *
368 * @param buffer the buffer to test 365 * @param buffer the buffer to test
369 * @retval true if the current buffer position has exceeded the last 366 * @retval true if the current buffer position has exceeded the last
370 * byte of the buffer's contents 367 * byte of the buffer's contents
371 * @retval false otherwise 368 * @retval false otherwise
372 */ 369 */
373 cx_attr_nonnull cx_attr_nodiscard 370 CX_EXTERN CX_NONNULL CX_NODISCARD
374 CX_EXPORT bool cxBufferEof(const CxBuffer *buffer); 371 bool cxBufferEof(const CxBuffer *buffer);
375 372
376 /** 373 /**
377 * Ensures that the buffer has the required capacity. 374 * Ensures that the buffer has the required capacity.
378 * 375 *
379 * If the current capacity is not sufficient, the buffer will be extended. 376 * If the current capacity is not sufficient, the buffer will be extended.
389 * @retval zero on success 386 * @retval zero on success
390 * @retval non-zero on allocation failure 387 * @retval non-zero on allocation failure
391 * @see cxBufferShrink() 388 * @see cxBufferShrink()
392 * @see cxBufferMinimumCapacity() 389 * @see cxBufferMinimumCapacity()
393 */ 390 */
394 cx_attr_nonnull 391 CX_EXTERN CX_NONNULL
395 CX_EXPORT int cxBufferReserve(CxBuffer *buffer, size_t capacity); 392 int cxBufferReserve(CxBuffer *buffer, size_t capacity);
396 393
397 /** 394 /**
398 * Limits the buffer's capacity. 395 * Limits the buffer's capacity.
399 * 396 *
400 * If the current capacity is already larger, this function fails and returns 397 * If the current capacity is already larger, this function fails and returns
408 * @retval zero the limit is applied 405 * @retval zero the limit is applied
409 * @retval non-zero the new limit is smaller than the current capacity 406 * @retval non-zero the new limit is smaller than the current capacity
410 * @see cxBufferReserve() 407 * @see cxBufferReserve()
411 * @see cxBufferMinimumCapacity() 408 * @see cxBufferMinimumCapacity()
412 */ 409 */
413 cx_attr_nonnull 410 CX_EXTERN CX_NONNULL
414 CX_EXPORT int cxBufferMaximumCapacity(CxBuffer *buffer, size_t capacity); 411 int cxBufferMaximumCapacity(CxBuffer *buffer, size_t capacity);
415 412
416 /** 413 /**
417 * Ensures that the buffer has a minimum capacity. 414 * Ensures that the buffer has a minimum capacity.
418 * 415 *
419 * If the current capacity is not sufficient, the buffer will be generously 416 * If the current capacity is not sufficient, the buffer will be generously
428 * @retval non-zero on allocation failure 425 * @retval non-zero on allocation failure
429 * @see cxBufferMaximumCapacity() 426 * @see cxBufferMaximumCapacity()
430 * @see cxBufferReserve() 427 * @see cxBufferReserve()
431 * @see cxBufferShrink() 428 * @see cxBufferShrink()
432 */ 429 */
433 cx_attr_nonnull 430 CX_EXTERN CX_NONNULL
434 CX_EXPORT int cxBufferMinimumCapacity(CxBuffer *buffer, size_t capacity); 431 int cxBufferMinimumCapacity(CxBuffer *buffer, size_t capacity);
435 432
436 /** 433 /**
437 * Shrinks the capacity of the buffer to fit its current size. 434 * Shrinks the capacity of the buffer to fit its current size.
438 * 435 *
439 * If @p reserve is larger than zero, the buffer is shrunk to its size plus 436 * If @p reserve is larger than zero, the buffer is shrunk to its size plus
448 * @param buffer the buffer 445 * @param buffer the buffer
449 * @param reserve the number of bytes that shall remain reserved 446 * @param reserve the number of bytes that shall remain reserved
450 * @see cxBufferReserve() 447 * @see cxBufferReserve()
451 * @see cxBufferMinimumCapacity() 448 * @see cxBufferMinimumCapacity()
452 */ 449 */
453 cx_attr_nonnull 450 CX_EXTERN CX_NONNULL
454 CX_EXPORT void cxBufferShrink(CxBuffer *buffer, size_t reserve); 451 void cxBufferShrink(CxBuffer *buffer, size_t reserve);
455 452
456 /** 453 /**
457 * Writes data to a CxBuffer. 454 * Writes data to a CxBuffer.
458 * 455 *
459 * If auto-extension is enabled, the buffer's capacity is automatically 456 * If auto-extension is enabled, the buffer's capacity is automatically
472 * @param buffer the CxBuffer to write to 469 * @param buffer the CxBuffer to write to
473 * @return the total count of elements written 470 * @return the total count of elements written
474 * @see cxBufferAppend() 471 * @see cxBufferAppend()
475 * @see cxBufferRead() 472 * @see cxBufferRead()
476 */ 473 */
477 cx_attr_nonnull 474 CX_EXTERN CX_NONNULL
478 CX_EXPORT size_t cxBufferWrite(const void *ptr, size_t size, 475 size_t cxBufferWrite(const void *ptr, size_t size,
479 size_t nitems, CxBuffer *buffer); 476 size_t nitems, CxBuffer *buffer);
480 477
481 /** 478 /**
482 * Appends data to a CxBuffer. 479 * Appends data to a CxBuffer.
483 * 480 *
495 * @param buffer the CxBuffer to write to 492 * @param buffer the CxBuffer to write to
496 * @return the total count of elements written 493 * @return the total count of elements written
497 * @see cxBufferWrite() 494 * @see cxBufferWrite()
498 * @see cxBufferRead() 495 * @see cxBufferRead()
499 */ 496 */
500 cx_attr_nonnull 497 CX_EXTERN CX_NONNULL
501 CX_EXPORT size_t cxBufferAppend(const void *ptr, size_t size, 498 size_t cxBufferAppend(const void *ptr, size_t size,
502 size_t nitems, CxBuffer *buffer); 499 size_t nitems, CxBuffer *buffer);
503 500
504 /** 501 /**
505 * Reads data from a CxBuffer. 502 * Reads data from a CxBuffer.
506 * 503 *
514 * @param buffer the CxBuffer to read from 511 * @param buffer the CxBuffer to read from
515 * @return the total number of elements read 512 * @return the total number of elements read
516 * @see cxBufferWrite() 513 * @see cxBufferWrite()
517 * @see cxBufferAppend() 514 * @see cxBufferAppend()
518 */ 515 */
519 cx_attr_nonnull 516 CX_EXTERN CX_NONNULL
520 CX_EXPORT size_t cxBufferRead(void *ptr, size_t size, 517 size_t cxBufferRead(void *ptr, size_t size,
521 size_t nitems, CxBuffer *buffer); 518 size_t nitems, CxBuffer *buffer);
522 519
523 /** 520 /**
524 * Writes a character to a buffer. 521 * Writes a character to a buffer.
525 * 522 *
538 * @param c the character to write 535 * @param c the character to write
539 * @return the byte that has been written or @c EOF when the end of the 536 * @return the byte that has been written or @c EOF when the end of the
540 * stream is reached, and automatic extension is not enabled or not possible 537 * stream is reached, and automatic extension is not enabled or not possible
541 * @see cxBufferTerminate() 538 * @see cxBufferTerminate()
542 */ 539 */
543 cx_attr_nonnull 540 CX_EXTERN CX_NONNULL
544 CX_EXPORT int cxBufferPut(CxBuffer *buffer, int c); 541 int cxBufferPut(CxBuffer *buffer, int c);
545 542
546 /** 543 /**
547 * Writes a terminating zero to a buffer at the current position. 544 * Writes a terminating zero to a buffer at the current position.
548 * 545 *
549 * If successful, also sets the size to the current position and shrinks the buffer. 546 * If successful, also sets the size to the current position and shrinks the buffer.
553 * 550 *
554 * @param buffer the buffer to write to 551 * @param buffer the buffer to write to
555 * @return zero, if the terminator could be written, non-zero otherwise 552 * @return zero, if the terminator could be written, non-zero otherwise
556 * @see cxBufferShrink() 553 * @see cxBufferShrink()
557 */ 554 */
558 cx_attr_nonnull 555 CX_EXTERN CX_NONNULL
559 CX_EXPORT int cxBufferTerminate(CxBuffer *buffer); 556 int cxBufferTerminate(CxBuffer *buffer);
560 557
561 /** 558 /**
562 * Internal function - do not use. 559 * Internal function - do not use.
563 * 560 *
564 * @param buffer the buffer 561 * @param buffer the buffer
565 * @param str the string 562 * @param str the string
566 * @return the number of bytes written 563 * @return the number of bytes written
567 * @see cxBufferPutString() 564 * @see cxBufferPutString()
568 */ 565 */
569 cx_attr_nonnull 566 CX_EXTERN CX_NONNULL
570 CX_EXPORT size_t cx_buffer_put_string(CxBuffer *buffer, cxstring str); 567 size_t cx_buffer_put_string(CxBuffer *buffer, cxstring str);
571 568
572 /** 569 /**
573 * Writes a string to a buffer with cxBufferWrite(). 570 * Writes a string to a buffer with cxBufferWrite().
574 * 571 *
575 * @param buffer (@c CxBuffer*) the buffer 572 * @param buffer (@c CxBuffer*) the buffer
586 * @param buffer the buffer 583 * @param buffer the buffer
587 * @param str the string 584 * @param str the string
588 * @return the number of bytes written 585 * @return the number of bytes written
589 * @see cxBufferPutString() 586 * @see cxBufferPutString()
590 */ 587 */
591 cx_attr_nonnull 588 CX_EXTERN CX_NONNULL
592 CX_EXPORT size_t cx_buffer_append_string(CxBuffer *buffer, cxstring str); 589 size_t cx_buffer_append_string(CxBuffer *buffer, cxstring str);
593 590
594 /** 591 /**
595 * Appends a string to a buffer with cxBufferAppend(). 592 * Appends a string to a buffer with cxBufferAppend().
596 * 593 *
597 * @param buffer (@c CxBuffer*) the buffer 594 * @param buffer (@c CxBuffer*) the buffer
608 * The current position of the buffer is increased after a successful read. 605 * The current position of the buffer is increased after a successful read.
609 * 606 *
610 * @param buffer the buffer to read from 607 * @param buffer the buffer to read from
611 * @return the character or @c EOF, if the end of the buffer is reached 608 * @return the character or @c EOF, if the end of the buffer is reached
612 */ 609 */
613 cx_attr_nonnull 610 CX_EXTERN CX_NONNULL
614 CX_EXPORT int cxBufferGet(CxBuffer *buffer); 611 int cxBufferGet(CxBuffer *buffer);
615 612
616 /** 613 /**
617 * Gets the data in a buffer as a @c cxstring. 614 * Gets the data in a buffer as a @c cxstring.
618 * 615 *
619 * @param buffer the buffer 616 * @param buffer the buffer
620 * @return the data in the buffer interpreted as a @c cxstring 617 * @return the data in the buffer interpreted as a @c cxstring
621 */ 618 */
622 CX_INLINE cxstring cx_bstr(CxBuffer *buffer) { 619 CX_NONNULL CX_INLINE
620 cxstring cx_bstr(CxBuffer *buffer) {
623 return cx_strn(buffer->space, buffer->size); 621 return cx_strn(buffer->space, buffer->size);
624 } 622 }
625 623
626 /** 624 /**
627 * Gets the data in a buffer as a @c cxmutstr. 625 * Gets the data in a buffer as a @c cxmutstr.
628 * 626 *
629 * @param buffer the buffer 627 * @param buffer the buffer
630 * @return the data in the buffer interpreted as a @c cxmutstr 628 * @return the data in the buffer interpreted as a @c cxmutstr
631 */ 629 */
632 CX_INLINE cxmutstr cx_bstr_m(CxBuffer *buffer) { 630 CX_NONNULL CX_INLINE
631 cxmutstr cx_bstr_m(CxBuffer *buffer) {
633 return cx_mutstrn(buffer->space, buffer->size); 632 return cx_mutstrn(buffer->space, buffer->size);
634 } 633 }
635 634
636 #ifdef __cplusplus
637 }
638 #endif
639
640 #endif // UCX_BUFFER_H 635 #endif // UCX_BUFFER_H

mercurial