]>
Commit | Line | Data |
---|---|---|
bb742ede | 1 | /* |
359fc2d2 | 2 | * Copyright (C) the libgit2 contributors. All rights reserved. |
bb742ede VM |
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 | */ | |
afeecf4f VM |
7 | #ifndef INCLUDE_buffer_h__ |
8 | #define INCLUDE_buffer_h__ | |
9 | ||
10 | #include "common.h" | |
b46708aa | 11 | #include "git2/strarray.h" |
85d54812 | 12 | #include "git2/buffer.h" |
afeecf4f | 13 | |
a9f51e43 RB |
14 | /* typedef struct { |
15 | * char *ptr; | |
16 | * size_t asize, size; | |
17 | * } git_buf; | |
18 | */ | |
afeecf4f | 19 | |
a0d95962 RB |
20 | extern char git_buf__initbuf[]; |
21 | extern char git_buf__oom[]; | |
afeecf4f | 22 | |
a9f51e43 | 23 | /* Use to initialize buffer structure when git_buf is on stack */ |
a0d95962 | 24 | #define GIT_BUF_INIT { git_buf__initbuf, 0, 0 } |
309113c9 | 25 | |
a9f51e43 RB |
26 | GIT_INLINE(bool) git_buf_is_allocated(const git_buf *buf) |
27 | { | |
28 | return (buf->ptr != NULL && buf->asize > 0); | |
29 | } | |
30 | ||
97769280 RB |
31 | /** |
32 | * Initialize a git_buf structure. | |
33 | * | |
34 | * For the cases where GIT_BUF_INIT cannot be used to do static | |
35 | * initialization. | |
36 | */ | |
7bf87ab6 | 37 | extern void git_buf_init(git_buf *buf, size_t initial_size); |
97769280 | 38 | |
4aa664ae ET |
39 | /** |
40 | * Resize the buffer allocation to make more space. | |
41 | * | |
42 | * This will attempt to grow the buffer to accommodate the additional size. | |
43 | * It is similar to `git_buf_grow`, but performs the new size calculation, | |
44 | * checking for overflow. | |
45 | * | |
46 | * Like `git_buf_grow`, if this is a user-supplied buffer, this will allocate | |
47 | * a new buffer. | |
48 | */ | |
49 | extern int git_buf_grow_by(git_buf *buffer, size_t additional_size); | |
50 | ||
97769280 | 51 | /** |
7bf87ab6 | 52 | * Attempt to grow the buffer to hold at least `target_size` bytes. |
97769280 | 53 | * |
a9f51e43 | 54 | * If the allocation fails, this will return an error. If `mark_oom` is true, |
7bf87ab6 RB |
55 | * this will mark the buffer as invalid for future operations; if false, |
56 | * existing buffer content will be preserved, but calling code must handle | |
a9f51e43 RB |
57 | * that buffer was not expanded. If `preserve_external` is true, then any |
58 | * existing data pointed to be `ptr` even if `asize` is zero will be copied | |
59 | * into the newly allocated buffer. | |
97769280 | 60 | */ |
a9f51e43 | 61 | extern int git_buf_try_grow( |
caab22c0 | 62 | git_buf *buf, size_t target_size, bool mark_oom); |
97769280 | 63 | |
6adcaab7 ET |
64 | /** |
65 | * Sanitizes git_buf structures provided from user input. Users of the | |
66 | * library, when providing git_buf's, may wish to provide a NULL ptr for | |
67 | * ease of handling. The buffer routines, however, expect a non-NULL ptr | |
68 | * always. This helper method simply handles NULL input, converting to a | |
cdb2c2a0 PS |
69 | * git_buf__initbuf. If a buffer with a non-NULL ptr is passed in, this method |
70 | * assures that the buffer is '\0'-terminated. | |
6adcaab7 ET |
71 | */ |
72 | extern void git_buf_sanitize(git_buf *buf); | |
73 | ||
7bf87ab6 RB |
74 | extern void git_buf_swap(git_buf *buf_a, git_buf *buf_b); |
75 | extern char *git_buf_detach(git_buf *buf); | |
76 | extern void git_buf_attach(git_buf *buf, char *ptr, size_t asize); | |
8c74d22e | 77 | |
d4cf1675 ET |
78 | /* Populates a `git_buf` where the contents are not "owned" by the |
79 | * buffer, and calls to `git_buf_free` will not free the given buf. | |
80 | */ | |
81 | extern void git_buf_attach_notowned( | |
82 | git_buf *buf, const char *ptr, size_t size); | |
83 | ||
8c74d22e | 84 | /** |
97769280 RB |
85 | * Test if there have been any reallocation failures with this git_buf. |
86 | * | |
8c74d22e RB |
87 | * Any function that writes to a git_buf can fail due to memory allocation |
88 | * issues. If one fails, the git_buf will be marked with an OOM error and | |
97769280 RB |
89 | * further calls to modify the buffer will fail. Check git_buf_oom() at the |
90 | * end of your sequence and it will be true if you ran out of memory at any | |
91 | * point with that buffer. | |
cb8a7961 VM |
92 | * |
93 | * @return false if no error, true if allocation error | |
97769280 | 94 | */ |
a0d95962 RB |
95 | GIT_INLINE(bool) git_buf_oom(const git_buf *buf) |
96 | { | |
97 | return (buf->ptr == git_buf__oom); | |
98 | } | |
97769280 RB |
99 | |
100 | /* | |
0d0fa7c3 RB |
101 | * Functions below that return int value error codes will return 0 on |
102 | * success or -1 on failure (which generally means an allocation failed). | |
103 | * Using a git_buf where the allocation has failed with result in -1 from | |
104 | * all further calls using that buffer. As a result, you can ignore the | |
105 | * return code of these functions and call them in a series then just call | |
106 | * git_buf_oom at the end. | |
97769280 | 107 | */ |
97769280 RB |
108 | int git_buf_sets(git_buf *buf, const char *string); |
109 | int git_buf_putc(git_buf *buf, char c); | |
b3b36a68 | 110 | int git_buf_putcn(git_buf *buf, char c, size_t len); |
97769280 RB |
111 | int git_buf_put(git_buf *buf, const char *data, size_t len); |
112 | int git_buf_puts(git_buf *buf, const char *string); | |
113 | int git_buf_printf(git_buf *buf, const char *format, ...) GIT_FORMAT_PRINTF(2, 3); | |
baaf1c47 | 114 | int git_buf_vprintf(git_buf *buf, const char *format, va_list ap); |
b87600cb | 115 | void git_buf_clear(git_buf *buf); |
c7c30513 | 116 | void git_buf_consume(git_buf *buf, const char *end); |
13224ea4 | 117 | void git_buf_truncate(git_buf *buf, size_t len); |
278ce746 | 118 | void git_buf_shorten(git_buf *buf, size_t amount); |
b6c93aef | 119 | void git_buf_rtruncate_at_char(git_buf *path, char separator); |
97769280 | 120 | |
18234b14 | 121 | /** General join with separator */ |
97769280 | 122 | int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...); |
18234b14 | 123 | /** Fast join of two strings - first may legally point into `buf` data */ |
97769280 | 124 | int git_buf_join(git_buf *buf, char separator, const char *str_a, const char *str_b); |
18234b14 RB |
125 | /** Fast join of three strings - cannot reference `buf` data */ |
126 | int git_buf_join3(git_buf *buf, char separator, const char *str_a, const char *str_b, const char *str_c); | |
97769280 RB |
127 | |
128 | /** | |
129 | * Join two strings as paths, inserting a slash between as needed. | |
0d0fa7c3 | 130 | * @return 0 on success, -1 on failure |
97769280 | 131 | */ |
bf6d2717 | 132 | GIT_INLINE(int) git_buf_joinpath(git_buf *buf, const char *a, const char *b) |
97769280 RB |
133 | { |
134 | return git_buf_join(buf, '/', a, b); | |
135 | } | |
8c74d22e | 136 | |
da3c187d | 137 | GIT_INLINE(const char *) git_buf_cstr(const git_buf *buf) |
bf6d2717 VM |
138 | { |
139 | return buf->ptr; | |
140 | } | |
141 | ||
da3c187d | 142 | GIT_INLINE(size_t) git_buf_len(const git_buf *buf) |
143 | { | |
144 | return buf->size; | |
145 | } | |
146 | ||
97769280 | 147 | void git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf); |
afeecf4f VM |
148 | |
149 | #define git_buf_PUTS(buf, str) git_buf_put(buf, str, sizeof(str) - 1) | |
150 | ||
ed4f95e5 | 151 | GIT_INLINE(ssize_t) git_buf_rfind_next(const git_buf *buf, char ch) |
df743c7d | 152 | { |
deafee7b | 153 | ssize_t idx = (ssize_t)buf->size - 1; |
df743c7d RB |
154 | while (idx >= 0 && buf->ptr[idx] == ch) idx--; |
155 | while (idx >= 0 && buf->ptr[idx] != ch) idx--; | |
156 | return idx; | |
157 | } | |
158 | ||
ed4f95e5 | 159 | GIT_INLINE(ssize_t) git_buf_rfind(const git_buf *buf, char ch) |
039fc406 RB |
160 | { |
161 | ssize_t idx = (ssize_t)buf->size - 1; | |
162 | while (idx >= 0 && buf->ptr[idx] != ch) idx--; | |
163 | return idx; | |
164 | } | |
165 | ||
ed4f95e5 | 166 | GIT_INLINE(ssize_t) git_buf_find(const git_buf *buf, char ch) |
f1e2735c | 167 | { |
ed4f95e5 RB |
168 | void *found = memchr(buf->ptr, ch, buf->size); |
169 | return found ? (ssize_t)((const char *)found - buf->ptr) : -1; | |
f1e2735c RB |
170 | } |
171 | ||
13224ea4 VM |
172 | /* Remove whitespace from the end of the buffer */ |
173 | void git_buf_rtrim(git_buf *buf); | |
174 | ||
ce49c7a8 RB |
175 | int git_buf_cmp(const git_buf *a, const git_buf *b); |
176 | ||
d3d95d5a | 177 | /* Quote and unquote a buffer as specified in |
d34f6826 ET |
178 | * http://marc.info/?l=git&m=112927316408690&w=2 |
179 | */ | |
d3d95d5a | 180 | int git_buf_quote(git_buf *buf); |
d34f6826 ET |
181 | int git_buf_unquote(git_buf *buf); |
182 | ||
2d3579be | 183 | /* Write data as base64 encoded in buffer */ |
e003f83a ET |
184 | int git_buf_encode_base64(git_buf *buf, const char *data, size_t len); |
185 | /* Decode the given bas64 and write the result to the buffer */ | |
186 | int git_buf_decode_base64(git_buf *buf, const char *base64, size_t len); | |
2d3579be | 187 | |
e349ed50 | 188 | /* Write data as "base85" encoded in buffer */ |
e003f83a | 189 | int git_buf_encode_base85(git_buf *buf, const char *data, size_t len); |
5b78dbdb ET |
190 | /* Decode the given "base85" and write the result to the buffer */ |
191 | int git_buf_decode_base85(git_buf *buf, const char *base64, size_t len, size_t output_len); | |
e349ed50 | 192 | |
3a14d3e2 | 193 | /* |
194 | * Insert, remove or replace a portion of the buffer. | |
195 | * | |
196 | * @param buf The buffer to work with | |
197 | * | |
198 | * @param where The location in the buffer where the transformation | |
199 | * should be applied. | |
200 | * | |
201 | * @param nb_to_remove The number of chars to be removed. 0 to not | |
202 | * remove any character in the buffer. | |
203 | * | |
204 | * @param data A pointer to the data which should be inserted. | |
205 | * | |
206 | * @param nb_to_insert The number of chars to be inserted. 0 to not | |
207 | * insert any character from the buffer. | |
208 | * | |
209 | * @return 0 or an error code. | |
210 | */ | |
211 | int git_buf_splice( | |
212 | git_buf *buf, | |
213 | size_t where, | |
214 | size_t nb_to_remove, | |
215 | const char *data, | |
216 | size_t nb_to_insert); | |
217 | ||
afeecf4f | 218 | #endif |