Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : #include "monetdb_config.h"
14 : #include "stream.h"
15 : #include "stream_internal.h"
16 :
17 :
18 :
19 : int
20 0 : mnstr_readChr(stream *restrict s, char *restrict val)
21 : {
22 0 : if (s == NULL || val == NULL)
23 : return -1;
24 0 : return (int) s->read(s, (void *) val, sizeof(*val), 1);
25 : }
26 :
27 : int
28 74 : mnstr_writeChr(stream *s, char val)
29 : {
30 74 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
31 : return 0;
32 74 : return s->write(s, (void *) &val, sizeof(val), 1) == 1;
33 : }
34 :
35 : int
36 123036 : mnstr_readBte(stream *restrict s, int8_t *restrict val)
37 : {
38 123036 : if (s == NULL || val == NULL)
39 : return -1;
40 123036 : return (int) s->read(s, (void *) val, sizeof(*val), 1);
41 : }
42 :
43 : int
44 11018765 : mnstr_writeBte(stream *s, int8_t val)
45 : {
46 11018765 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
47 : return 0;
48 11018765 : return s->write(s, (void *) &val, sizeof(val), 1) == 1;
49 : }
50 :
51 : int
52 1046720 : mnstr_readSht(stream *restrict s, int16_t *restrict val)
53 : {
54 1046720 : if (s == NULL || val == NULL)
55 : return 0;
56 1046717 : assert(s->binary);
57 1046717 : switch (s->read(s, val, sizeof(*val), 1)) {
58 1008323 : case 1:
59 1008323 : if (s->swapbytes)
60 0 : *val = short_int_SWAP(*val);
61 : return 1;
62 : case 0:
63 : return 0;
64 : default: /* -1 */
65 : return -1;
66 : }
67 : }
68 :
69 : int
70 1024467 : mnstr_writeSht(stream *s, int16_t val)
71 : {
72 1024467 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
73 : return 0;
74 1024467 : assert(s->binary);
75 1024467 : if (s->swapbytes)
76 0 : val = short_int_SWAP(val);
77 1024467 : return s->write(s, &val, sizeof(val), 1) == 1;
78 : }
79 :
80 : int
81 751194 : mnstr_readInt(stream *restrict s, int *restrict val)
82 : {
83 751194 : if (s == NULL || val == NULL)
84 : return 0;
85 751194 : assert(s->binary);
86 751194 : switch (s->read(s, val, sizeof(*val), 1)) {
87 751194 : case 1:
88 751194 : if (s->swapbytes)
89 0 : *val = normal_int_SWAP(*val);
90 : return 1;
91 : case 0:
92 : return 0;
93 : default: /* -1 */
94 : return -1;
95 : }
96 : }
97 :
98 : int
99 757823 : mnstr_writeInt(stream *s, int val)
100 : {
101 757823 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
102 : return 0;
103 757823 : assert(s->binary);
104 757823 : if (s->swapbytes)
105 0 : val = normal_int_SWAP(val);
106 757823 : return s->write(s, &val, sizeof(val), 1) == 1;
107 : }
108 :
109 : int
110 10893266 : mnstr_writeStr(stream *restrict s, const char *restrict val)
111 : {
112 10893266 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
113 : return 0;
114 10893266 : return s->write(s, (void *) val, strlen(val), (size_t) 1) == 1;
115 : }
116 :
117 : int
118 0 : mnstr_readStr(stream *restrict s, char *restrict val)
119 : {
120 0 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
121 : return 0;
122 0 : do {
123 0 : if (mnstr_readChr(s, val) != 1) {
124 : return -1;
125 : }
126 0 : val++;
127 0 : } while (*(val - 1) != '\0');
128 : return 1;
129 : }
130 :
131 :
132 : int
133 805626 : mnstr_readLng(stream *restrict s, int64_t *restrict val)
134 : {
135 805626 : if (s == NULL || val == NULL)
136 : return 0;
137 805626 : assert(s->binary);
138 805626 : switch (s->read(s, val, sizeof(*val), 1)) {
139 805626 : case 1:
140 805626 : if (s->swapbytes)
141 0 : *val = long_int_SWAP(*val);
142 : return 1;
143 : case 0:
144 : return 0;
145 : default: /* -1 */
146 : return -1;
147 : }
148 : }
149 :
150 : int
151 820135 : mnstr_writeLng(stream *s, int64_t val)
152 : {
153 820135 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
154 : return 0;
155 820135 : assert(s->binary);
156 820135 : if (s->swapbytes)
157 0 : val = long_int_SWAP(val);
158 820135 : return s->write(s, &val, sizeof(val), 1) == 1;
159 : }
160 :
161 : int
162 0 : mnstr_writeFlt(stream *s, float val)
163 : {
164 0 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
165 : return 0;
166 0 : assert(s->binary);
167 0 : return s->write(s, &val, sizeof(val), 1) == 1;
168 : }
169 :
170 : int
171 0 : mnstr_writeDbl(stream *s, double val)
172 : {
173 0 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
174 : return 0;
175 0 : assert(s->binary);
176 0 : return s->write(s, &val, sizeof(val), 1) == 1;
177 : }
178 :
179 :
180 : #ifdef HAVE_HGE
181 : int
182 0 : mnstr_readHge(stream *restrict s, hge *restrict val)
183 : {
184 0 : if (s == NULL || val == NULL)
185 : return 0;
186 0 : assert(s->binary);
187 0 : switch (s->read(s, val, sizeof(*val), 1)) {
188 0 : case 1:
189 0 : if (s->swapbytes)
190 0 : *val = huge_int_SWAP(*val);
191 : return 1;
192 : case 0:
193 : return 0;
194 : default: /* -1 */
195 : return -1;
196 : }
197 : }
198 :
199 : int
200 0 : mnstr_writeHge(stream *s, hge val)
201 : {
202 0 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
203 : return 0;
204 0 : assert(s->binary);
205 0 : if (s->swapbytes)
206 0 : val = huge_int_SWAP(val);
207 0 : return s->write(s, &val, sizeof(val), 1) == 1;
208 : }
209 : #endif
210 :
211 : int
212 131492 : mnstr_readBteArray(stream *restrict s, int8_t *restrict val, size_t cnt)
213 : {
214 131492 : if (s == NULL || val == NULL)
215 : return 0;
216 :
217 131492 : if (s->read(s, (void *) val, sizeof(*val), cnt) < (ssize_t) cnt) {
218 0 : if (s->errkind == MNSTR_NO__ERROR)
219 0 : mnstr_set_error(s, MNSTR_UNEXPECTED_EOF, NULL);
220 0 : return 0;
221 : }
222 :
223 : return 1;
224 : }
225 :
226 : int
227 131569 : mnstr_writeBteArray(stream *restrict s, const int8_t *restrict val, size_t cnt)
228 : {
229 131569 : if (s == NULL || s->errkind != MNSTR_NO__ERROR || val == NULL)
230 : return 0;
231 131569 : return s->write(s, val, sizeof(*val), cnt) == (ssize_t) cnt;
232 : }
233 :
234 : int
235 4078 : mnstr_readShtArray(stream *restrict s, int16_t *restrict val, size_t cnt)
236 : {
237 4078 : if (s == NULL || val == NULL)
238 : return 0;
239 4078 : assert(s->binary);
240 4078 : if (s->read(s, val, sizeof(*val), cnt) < (ssize_t) cnt) {
241 0 : if (s->errkind == MNSTR_NO__ERROR)
242 0 : mnstr_set_error(s, MNSTR_UNEXPECTED_EOF, NULL);
243 0 : return 0;
244 : }
245 4078 : if (s->swapbytes) {
246 0 : for (size_t i = 0; i < cnt; i++, val++)
247 0 : *val = short_int_SWAP(*val);
248 : }
249 : return 1;
250 : }
251 :
252 : int
253 4185 : mnstr_writeShtArray(stream *restrict s, const int16_t *restrict val, size_t cnt)
254 : {
255 4185 : if (s == NULL || s->errkind != MNSTR_NO__ERROR || val == NULL)
256 : return 0;
257 4185 : assert(s->binary);
258 4185 : if (s->swapbytes) {
259 0 : for (size_t i = 0; i < cnt; i++)
260 0 : if (!mnstr_writeSht(s, val[i]))
261 : return 0;
262 : return 1;
263 : }
264 4185 : return s->write(s, val, sizeof(*val), cnt) == (ssize_t) cnt;
265 : }
266 :
267 : int
268 111109 : mnstr_readIntArray(stream *restrict s, int *restrict val, size_t cnt)
269 : {
270 111109 : if (s == NULL || val == NULL)
271 : return 0;
272 111109 : assert(s->binary);
273 111109 : if (s->read(s, val, sizeof(*val), cnt) < (ssize_t) cnt) {
274 0 : if (s->errkind == MNSTR_NO__ERROR)
275 0 : mnstr_set_error(s, MNSTR_UNEXPECTED_EOF, NULL);
276 0 : return 0;
277 : }
278 111109 : if (s->swapbytes) {
279 0 : for (size_t i = 0; i < cnt; i++, val++)
280 0 : *val = normal_int_SWAP(*val);
281 : }
282 : return 1;
283 : }
284 :
285 : int
286 111624 : mnstr_writeIntArray(stream *restrict s, const int *restrict val, size_t cnt)
287 : {
288 111624 : if (s == NULL || s->errkind != MNSTR_NO__ERROR || val == NULL)
289 : return 0;
290 111624 : assert(s->binary);
291 111624 : if (s->swapbytes) {
292 0 : for (size_t i = 0; i < cnt; i++)
293 0 : if (!mnstr_writeInt(s, val[i]))
294 : return 0;
295 : return 1;
296 : }
297 111624 : return s->write(s, val, sizeof(*val), cnt) == (ssize_t) cnt;
298 : }
299 :
300 : int
301 15947 : mnstr_readLngArray(stream *restrict s, int64_t *restrict val, size_t cnt)
302 : {
303 15947 : if (s == NULL || val == NULL)
304 : return 0;
305 15947 : assert(s->binary);
306 15947 : if (s->read(s, val, sizeof(*val), cnt) < (ssize_t) cnt) {
307 0 : if (s->errkind == MNSTR_NO__ERROR)
308 0 : mnstr_set_error(s, MNSTR_UNEXPECTED_EOF, NULL);
309 0 : return 0;
310 : }
311 15947 : if (s->swapbytes) {
312 0 : for (size_t i = 0; i < cnt; i++, val++)
313 0 : *val = long_int_SWAP(*val);
314 : }
315 : return 1;
316 : }
317 :
318 : int
319 3626 : mnstr_writeLngArray(stream *restrict s, const int64_t *restrict val, size_t cnt)
320 : {
321 3626 : if (s == NULL || s->errkind != MNSTR_NO__ERROR || val == NULL)
322 : return 0;
323 3626 : assert(s->binary);
324 3626 : if (s->swapbytes) {
325 0 : for (size_t i = 0; i < cnt; i++)
326 0 : if (!mnstr_writeLng(s, val[i]))
327 : return 0;
328 : return 1;
329 : }
330 3626 : return s->write(s, val, sizeof(*val), cnt) == (ssize_t) cnt;
331 : }
332 :
333 : #ifdef HAVE_HGE
334 : int
335 477 : mnstr_readHgeArray(stream *restrict s, hge *restrict val, size_t cnt)
336 : {
337 477 : if (s == NULL || val == NULL)
338 : return 0;
339 477 : assert(s->binary);
340 477 : if (s->read(s, val, sizeof(*val), cnt) < (ssize_t) cnt) {
341 0 : if (s->errkind == MNSTR_NO__ERROR)
342 0 : mnstr_set_error(s, MNSTR_UNEXPECTED_EOF, NULL);
343 0 : return 0;
344 : }
345 477 : if (s->swapbytes) {
346 0 : for (size_t i = 0; i < cnt; i++, val++)
347 0 : *val = huge_int_SWAP(*val);
348 : }
349 : return 1;
350 : }
351 :
352 : int
353 477 : mnstr_writeHgeArray(stream *restrict s, const hge *restrict val, size_t cnt)
354 : {
355 477 : if (s == NULL || s->errkind != MNSTR_NO__ERROR || val == NULL)
356 : return 0;
357 477 : assert(s->binary);
358 477 : if (s->swapbytes) {
359 0 : for (size_t i = 0; i < cnt; i++)
360 0 : if (!mnstr_writeHge(s, val[i]))
361 : return 0;
362 : return 1;
363 : }
364 477 : return s->write(s, val, sizeof(*val), cnt) == (ssize_t) cnt;
365 : }
366 : #endif
367 :
368 : int
369 11041092 : mnstr_printf(stream *restrict s, const char *restrict format, ...)
370 : {
371 11041092 : va_list ap;
372 11041092 : char buf[512], *bf = buf;
373 11041092 : int i = 0;
374 11041092 : size_t bfsz = sizeof(buf);
375 :
376 11041092 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
377 : return -1;
378 :
379 11041092 : va_start(ap, format);
380 11041092 : i = vsnprintf(bf, bfsz, format, ap);
381 11041092 : va_end(ap);
382 11041246 : while (i < 0 || (size_t) i >= bfsz) {
383 154 : if (i >= 0) /* glibc 2.1 */
384 154 : bfsz = (size_t) i + 1; /* precisely what is needed */
385 : else /* glibc 2.0 */
386 0 : bfsz *= 2; /* twice the old size */
387 154 : if (bf != buf)
388 0 : free(bf);
389 154 : bf = malloc(bfsz);
390 154 : if (bf == NULL) {
391 0 : mnstr_set_error(s, MNSTR_WRITE_ERROR, "malloc failed");
392 0 : return -1;
393 : }
394 154 : va_start(ap, format);
395 154 : i = vsnprintf(bf, bfsz, format, ap);
396 154 : va_end(ap);
397 : }
398 11041092 : s->write(s, (void *) bf, (size_t) i, (size_t) 1);
399 11041123 : if (bf != buf)
400 154 : free(bf);
401 11041123 : return s->errkind == MNSTR_NO__ERROR ? i : -1;
402 : }
|