File Coverage

houdini/buffer.h
Criterion Covered Total %
statement 1 1 100.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 1 1 100.0


line stmt bran cond sub pod time code
1             /*
2             * Copyright (C) the libgit2 contributors. All rights reserved.
3             *
4             * This file is part of libgit2, distributed under the GNU GPL v2 with
5             * a Linking Exception. For full terms see the included COPYING file.
6             */
7             #ifndef INCLUDE_buffer_h__
8             #define INCLUDE_buffer_h__
9              
10             #include
11             #include
12             #include
13             #include
14             #include
15              
16             typedef struct {
17             char *ptr;
18             size_t asize, size;
19             } gh_buf;
20              
21             extern char gh_buf__initbuf[];
22             extern char gh_buf__oom[];
23              
24             #define GH_BUF_INIT { gh_buf__initbuf, 0, 0 }
25              
26             /**
27             * Initialize a gh_buf structure.
28             *
29             * For the cases where GH_BUF_INIT cannot be used to do static
30             * initialization.
31             */
32             extern void gh_buf_init(gh_buf *buf, size_t initial_size);
33              
34             /**
35             * Attempt to grow the buffer to hold at least `target_size` bytes.
36             *
37             * If the allocation fails, this will return an error. If mark_oom is true,
38             * this will mark the buffer as invalid for future operations; if false,
39             * existing buffer content will be preserved, but calling code must handle
40             * that buffer was not expanded.
41             */
42             extern int gh_buf_try_grow(gh_buf *buf, size_t target_size, bool mark_oom);
43              
44             /**
45             * Grow the buffer to hold at least `target_size` bytes.
46             *
47             * If the allocation fails, this will return an error and the buffer will be
48             * marked as invalid for future operations, invaliding contents.
49             *
50             * @return 0 on success or -1 on failure
51             */
52             static inline int gh_buf_grow(gh_buf *buf, size_t target_size)
53             {
54 2           return gh_buf_try_grow(buf, target_size, true);
55             }
56              
57             extern void gh_buf_free(gh_buf *buf);
58             extern void gh_buf_swap(gh_buf *buf_a, gh_buf *buf_b);
59              
60             /**
61             * Test if there have been any reallocation failures with this gh_buf.
62             *
63             * Any function that writes to a gh_buf can fail due to memory allocation
64             * issues. If one fails, the gh_buf will be marked with an OOM error and
65             * further calls to modify the buffer will fail. Check gh_buf_oom() at the
66             * end of your sequence and it will be true if you ran out of memory at any
67             * point with that buffer.
68             *
69             * @return false if no error, true if allocation error
70             */
71             static inline bool gh_buf_oom(const gh_buf *buf)
72             {
73             return (buf->ptr == gh_buf__oom);
74             }
75              
76              
77             static inline size_t gh_buf_len(const gh_buf *buf)
78             {
79             return buf->size;
80             }
81              
82             extern int gh_buf_cmp(const gh_buf *a, const gh_buf *b);
83              
84             extern void gh_buf_attach(gh_buf *buf, char *ptr, size_t asize);
85             extern char *gh_buf_detach(gh_buf *buf);
86             extern void gh_buf_copy_cstr(char *data, size_t datasize, const gh_buf *buf);
87              
88             static inline const char *gh_buf_cstr(const gh_buf *buf)
89             {
90             return buf->ptr;
91             }
92              
93             /*
94             * Functions below that return int value error codes will return 0 on
95             * success or -1 on failure (which generally means an allocation failed).
96             * Using a gh_buf where the allocation has failed with result in -1 from
97             * all further calls using that buffer. As a result, you can ignore the
98             * return code of these functions and call them in a series then just call
99             * gh_buf_oom at the end.
100             */
101             extern int gh_buf_set(gh_buf *buf, const char *data, size_t len);
102             extern int gh_buf_sets(gh_buf *buf, const char *string);
103             extern int gh_buf_putc(gh_buf *buf, char c);
104             extern int gh_buf_put(gh_buf *buf, const void *data, size_t len);
105             extern int gh_buf_puts(gh_buf *buf, const char *string);
106             extern int gh_buf_printf(gh_buf *buf, const char *format, ...)
107             __attribute__((format (printf, 2, 3)));
108             extern int gh_buf_vprintf(gh_buf *buf, const char *format, va_list ap);
109             extern void gh_buf_clear(gh_buf *buf);
110              
111             #define gh_buf_PUTS(buf, str) gh_buf_put(buf, str, sizeof(str) - 1)
112              
113             #endif