Line data Source code
1 : /*
2 : dyn_buffer.c
3 : Created by Danny Goossen, Gioxa Ltd on 8/3/17.
4 :
5 : MIT License
6 :
7 : Copyright (c) 2017 deployctl, Gioxa Ltd.
8 :
9 : Permission is hereby granted, free of charge, to any person obtaining a copy
10 : of this software and associated documentation files (the "Software"), to deal
11 : in the Software without restriction, including without limitation the rights
12 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 : copies of the Software, and to permit persons to whom the Software is
14 : furnished to do so, subject to the following conditions:
15 :
16 : The above copyright notice and this permission notice shall be included in all
17 : copies or substantial portions of the Software.
18 :
19 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 : SOFTWARE.
26 :
27 : */
28 :
29 : /** \file dyn_buffer.c
30 : * \brief functions for Dynamic buffer manipulations
31 : * \author Created by Danny Goossen on 23/7/18.
32 : * \copyright Copyright (c) 2018 Danny Goossen. All rights reserved.
33 : */
34 :
35 :
36 : #include "deployd.h"
37 :
38 : /**
39 : * \brief Dynbuffer structure definition (internal)
40 : */
41 : struct MemoryStruct {
42 : char *memory; /**< buffer */
43 : size_t size; /**< lenth of content of buffer */
44 : ssize_t read; /**< index in buffer for getc */
45 : };
46 :
47 : // functions for IO_Stream
48 :
49 0 : int dynbuffer_ungetc(int c, dynbuffer *userp)
50 : {
51 0 : struct MemoryStruct *mem = (struct MemoryStruct *)userp;
52 0 : if (mem->read >0)
53 : {
54 0 : mem->read--;
55 :
56 0 : mem->memory[mem->read]=(char)c;
57 0 : return 0;
58 : }
59 : else return -1;
60 :
61 : }
62 0 : int dynbuffer_getc(dynbuffer *userp)
63 : {
64 0 : int c=0;
65 0 : struct MemoryStruct *mem = (struct MemoryStruct *)userp;
66 0 : if (mem->read!=mem->size)
67 : {
68 0 : c=(int)mem->memory[mem->read];
69 0 : mem->read++;
70 :
71 : }
72 : else c=-1;
73 0 : return c;
74 : }
75 :
76 0 : size_t dynbuffer_fread( void * p, size_t s2, size_t s1,dynbuffer *userp)
77 : {
78 0 : struct MemoryStruct *mem = (struct MemoryStruct *)userp;
79 0 : size_t len_requested=s2*s1;
80 0 : if (mem->read==mem->size) return 0;
81 0 : if (mem->size-mem->read>len_requested)
82 : {
83 0 : memcpy(p, mem->memory+mem->read, len_requested);
84 0 : mem->read=mem->read+len_requested;
85 0 : return len_requested;
86 : }
87 : else
88 : {
89 0 : len_requested=mem->size-mem->read;
90 0 : memcpy(p, mem->memory+mem->read, len_requested);
91 0 : mem->read=mem->read+len_requested;
92 0 : return len_requested;
93 : }
94 : }
95 :
96 0 : int dynbuffer_putc(int c,dynbuffer *userp)
97 : {
98 0 : dynbuffer_write_n(&c, 1, userp);
99 0 : return 0;
100 : }
101 :
102 0 : size_t dynbuffer_fwrite(const void * p, size_t s2, size_t s1,dynbuffer *userp)
103 : {
104 :
105 0 : return dynbuffer_write_n(p, s1*s2, userp);
106 : }
107 0 : int dynbuffer_fputs(const char * p,dynbuffer *userp)
108 : {
109 0 : dynbuffer_write(p,userp);
110 0 : return 0;
111 : }
112 :
113 :
114 :
115 : /*------------------------------------------------------------------------
116 : * Helper function for Curl request
117 : *------------------------------------------------------------------------*/
118 0 : size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, dynbuffer *userp)
119 : {
120 0 : size_t realsize = size * nmemb;
121 0 : struct MemoryStruct *mem = (struct MemoryStruct *)userp;
122 :
123 0 : void * tmp= realloc(mem->memory, mem->size + realsize + 1);
124 0 : if(tmp == NULL) {
125 : // LCOV_EXCL_START
126 : /* out of memory! */
127 : // error("not enough memory (realloc returned NULL)\n");
128 : return 0;
129 : // LCOV_EXCL_STOP
130 :
131 : }
132 : else
133 0 : mem->memory=tmp;
134 :
135 0 : memcpy(&(mem->memory[mem->size]), contents, realsize);
136 0 : mem->size += realsize;
137 0 : mem->memory[mem->size] = 0;
138 0 : return realsize;
139 : }
140 :
141 :
142 :
143 : // START Dynbuffer
144 :
145 : /*------------------------------------------------------------------------
146 : * Helper function write string to dynamic buffer
147 : *------------------------------------------------------------------------*/
148 0 : size_t dynbuffer_write(const void *contents, dynbuffer *userp)
149 : {
150 0 : size_t realsize = strlen(contents);
151 0 : struct MemoryStruct *mem = (struct MemoryStruct *)userp;
152 :
153 0 : void * tmp= realloc(mem->memory, mem->size + realsize + 1);
154 0 : if(tmp == NULL) {
155 : // LCOV_EXCL_START
156 : /* out of memory! */
157 : // error("not enough memory (realloc returned NULL)\n");
158 : return 0;
159 : // LCOV_EXCL_STOP
160 : }
161 : else
162 0 : mem->memory=tmp;
163 0 : memcpy(&(mem->memory[mem->size]), contents, realsize);
164 0 : mem->size += realsize;
165 0 : mem->memory[mem->size] = 0;
166 :
167 0 : return realsize;
168 : }
169 :
170 :
171 : /*------------------------------------------------------------------------
172 : * Helper function write string to dynamic buffer
173 : *------------------------------------------------------------------------*/
174 0 : size_t dynbuffer_write_v( dynbuffer *userp,const char*data,...)
175 : {
176 0 : char * contents=CSPRINTF(data);
177 0 : if (contents)
178 : {
179 0 : size_t realsize = strlen(contents);
180 0 : struct MemoryStruct *mem = (struct MemoryStruct *)userp;
181 :
182 0 : void * tmp= realloc(mem->memory, mem->size + realsize + 1);
183 0 : if(tmp == NULL) {
184 : // LCOV_EXCL_START
185 : /* out of memory! */
186 : // error("not enough memory (realloc returned NULL)\n");
187 : return 0;
188 : // LCOV_EXCL_STOP
189 : }
190 : else
191 0 : mem->memory=tmp;
192 0 : memcpy(&(mem->memory[mem->size]), contents, realsize);
193 0 : mem->size += realsize;
194 0 : mem->memory[mem->size] = 0;
195 0 : free(contents);
196 0 : return realsize;
197 : }
198 : else return 0;
199 : }
200 :
201 :
202 : /*------------------------------------------------------------------------
203 : * Helper function write non NULL string to dynamic buffer
204 : *------------------------------------------------------------------------*/
205 4 : size_t dynbuffer_write_n(const void *contents, size_t content_len, dynbuffer *userp)
206 : {
207 4 : size_t realsize = content_len;
208 4 : struct MemoryStruct *mem = (struct MemoryStruct *)userp;
209 :
210 4 : void * tmp= realloc(mem->memory, mem->size + realsize + 1);
211 4 : if(tmp == NULL) {
212 : // LCOV_EXCL_START
213 : /* out of memory! */
214 : // error("not enough memory (realloc returned NULL)\n");
215 : return 0;
216 : // LCOV_EXCL_STOP
217 : }
218 : else
219 4 : mem->memory=tmp;
220 :
221 :
222 4 : memcpy(&(mem->memory[mem->size]), contents, realsize);
223 4 : mem->size += realsize;
224 4 : mem->memory[mem->size] = 0;
225 :
226 4 : return realsize;
227 : }
228 :
229 : /*------------------------------------------------------------------------
230 : * intializes the dynamic buff
231 : *------------------------------------------------------------------------*/
232 4 : dynbuffer * dynbuffer_init( void )
233 : {
234 4 : struct MemoryStruct *mem = calloc(1,sizeof(struct MemoryStruct));
235 4 : if (mem)
236 : {
237 4 : mem->read=0;
238 4 : mem->memory = malloc( 1);
239 4 : mem->size=0;
240 4 : if(mem->memory == NULL) {
241 0 : free(mem);
242 0 : return NULL;
243 : }
244 4 : mem->memory[mem->size] = 0;
245 : }
246 4 : return mem;
247 : }
248 :
249 :
250 : /*------------------------------------------------------------------------
251 : * intializes the dynamic buff, with a given buffer, use pop to retrieve buff
252 : *------------------------------------------------------------------------*/
253 0 : dynbuffer * dynbuffer_init_push( char ** ptr, size_t n)
254 : {
255 0 : if (!ptr || !(*ptr)) return NULL;
256 0 : struct MemoryStruct *mem = calloc(1,sizeof(struct MemoryStruct));
257 0 : if (mem)
258 : {
259 0 : mem->memory = *ptr;
260 0 : *ptr=NULL;
261 0 : if (n!=0)
262 0 : mem->size=n;
263 : else
264 0 : mem->size=strlen(mem->memory);
265 0 : mem->read=0;
266 0 : if(mem->memory == NULL) {
267 0 : free(mem);
268 0 : return NULL;
269 : }
270 : }
271 0 : return mem;
272 : }
273 :
274 :
275 : /*------------------------------------------------------------------------
276 : * frees the dynamic buff
277 : *------------------------------------------------------------------------*/
278 0 : void dynbuffer_clear( dynbuffer **userp)
279 : {
280 0 : struct MemoryStruct **mem = (struct MemoryStruct **)userp;
281 0 : if (mem && *mem)
282 : {
283 0 : if ((*mem)->memory)free((*mem)->memory);
284 0 : (*mem)->memory=NULL;
285 0 : (*mem)->size=-0;
286 0 : free(*mem);
287 0 : *mem=NULL;
288 : }
289 0 : return ;
290 : }
291 :
292 :
293 : // detach data from dyn_buffer and free dynbuffer struct
294 4 : void dynbuffer_pop(dynbuffer **userp, char ** buffer, size_t * len)
295 : {
296 4 : struct MemoryStruct **mem = (struct MemoryStruct **)userp;
297 4 : if(mem && *mem && buffer)
298 : {
299 4 : *buffer=(*mem)->memory;
300 4 : (*mem)->memory=NULL;
301 4 : if (len) *len=(*mem)->size;
302 4 : (*mem)->size=0;
303 4 : free(*userp);
304 4 : *userp=NULL;
305 : }
306 4 : }
307 :
308 :
309 0 : const char * dynbuffer_get(dynbuffer *userp)
310 : {
311 0 : struct MemoryStruct *mem = (struct MemoryStruct *)userp;
312 0 : return (const char *)mem->memory;
313 : }
314 :
315 0 : size_t dynbuffer_len(dynbuffer *userp)
316 : {
317 0 : struct MemoryStruct *mem = (struct MemoryStruct *)userp;
318 0 : return mem->size;
319 : }
320 :
321 :
322 :
323 :
324 :
325 :
|