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