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 0 : mnstr_writeChr(stream *s, char val)
29 : {
30 0 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
31 : return 0;
32 0 : return s->write(s, (void *) &val, sizeof(val), 1) == 1;
33 : }
34 :
35 : int
36 121614 : mnstr_readBte(stream *restrict s, int8_t *restrict val)
37 : {
38 121614 : if (s == NULL || val == NULL)
39 : return -1;
40 121614 : return (int) s->read(s, (void *) val, sizeof(*val), 1);
41 : }
42 :
43 : int
44 11017422 : mnstr_writeBte(stream *s, int8_t val)
45 : {
46 11017422 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
47 : return 0;
48 11017422 : return s->write(s, (void *) &val, sizeof(val), 1) == 1;
49 : }
50 :
51 : int
52 1047705 : mnstr_readSht(stream *restrict s, int16_t *restrict val)
53 : {
54 1047705 : if (s == NULL || val == NULL)
55 : return 0;
56 1047705 : assert(s->binary);
57 1047705 : switch (s->read(s, val, sizeof(*val), 1)) {
58 1008948 : case 1:
59 1008948 : 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 1025108 : mnstr_writeSht(stream *s, int16_t val)
71 : {
72 1025108 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
73 : return 0;
74 1025108 : assert(s->binary);
75 1025108 : if (s->swapbytes)
76 0 : val = short_int_SWAP(val);
77 1025108 : return s->write(s, &val, sizeof(val), 1) == 1;
78 : }
79 :
80 : int
81 747161 : mnstr_readInt(stream *restrict s, int *restrict val)
82 : {
83 747161 : if (s == NULL || val == NULL)
84 : return 0;
85 747161 : assert(s->binary);
86 747161 : switch (s->read(s, val, sizeof(*val), 1)) {
87 747161 : case 1:
88 747161 : 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 753909 : mnstr_writeInt(stream *s, int val)
100 : {
101 753909 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
102 : return 0;
103 753909 : assert(s->binary);
104 753909 : if (s->swapbytes)
105 0 : val = normal_int_SWAP(val);
106 753909 : return s->write(s, &val, sizeof(val), 1) == 1;
107 : }
108 :
109 : int
110 10893286 : mnstr_writeStr(stream *restrict s, const char *restrict val)
111 : {
112 10893286 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
113 : return 0;
114 10893286 : 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 801650 : mnstr_readLng(stream *restrict s, int64_t *restrict val)
134 : {
135 801650 : if (s == NULL || val == NULL)
136 : return 0;
137 801650 : assert(s->binary);
138 801650 : switch (s->read(s, val, sizeof(*val), 1)) {
139 801650 : case 1:
140 801650 : 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 816383 : mnstr_writeLng(stream *s, int64_t val)
152 : {
153 816383 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
154 : return 0;
155 816383 : assert(s->binary);
156 816383 : if (s->swapbytes)
157 0 : val = long_int_SWAP(val);
158 816383 : 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 130684 : mnstr_readBteArray(stream *restrict s, int8_t *restrict val, size_t cnt)
213 : {
214 130684 : if (s == NULL || val == NULL)
215 : return 0;
216 :
217 130684 : 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 130787 : mnstr_writeBteArray(stream *restrict s, const int8_t *restrict val, size_t cnt)
228 : {
229 130787 : if (s == NULL || s->errkind != MNSTR_NO__ERROR || val == NULL)
230 : return 0;
231 130787 : return s->write(s, val, sizeof(*val), cnt) == (ssize_t) cnt;
232 : }
233 :
234 : int
235 4129 : mnstr_readShtArray(stream *restrict s, int16_t *restrict val, size_t cnt)
236 : {
237 4129 : if (s == NULL || val == NULL)
238 : return 0;
239 4129 : assert(s->binary);
240 4129 : 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 4129 : 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 4242 : mnstr_writeShtArray(stream *restrict s, const int16_t *restrict val, size_t cnt)
254 : {
255 4242 : if (s == NULL || s->errkind != MNSTR_NO__ERROR || val == NULL)
256 : return 0;
257 4242 : assert(s->binary);
258 4242 : 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 4242 : return s->write(s, val, sizeof(*val), cnt) == (ssize_t) cnt;
265 : }
266 :
267 : int
268 111095 : mnstr_readIntArray(stream *restrict s, int *restrict val, size_t cnt)
269 : {
270 111095 : if (s == NULL || val == NULL)
271 : return 0;
272 111095 : assert(s->binary);
273 111095 : 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 111095 : 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 111692 : mnstr_writeIntArray(stream *restrict s, const int *restrict val, size_t cnt)
287 : {
288 111692 : if (s == NULL || s->errkind != MNSTR_NO__ERROR || val == NULL)
289 : return 0;
290 111692 : assert(s->binary);
291 111692 : 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 111692 : return s->write(s, val, sizeof(*val), cnt) == (ssize_t) cnt;
298 : }
299 :
300 : int
301 15919 : mnstr_readLngArray(stream *restrict s, int64_t *restrict val, size_t cnt)
302 : {
303 15919 : if (s == NULL || val == NULL)
304 : return 0;
305 15919 : assert(s->binary);
306 15919 : 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 15919 : 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 3597 : mnstr_writeLngArray(stream *restrict s, const int64_t *restrict val, size_t cnt)
320 : {
321 3597 : if (s == NULL || s->errkind != MNSTR_NO__ERROR || val == NULL)
322 : return 0;
323 3597 : assert(s->binary);
324 3597 : 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 3597 : 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 11030216 : mnstr_printf(stream *restrict s, const char *restrict format, ...)
370 : {
371 11030216 : va_list ap;
372 11030216 : char buf[512], *bf = buf;
373 11030216 : int i = 0;
374 11030216 : size_t bfsz = sizeof(buf);
375 :
376 11030216 : if (s == NULL || s->errkind != MNSTR_NO__ERROR)
377 : return -1;
378 :
379 11030216 : va_start(ap, format);
380 11030216 : i = vsnprintf(bf, bfsz, format, ap);
381 11030216 : va_end(ap);
382 11030370 : 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 11030216 : s->write(s, (void *) bf, (size_t) i, (size_t) 1);
399 11030209 : if (bf != buf)
400 154 : free(bf);
401 11030209 : return s->errkind == MNSTR_NO__ERROR ? i : -1;
402 : }
|