From d2316d574694a1943499553c535fa3830c198380 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 29 Aug 2021 13:10:44 -0400 Subject: buf: deprecate public git_buf writing functions A `git_buf` is now a read-only structure as far as callers are concerned. This is a mechanism that we can return data to callers using memory that is owned by the library and can be cleaned up by callers (using `git_buf_dispose`). A `git_buf` can no longer be allocated by callers or provided to the library. --- include/git2/deprecated.h | 55 +++++++++++++++++++++++++++++++++++++++++++ src/buffer.h | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/include/git2/deprecated.h b/include/git2/deprecated.h index ac60488ac..739f0b53f 100644 --- a/include/git2/deprecated.h +++ b/include/git2/deprecated.h @@ -191,6 +191,61 @@ GIT_EXTERN(int) git_treebuilder_write_with_buffer( */ /**@{*/ +/** + * Static initializer for git_buf from static buffer + */ +#define GIT_BUF_INIT_CONST(STR,LEN) { (char *)(STR), 0, (size_t)(LEN) } + +/** + * Resize the buffer allocation to make more space. + * + * This will attempt to grow the buffer to accommodate the target size. + * + * If the buffer refers to memory that was not allocated by libgit2 (i.e. + * the `asize` field is zero), then `ptr` will be replaced with a newly + * allocated block of data. Be careful so that memory allocated by the + * caller is not lost. As a special variant, if you pass `target_size` as + * 0 and the memory is not allocated by libgit2, this will allocate a new + * buffer of size `size` and copy the external data into it. + * + * Currently, this will never shrink a buffer, only expand it. + * + * If the allocation fails, this will return an error and the buffer will be + * marked as invalid for future operations, invaliding the contents. + * + * @param buffer The buffer to be resized; may or may not be allocated yet + * @param target_size The desired available size + * @return 0 on success, -1 on allocation failure + */ +GIT_EXTERN(int) git_buf_grow(git_buf *buffer, size_t target_size); + +/** + * Set buffer to a copy of some raw data. + * + * @param buffer The buffer to set + * @param data The data to copy into the buffer + * @param datalen The length of the data to copy into the buffer + * @return 0 on success, -1 on allocation failure + */ +GIT_EXTERN(int) git_buf_set( + git_buf *buffer, const void *data, size_t datalen); + +/** +* Check quickly if buffer looks like it contains binary data +* +* @param buf Buffer to check +* @return 1 if buffer looks like non-text data +*/ +GIT_EXTERN(int) git_buf_is_binary(const git_buf *buf); + +/** +* Check quickly if buffer contains a NUL byte +* +* @param buf Buffer to check +* @return 1 if buffer contains a NUL byte +*/ +GIT_EXTERN(int) git_buf_contains_nul(const git_buf *buf); + /** * Free the memory referred to by the git_buf. This is an alias of * `git_buf_dispose` and is preserved for backward compatibility. diff --git a/src/buffer.h b/src/buffer.h index d043ed626..7faa9fdc8 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -38,6 +38,13 @@ extern char git_buf__oom[]; /* Use to initialize buffer structure when git_buf is on stack */ #define GIT_BUF_INIT { git_buf__initbuf, 0, 0 } +/** + * Static initializer for git_buf from static buffer + */ +#ifdef GIT_DEPRECATE_HARD +# define GIT_BUF_INIT_CONST(STR,LEN) { (char *)(STR), 0, (size_t)(LEN) } +#endif + GIT_INLINE(bool) git_buf_is_allocated(const git_buf *buf) { return (buf->ptr != NULL && buf->asize > 0); @@ -51,6 +58,33 @@ GIT_INLINE(bool) git_buf_is_allocated(const git_buf *buf) */ extern int git_buf_init(git_buf *buf, size_t initial_size); +#ifdef GIT_DEPRECATE_HARD + +/** + * Resize the buffer allocation to make more space. + * + * This will attempt to grow the buffer to accommodate the target size. + * + * If the buffer refers to memory that was not allocated by libgit2 (i.e. + * the `asize` field is zero), then `ptr` will be replaced with a newly + * allocated block of data. Be careful so that memory allocated by the + * caller is not lost. As a special variant, if you pass `target_size` as + * 0 and the memory is not allocated by libgit2, this will allocate a new + * buffer of size `size` and copy the external data into it. + * + * Currently, this will never shrink a buffer, only expand it. + * + * If the allocation fails, this will return an error and the buffer will be + * marked as invalid for future operations, invaliding the contents. + * + * @param buffer The buffer to be resized; may or may not be allocated yet + * @param target_size The desired available size + * @return 0 on success, -1 on allocation failure + */ +int git_buf_grow(git_buf *buffer, size_t target_size); + +#endif + /** * Resize the buffer allocation to make more space. * @@ -120,6 +154,11 @@ GIT_INLINE(bool) git_buf_oom(const git_buf *buf) * return code of these functions and call them in a series then just call * git_buf_oom at the end. */ + +#ifdef GIT_DEPRECATE_HARD +int git_buf_set(git_buf *buffer, const void *data, size_t datalen); +#endif + int git_buf_sets(git_buf *buf, const char *string); int git_buf_putc(git_buf *buf, char c); int git_buf_putcn(git_buf *buf, char c, size_t len); @@ -311,4 +350,24 @@ extern int git_buf_detect_bom(git_buf_bom_t *bom, const git_buf *buf); extern bool git_buf_gather_text_stats( git_buf_text_stats *stats, const git_buf *buf, bool skip_bom); +#ifdef GIT_DEPRECATE_HARD + +/** +* Check quickly if buffer looks like it contains binary data +* +* @param buf Buffer to check +* @return 1 if buffer looks like non-text data +*/ +int git_buf_is_binary(const git_buf *buf); + +/** +* Check quickly if buffer contains a NUL byte +* +* @param buf Buffer to check +* @return 1 if buffer contains a NUL byte +*/ +int git_buf_contains_nul(const git_buf *buf); + +#endif + #endif -- cgit v1.2.1