1 /*
2 Copyright (C) 2015-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5 
6 /*
7 	WARNING: This file was generated by the dkct program (see
8 	http://dktools.sourceforge.net/ for details).
9 	Changes you make here will be lost if dkct is run again!
10 	You should modify the original source and run dkct on it.
11 	Original source: dk4membuf.ctr
12 */
13 
14 /**	@file dk4membuf.c The dk4membuf module.
15 */
16 
17 
18 #include "dk4conf.h"
19 #include <libdk4c/dk4membuf.h>
20 #include <libdk4base/dk4mem.h>
21 #include <libdk4ma/dk4maasz.h>
22 
23 #if DK4_HAVE_ASSERT_H
24 #ifndef	ASSERT_H_INCLUDED
25 #include <assert.h>
26 #define	ASSERT_H_INCLUDED 1
27 #endif
28 #endif
29 
30 
31 
32 
33 
34 
35 static
36 void
dk4membuf_cell_close(dk4_membuf_cell_t * mcptr)37 dk4membuf_cell_close(dk4_membuf_cell_t *mcptr)
38 {
39 #if	DK4_USE_ASSERT
40 	assert(NULL != mcptr);
41 #endif
42   if (NULL != mcptr) {
43     dk4mem_release(mcptr->buf);
44     mcptr->next = NULL;
45     mcptr->max = mcptr->used = 0;
46     dk4mem_free(mcptr);
47   }
48 }
49 
50 
51 
52 static
53 dk4_membuf_cell_t *
dk4membuf_cell_open(size_t sz,dk4_er_t * erp)54 dk4membuf_cell_open(size_t sz, dk4_er_t *erp)
55 {
56   dk4_er_t		 er;
57   dk4_membuf_cell_t	*back	= NULL;
58   size_t		 nb;
59 
60   /*	Ensure number of bytes is a multiple of the chunk size.
61   */
62   nb = sz / DK4MEMBUF_CHUNK_SIZE;
63   if (0 != (sz % DK4MEMBUF_CHUNK_SIZE)) { nb++; }
64   dk4error_init(&er);
65   nb = dk4ma_size_t_mul(nb, (size_t)(DK4MEMBUF_CHUNK_SIZE), &er);
66   if (0 != er.ec) { nb = sz; }
67 
68   /*	Allocate
69   */
70   back = dk4mem_new(dk4_membuf_cell_t,1,erp);
71   if (NULL != back) {
72     back->next = NULL;
73     back->max  = nb;
74     back->used = 0;
75     back->buf = dk4mem_new(char,nb,erp);
76     if (NULL == back->buf) {
77       dk4mem_free(back);
78       back = NULL;
79     }
80   }
81   return back;
82 }
83 
84 
85 
86 dk4_membuf_t *
dk4membuf_open(dk4_er_t * erp)87 dk4membuf_open(dk4_er_t *erp)
88 {
89   dk4_membuf_t		*back	= NULL;
90   back = dk4mem_new(dk4_membuf_t,1,erp);
91   if (NULL != back) {
92     back->he = 0;
93     back->last = NULL;
94     back->first = dk4membuf_cell_open(DK4MEMBUF_CHUNK_SIZE, erp);
95     if (NULL != back->first) {
96       back->last = back->first;
97     } else {
98       dk4mem_free(back);
99       back = NULL;
100     }
101   }
102   return back;
103 }
104 
105 
106 
107 void
dk4membuf_close(dk4_membuf_t * mbptr)108 dk4membuf_close(dk4_membuf_t *mbptr)
109 {
110   dk4_membuf_cell_t	*pc;
111   dk4_membuf_cell_t	*pn;
112 #if	DK4_USE_ASSERT
113 	assert(NULL != mbptr);
114 #endif
115   if (NULL != mbptr) {
116     pc = mbptr->first;
117     while (NULL != pc) {
118       pn = pc->next;
119       dk4membuf_cell_close(pc);
120       pc = pn;
121     }
122     dk4mem_free(mbptr);
123   }
124 }
125 
126 
127 
128 int
dk4membuf_store(dk4_membuf_t * mbptr,const void * src,size_t sz,dk4_er_t * erp)129 dk4membuf_store(dk4_membuf_t *mbptr, const void *src, size_t sz, dk4_er_t *erp)
130 {
131   dk4_membuf_cell_t	*pc	= NULL;
132   dk4_membuf_cell_t	*pn	= NULL;
133   const char		*psrc	= NULL;
134   size_t		 bl	= 0;
135   int			 back	= 0;
136 #if	DK4_USE_ASSERT
137 	assert(NULL != src);
138 	assert(0 < sz);
139 	assert(NULL != mbptr);
140 #endif
141   if ((NULL != mbptr) && (NULL != src) && (0 < sz)) {
142     /*	Initialize variables.
143     */
144     back = 1;
145     pc   = mbptr->last;
146     psrc = (const char *)src;
147     /*	Attempt to fill current cell.
148     */
149     if (pc->max > pc->used) {
150       bl = pc->max - pc->used;
151       if (sz < bl) { bl = sz; }
152       DK4_MEMCPY(&((pc->buf)[pc->used]), psrc, bl);
153       pc->used += bl;
154       sz -= bl;
155       psrc = &(psrc[bl]);
156     }
157     /*	Use new cell if necessary.
158     */
159     if (0 < sz) {
160       back = 0;
161       pn = dk4membuf_cell_open(sz, erp);
162       if (NULL != pn) {
163         pc->next = pn;
164 	mbptr->last = pn;
165 	DK4_MEMCPY(pn->buf, psrc, sz);
166 	back = 1;
167 	pn->used = sz;
168       } else {
169         mbptr->he = 1;
170       }
171     }
172   } else {
173     dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
174   }
175   return back;
176 }
177 
178 
179 
180 int
dk4membuf_size(size_t * szptr,dk4_membuf_t const * mbptr,dk4_er_t * erp)181 dk4membuf_size(size_t *szptr, dk4_membuf_t const *mbptr, dk4_er_t *erp)
182 {
183   dk4_er_t		 er;
184   dk4_membuf_cell_t	*cp	= NULL;
185   size_t		 result	= (size_t)0U;
186   int			 back	= 0;
187 
188 #if	DK4_USE_ASSERT
189 	assert(NULL != szptr);
190 	assert(NULL != mbptr);
191 #endif
192   if ((NULL != szptr) && (NULL != mbptr)) {
193     back = 1;
194     cp = mbptr->first;
195     dk4error_init(&er);
196 
197     while (NULL != cp) {
198 
199       result = dk4ma_size_t_add(result, cp->used, &er);
200       cp = cp->next;
201     }
202     if (DK4_E_NONE == er.ec) {
203       back = 1;
204       *szptr = result;
205     }
206 #if TRACE_DEBUG
207     else {
208     }
209 #endif
210   } else {
211 #if TRACE_DEBUG
212     if (NULL == szptr) {
213     }
214     if (NULL == mbptr) {
215     }
216 #endif
217     dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
218   }
219 
220   return back;
221 }
222 
223 
224