| /* Low level interface to the Zstandard algorithm & the zstd library. */ | |
| #ifndef ZSTD_BUFFER_H | |
| #define ZSTD_BUFFER_H | |
| #include "pycore_blocks_output_buffer.h" | |
| #include <zstd.h> // ZSTD_outBuffer | |
| /* Blocks output buffer wrapper code */ | |
| /* Initialize the buffer, and grow the buffer. | |
| Return 0 on success | |
| Return -1 on failure */ | |
| static inline int | |
| _OutputBuffer_InitAndGrow(_BlocksOutputBuffer *buffer, ZSTD_outBuffer *ob, | |
| Py_ssize_t max_length) | |
| { | |
| /* Ensure .writer was set to NULL */ | |
| assert(buffer->writer == NULL); | |
| Py_ssize_t res = _BlocksOutputBuffer_InitAndGrow(buffer, max_length, | |
| &ob->dst); | |
| if (res < 0) { | |
| return -1; | |
| } | |
| ob->size = (size_t) res; | |
| ob->pos = 0; | |
| return 0; | |
| } | |
| /* Initialize the buffer, with an initial size. | |
| init_size: the initial size. | |
| Return 0 on success | |
| Return -1 on failure */ | |
| static inline int | |
| _OutputBuffer_InitWithSize(_BlocksOutputBuffer *buffer, ZSTD_outBuffer *ob, | |
| Py_ssize_t max_length, Py_ssize_t init_size) | |
| { | |
| Py_ssize_t block_size; | |
| /* Ensure .writer was set to NULL */ | |
| assert(buffer->writer == NULL); | |
| /* Get block size */ | |
| if (0 <= max_length && max_length < init_size) { | |
| block_size = max_length; | |
| } | |
| else { | |
| block_size = init_size; | |
| } | |
| Py_ssize_t res = _BlocksOutputBuffer_InitWithSize(buffer, block_size, | |
| &ob->dst); | |
| if (res < 0) { | |
| return -1; | |
| } | |
| // Set max_length, InitWithSize doesn't do this | |
| buffer->max_length = max_length; | |
| ob->size = (size_t) res; | |
| ob->pos = 0; | |
| return 0; | |
| } | |
| /* Grow the buffer. | |
| Return 0 on success | |
| Return -1 on failure */ | |
| static inline int | |
| _OutputBuffer_Grow(_BlocksOutputBuffer *buffer, ZSTD_outBuffer *ob) | |
| { | |
| assert(ob->pos == ob->size); | |
| Py_ssize_t res = _BlocksOutputBuffer_Grow(buffer, &ob->dst, 0); | |
| if (res < 0) { | |
| return -1; | |
| } | |
| ob->size = (size_t) res; | |
| ob->pos = 0; | |
| return 0; | |
| } | |
| /* Finish the buffer. | |
| Return a bytes object on success | |
| Return NULL on failure */ | |
| static inline PyObject * | |
| _OutputBuffer_Finish(_BlocksOutputBuffer *buffer, ZSTD_outBuffer *ob) | |
| { | |
| return _BlocksOutputBuffer_Finish(buffer, ob->size - ob->pos); | |
| } | |
| /* Clean up the buffer */ | |
| static inline void | |
| _OutputBuffer_OnError(_BlocksOutputBuffer *buffer) | |
| { | |
| _BlocksOutputBuffer_OnError(buffer); | |
| } | |
| /* Whether the output data has reached max_length. | |
| The avail_out must be 0, please check it before calling. */ | |
| static inline int | |
| _OutputBuffer_ReachedMaxLength(_BlocksOutputBuffer *buffer, ZSTD_outBuffer *ob) | |
| { | |
| /* Ensure (data size == allocated size) */ | |
| assert(ob->pos == ob->size); | |
| return buffer->allocated == buffer->max_length; | |
| } | |
| #endif // !ZSTD_BUFFER_H |