| 113 |
113 |
| 114 The above functions destroy the buffer and deallocate the buffer's memory when the `CX_BUFFER_FREE_CONTENTS` flag is set. |
114 The above functions destroy the buffer and deallocate the buffer's memory when the `CX_BUFFER_FREE_CONTENTS` flag is set. |
| 115 |
115 |
| 116 The function `cxBufferDestroy()` is to be used when the buffer was initialized with `cxBufferInit()`, |
116 The function `cxBufferDestroy()` is to be used when the buffer was initialized with `cxBufferInit()`, |
| 117 and the function `cxBufferFree()` is to be used when the buffer was created with `cxBufferCreate()`. |
117 and the function `cxBufferFree()` is to be used when the buffer was created with `cxBufferCreate()`. |
| 118 The only difference is, that `cxBufferFree()` additionally deallocates the memory of the `CxBuffer` structure. |
118 The only difference is that `cxBufferFree()` additionally deallocates the memory of the `CxBuffer` structure. |
| 119 |
119 |
| 120 ## Capacity Management |
120 ## Capacity Management |
| 121 |
121 |
| 122 ```C |
122 ```C |
| 123 #include <cx/buffer.h> |
123 #include <cx/buffer.h> |
| 150 plus a number of `reserve` bytes. |
150 plus a number of `reserve` bytes. |
| 151 If the current capacity is not larger than the size plus the reserve bytes, the function will do nothing. |
151 If the current capacity is not larger than the size plus the reserve bytes, the function will do nothing. |
| 152 |
152 |
| 153 > If the buffer is in a copy-on-write state, `cxBufferMinimumCapacity()` will perform the copy-on-write action |
153 > If the buffer is in a copy-on-write state, `cxBufferMinimumCapacity()` will perform the copy-on-write action |
| 154 > before reallocating the space. |
154 > before reallocating the space. |
| 155 > The function `cxBufferShrink()` on the other hand does _nothing_ when the buffer is in a copy-on-write state, |
155 > The function `cxBufferShrink()` on the other hand, does _nothing_ when the buffer is in a copy-on-write state, |
| 156 > because it makes little sense to copy the memory just to have it in a smaller memory region. |
156 > because it makes little sense to copy the memory just to have it in a smaller memory region. |
| 157 |
157 |
| 158 ## Write |
158 ## Write |
| 159 |
159 |
| 160 ```C |
160 ```C |
| 180 |
180 |
| 181 When the capacity of the buffer is not sufficient and the `CX_BUFFER_AUTO_EXTEND` is not set in the buffer, |
181 When the capacity of the buffer is not sufficient and the `CX_BUFFER_AUTO_EXTEND` is not set in the buffer, |
| 182 items that do not fit into the buffer are discarded. |
182 items that do not fit into the buffer are discarded. |
| 183 The function then returns the actual number of items successfully written. |
183 The function then returns the actual number of items successfully written. |
| 184 This equals the number of bytes if and only if `size=1`. |
184 This equals the number of bytes if and only if `size=1`. |
| 185 If `CX_BUFFER_AUTO_EXTEND` is set, the buffer is grown to it's maximum capacity |
185 If `CX_BUFFER_AUTO_EXTEND` is set, the buffer is grown to its maximum capacity |
| 186 (see `cxBufferMaximumCapacity()` in [](#capacity-management)). |
186 (see `cxBufferMaximumCapacity()` in [](#capacity-management)). |
| 187 In case the allocation for auto-extension fails, the function immediately returns zero and does not write any data. |
187 In case the allocation for auto-extension fails, the function immediately returns zero and does not write any data. |
| 188 |
188 |
| 189 The function `cxBufferPut()` is a `putc()`-like wrapper for `cxBufferWrite()` which writes the character `c`, |
189 The function `cxBufferPut()` is a `putc()`-like wrapper for `cxBufferWrite()` which writes the character `c`, |
| 190 converted to an `unsigned char` to the buffer. |
190 converted to an `unsigned char` to the buffer. |
| 198 and cause the _size_ of the buffer to grow, if necessary, to contain all written bytes. |
198 and cause the _size_ of the buffer to grow, if necessary, to contain all written bytes. |
| 199 On the other hand, `cxBufferTerminate()` writes a zero-byte at the current position and shrinks the buffer, |
199 On the other hand, `cxBufferTerminate()` writes a zero-byte at the current position and shrinks the buffer, |
| 200 effectively creating a zero-terminated string whose size equals the buffer size. |
200 effectively creating a zero-terminated string whose size equals the buffer size. |
| 201 |
201 |
| 202 > If you use cxBufferTerminate() on a buffer with the `CX_BUFFER_COPY_ON_EXTEND` flag set, the shrink operation is skipped. |
202 > If you use cxBufferTerminate() on a buffer with the `CX_BUFFER_COPY_ON_EXTEND` flag set, the shrink operation is skipped. |
| 203 > Using `cxBufferTerminate()` on a buffer with the `CX_BUFFER_COPY_ON_WRITE` flag set, will copy the entire memory just to add the zero-terminator. |
203 > Using `cxBufferTerminate()` on a buffer with the `CX_BUFFER_COPY_ON_WRITE` flag set will copy the entire memory just to add the zero-terminator. |
| 204 |
204 |
| 205 The function `cxBufferAppend()` writes the data to the end of the buffer (given by its size) regardless of the current position, |
205 The function `cxBufferAppend()` writes the data to the end of the buffer (given by its size) regardless of the current position, |
| 206 and it also does _not_ advance the position. |
206 and it also does _not_ advance the position. |
| 207 |
207 |
| 208 ## Read |
208 ## Read |
| 220 |
220 |
| 221 The function `cxBufferRead()` reads `nitems` number of items of `size` bytes each from the `buffer` |
221 The function `cxBufferRead()` reads `nitems` number of items of `size` bytes each from the `buffer` |
| 222 and stores them into the memory pointed to by `ptr`, which must be large enough to hold the contents. |
222 and stores them into the memory pointed to by `ptr`, which must be large enough to hold the contents. |
| 223 The function returns the actual bytes read, which might be lower if the desired number of items is not available. |
223 The function returns the actual bytes read, which might be lower if the desired number of items is not available. |
| 224 |
224 |
| 225 The function `cxBufferGet()` is a `fgetc()`-like function which returns the next byte in the buffer converted to an `int`. |
225 The function `cxBufferGet()` is an `fgetc()`-like function which returns the next byte in the buffer converted to an `int`. |
| 226 Similar to `fgetc()` it returns `EOF` when there are no more bytes in the buffer. |
226 Similar to `fgetc()` it returns `EOF` when there are no more bytes in the buffer. |
| 227 |
227 |
| 228 When all bytes from the buffer have been read, the function `cxBufferEof()` returns true. |
228 When all bytes from the buffer have been read, the function `cxBufferEof()` returns true. |
| 229 |
229 |
| 230 All read functions advance the position in the buffer by the number of read bytes. |
230 All read functions advance the position in the buffer by the number of read bytes. |
| 231 |
231 |
| 232 > When you want to read from a buffer that you previously used for writing, do not forget to set the position |
232 > When you want to read from a buffer that you previously used for writing, remember to set the position |
| 233 > in the buffer to zero, e.g. by calling `cxBufferSeek()`. |
233 > in the buffer to zero, e.g., by calling `cxBufferSeek()`. |
| 234 |
234 |
| 235 ## Reset and Clear |
235 ## Reset and Clear |
| 236 |
236 |
| 237 ```C |
237 ```C |
| 238 #include <cx/buffer.h> |
238 #include <cx/buffer.h> |
| 243 |
243 |
| 244 size_t cxBufferPop(CxBuffer *buffer, |
244 size_t cxBufferPop(CxBuffer *buffer, |
| 245 size_t size, size_t nitems); |
245 size_t size, size_t nitems); |
| 246 ``` |
246 ``` |
| 247 |
247 |
| 248 The function `cxBufferReset()` sets both size and position of the buffer to zero, |
248 The function `cxBufferReset()` sets both the size and position of the buffer to zero, |
| 249 and `cxBufferClear()` additionally uses `memset()` to set every byte in the buffer to zero. |
249 and `cxBufferClear()` additionally uses `memset()` to set every byte in the buffer to zero. |
| 250 |
250 |
| 251 > When clearing the buffer, only the "live" data, i.e., bytes with indices `[0..size)`, are cleared. |
251 > When clearing the buffer, only the "live" data, i.e., bytes with indices `[0..size)`, are cleared. |
| 252 > If you want to clear the entire buffer's memory, you would need to set the size to the capacity, first. |
252 > If you want to clear the entire buffer's memory, you would need to set the size to the capacity, first. |
| 253 |
253 |
| 269 |
269 |
| 270 The function `cxBufferSeek()` is a `fseek()`-like function that sets the current position in the buffer |
270 The function `cxBufferSeek()` is a `fseek()`-like function that sets the current position in the buffer |
| 271 relative to the start (when `whence` is `SEEK_SET`), the current position (when `whence` is `SEEK_CUR`), |
271 relative to the start (when `whence` is `SEEK_SET`), the current position (when `whence` is `SEEK_CUR`), |
| 272 or end (when `whence` is `SEEK_END`) of the buffer. |
272 or end (when `whence` is `SEEK_END`) of the buffer. |
| 273 |
273 |
| 274 If the resulting position is negative, or larger than the size (i.e. the first unused byte), |
274 If the resulting position is negative, or larger than the size (i.e., the first unused byte), |
| 275 this function returns non-zero and sets `errno` to `EINVAL`. |
275 this function returns non-zero and sets `errno` to `EINVAL`. |
| 276 |
276 |
| 277 > Note that the behavior of `cxBufferSeek()` when seeking beyond the end of the buffer is not exactly the same as for POSIX `fseek()`. |
277 > Note that the behavior of `cxBufferSeek()` when seeking beyond the end of the buffer is not exactly the same as for POSIX `fseek()`. |
| 278 |
278 |
| 279 ## Shift Contents |
279 ## Shift Contents |
| 293 It also adjusts the current position within the buffer, and in the case of a right shift also the size, by the same offset. |
293 It also adjusts the current position within the buffer, and in the case of a right shift also the size, by the same offset. |
| 294 |
294 |
| 295 Data shifted to the left is always discarded when the new position of a byte would be smaller than zero. |
295 Data shifted to the left is always discarded when the new position of a byte would be smaller than zero. |
| 296 When bytes are discarded, the new position of the buffer is set to zero. |
296 When bytes are discarded, the new position of the buffer is set to zero. |
| 297 |
297 |
| 298 When data is shift to the right, the behavior depends on the `CX_BUFFER_AUTO_EXTEND` flag. |
298 When data is shifted to the right, the behavior depends on the `CX_BUFFER_AUTO_EXTEND` flag. |
| 299 If set, the function extends the buffer's capacity before moving the data. |
299 If set, the function extends the buffer's capacity before moving the data. |
| 300 Otherwise, the function discards all data that would exceed the buffer's capacity, and both the size and the position are equal to the capacity |
300 Otherwise, the function discards all data that would exceed the buffer's capacity, and both the size and the position are equal to the capacity |
| 301 (which means, `cxBufferEof()` returns `true` after the operation). |
301 (which means, `cxBufferEof()` returns `true` after the operation). |
| 302 |
302 |
| 303 The functions `cxBufferShiftRight()` and `cxBufferShiftLeft()` accept a larger (but in both cases positive) shift offset, |
303 The functions `cxBufferShiftRight()` and `cxBufferShiftLeft()` accept a larger (but in both cases positive) shift offset, |