--- a/src/cx/buffer.h Sun Dec 15 15:23:29 2024 +0100 +++ b/src/cx/buffer.h Wed Dec 18 15:35:42 2024 +0100 @@ -60,14 +60,25 @@ /** * If this flag is enabled, the buffer will automatically free its contents when destroyed. + * + * Do NOT set this flag together with #CX_BUFFER_COPY_ON_WRITE. It will be automatically + * set when the copy-on-write operations is performed. */ #define CX_BUFFER_FREE_CONTENTS 0x01 /** - * If this flag is enabled, the buffer will automatically extends its capacity. + * If this flag is enabled, the buffer will automatically extend its capacity. */ #define CX_BUFFER_AUTO_EXTEND 0x02 +/** + * If this flag is enabled, the buffer will allocate new memory when written to. + * + * The current contents of the buffer will be copied to the new memory and the flag + * will be cleared while the #CX_BUFFER_FREE_CONTENTS flag will be set automatically. + */ +#define CX_BUFFER_COPY_ON_WRITE 0x04 + /** Structure for the UCX buffer data. */ typedef struct { /** A pointer to the buffer contents. */ @@ -128,6 +139,7 @@ * @see #CX_BUFFER_DEFAULT * @see #CX_BUFFER_FREE_CONTENTS * @see #CX_BUFFER_AUTO_EXTEND + * @see #CX_BUFFER_COPY_ON_WRITE */ int flags; } cx_buffer_s; @@ -140,9 +152,15 @@ /** * Initializes a fresh buffer. * + * You may also provide a read-only \p space, in which case + * you will need to cast the pointer, and you should set the + * #CX_BUFFER_COPY_ON_WRITE flag. + * * \note You may provide \c NULL as argument for \p space. * Then this function will allocate the space and enforce - * the #CX_BUFFER_FREE_CONTENTS flag. + * the #CX_BUFFER_FREE_CONTENTS flag. In that case, specifying + * copy-on-write should be avoided, because the allocated + * space will be leaking after the copy-on-write operation. * * @param buffer the buffer to initialize * @param space pointer to the memory area, or \c NULL to allocate @@ -192,6 +210,10 @@ /** * Allocates and initializes a fresh buffer. * + * You may also provide a read-only \p space, in which case + * you will need to cast the pointer, and you should set the + * #CX_BUFFER_COPY_ON_WRITE flag. + * * \note You may provide \c NULL as argument for \p space. * Then this function will allocate the space and enforce * the #CX_BUFFER_FREE_CONTENTS flag. @@ -246,7 +268,7 @@ * * @param buffer the buffer * @param shift the shift offset (negative means left shift) - * @return 0 on success, non-zero if a required auto-extension fails + * @return 0 on success, non-zero if a required auto-extension or copy-on-write fails */ cx_attr_nonnull int cxBufferShift( @@ -260,7 +282,7 @@ * * @param buffer the buffer * @param shift the shift offset - * @return 0 on success, non-zero if a required auto-extension fails + * @return 0 on success, non-zero if a required auto-extension or copy-on-write fails * @see cxBufferShift() */ cx_attr_nonnull @@ -273,12 +295,9 @@ * Shifts the buffer to the left. * See cxBufferShift() for details. * - * \note Since a left shift cannot fail due to memory allocation problems, this - * function always returns zero. - * * @param buffer the buffer * @param shift the positive shift offset - * @return always zero + * @return usually zero, except the buffer uses copy-on-write and the allocation fails * @see cxBufferShift() */ cx_attr_nonnull @@ -320,6 +339,9 @@ * The data is deleted by zeroing it with a call to memset(). * If you do not need that, you can use the faster cxBufferReset(). * + * \note If the #CX_BUFFER_COPY_ON_WRITE flag is set, this function + * will not erase the data and behave exactly as cxBufferReset(). + * * @param buffer the buffer to be cleared * @see cxBufferReset() */