1 /*
2 * byteswap - byte swapping routines
3 *
4 * Copyright (C) 1999,2021 Landon Curt Noll
5 *
6 * Calc is open software; you can redistribute it and/or modify it under
7 * the terms of the version 2.1 of the GNU Lesser General Public License
8 * as published by the Free Software Foundation.
9 *
10 * Calc is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
13 * Public License for more details.
14 *
15 * A copy of version 2.1 of the GNU Lesser General Public License is
16 * distributed with calc under the filename COPYING-LGPL. You should have
17 * received a copy with calc; if not, write to Free Software Foundation, Inc.
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 * Under source code control: 1995/10/11 04:44:01
21 * File existed as early as: 1995
22 *
23 * chongo <was here> /\oo/\ http://www.isthe.com/chongo/
24 * Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
25 */
26
27
28 #include "cmath.h"
29 #include "byteswap.h"
30
31
32 #include "banned.h" /* include after system header <> includes */
33
34
35 /*
36 * swap_b8_in_HALFs - swap 8 and if needed, 16 bits in an array of HALFs
37 *
38 * given:
39 * dest - pointer to where the swapped src will be put or
40 * NULL to allocate the storage
41 * src - pointer to a HALF array to swap
42 * len - length of the src HALF array
43 *
44 * returns:
45 * pointer to where the swapped src has been put
46 */
47 HALF *
swap_b8_in_HALFs(HALF * dest,HALF * src,LEN len)48 swap_b8_in_HALFs(HALF *dest, HALF *src, LEN len)
49 {
50 HALF *ret;
51 LEN i;
52
53 /*
54 * allocate storage if needed
55 */
56 if (dest == NULL) {
57 dest = alloc(len);
58 }
59 ret = dest;
60
61 /*
62 * swap the array
63 */
64 for (i=0; i < len; ++i, ++dest, ++src) {
65 SWAP_B8_IN_HALF(dest, src);
66 }
67
68 /*
69 * return the result
70 */
71 return ret;
72 }
73
74
75 /*
76 * swap_b8_in_ZVALUE - swap 8 and if needed, 16 bits in a ZVALUE
77 *
78 * given:
79 * dest - pointer to where the swapped src will be put or
80 * NULL to allocate the storage
81 * src - pointer to a ZVALUE to swap
82 * all - TRUE => swap every element, FALSE => swap only the
83 * multi-precision storage
84 *
85 * returns:
86 * pointer to where the swapped src has been put
87 *
88 * This macro will either switch to the opposite byte sex (Big Endian vs.
89 * Little Endian) the elements of a ZVALUE.
90 */
91 ZVALUE *
swap_b8_in_ZVALUE(ZVALUE * dest,ZVALUE * src,BOOL all)92 swap_b8_in_ZVALUE(ZVALUE *dest, ZVALUE *src, BOOL all)
93 {
94 /*
95 * allocate storage if needed
96 */
97 if (dest == NULL) {
98
99 /*
100 * allocate the storage
101 */
102 dest = malloc(sizeof(ZVALUE));
103 if (dest == NULL) {
104 math_error("swap_b8_in_ZVALUE: swap_b8_in_ZVALUE: "
105 "Not enough memory");
106 /*NOTREACHED*/
107 }
108
109 /*
110 * allocate (by forcing swap_b8_in_ZVALUE) and swap storage
111 */
112 dest->v = swap_b8_in_HALFs(NULL, src->v, src->len);
113
114 } else {
115
116 /*
117 * swap storage
118 */
119 if (dest->v != NULL) {
120 zfree(*dest);
121 }
122 dest->v = swap_b8_in_HALFs(NULL, src->v, src->len);
123 }
124
125 /*
126 * swap or copy the rest of the ZVALUE elements
127 */
128 if (all) {
129 SWAP_B8_IN_LEN(&dest->len, &src->len);
130 SWAP_B8_IN_BOOL(&dest->sign, &src->sign);
131 } else {
132 dest->len = src->len;
133 dest->sign = src->sign;
134 }
135
136 /*
137 * return the result
138 */
139 return dest;
140 }
141
142
143 /*
144 * swap_b8_in_NUMBER - swap 8 and if needed, 16 bits in a NUMBER
145 *
146 * given:
147 * dest - pointer to where the swapped src will be put or
148 * NULL to allocate the storage
149 * src - pointer to a NUMBER to swap
150 * all - TRUE => swap every element, FALSE => swap only the
151 * multi-precision storage
152 *
153 * returns:
154 * pointer to where the swapped src has been put
155 *
156 * This macro will either switch to the opposite byte sex (Big Endian vs.
157 * Little Endian) the elements of a NUMBER.
158 */
159 NUMBER *
swap_b8_in_NUMBER(NUMBER * dest,NUMBER * src,BOOL all)160 swap_b8_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all)
161 {
162 /*
163 * allocate storage if needed
164 */
165 if (dest == NULL) {
166
167 /*
168 * allocate the storage
169 */
170 dest = malloc(sizeof(NUMBER));
171 if (dest == NULL) {
172 math_error("swap_b8_in_NUMBER: Not enough memory");
173 /*NOTREACHED*/
174 }
175
176 /*
177 * allocate (by forcing swap_b8_in_ZVALUE) and swap storage
178 */
179 dest->num = *swap_b8_in_ZVALUE(NULL, &src->num, all);
180 dest->den = *swap_b8_in_ZVALUE(NULL, &src->den, all);
181
182 } else {
183
184 /*
185 * swap storage
186 */
187 dest->num = *swap_b8_in_ZVALUE(&dest->num, &src->num, all);
188 dest->den = *swap_b8_in_ZVALUE(&dest->den, &src->den, all);
189 }
190
191 /*
192 * swap or copy the rest of the NUMBER elements
193 */
194 if (all) {
195 SWAP_B8_IN_LONG(&dest->links, &src->links);
196 } else {
197 dest->links = src->links;
198 }
199
200 /*
201 * return the result
202 */
203 return dest;
204 }
205
206
207 /*
208 * swap_b8_in_COMPLEX - swap 8 and if needed, 16 bits in a COMPLEX
209 *
210 * given:
211 * dest - pointer to where the swapped src will be put or
212 * NULL to allocate the storage
213 * src - pointer to a COMPLEX to swap
214 * all - TRUE => swap every element, FALSE => swap only the
215 * multi-precision storage
216 *
217 * returns:
218 * pointer to where the swapped src has been put
219 *
220 * This macro will either switch to the opposite byte sex (Big Endian vs.
221 * Little Endian) the elements of a COMPLEX.
222 */
223 COMPLEX *
swap_b8_in_COMPLEX(COMPLEX * dest,COMPLEX * src,BOOL all)224 swap_b8_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all)
225 {
226 /*
227 * allocate storage if needed
228 */
229 if (dest == NULL) {
230
231 /*
232 * allocate the storage
233 */
234 dest = malloc(sizeof(COMPLEX));
235 if (dest == NULL) {
236 math_error("swap_b8_in_COMPLEX: Not enough memory");
237 /*NOTREACHED*/
238 }
239
240 /*
241 * allocate (by forcing swap_b8_in_ZVALUE) and swap storage
242 */
243 dest->real = swap_b8_in_NUMBER(NULL, src->real, all);
244 dest->imag = swap_b8_in_NUMBER(NULL, src->imag, all);
245
246 } else {
247
248 /*
249 * swap storage
250 */
251 dest->real = swap_b8_in_NUMBER(dest->real, src->real, all);
252 dest->imag = swap_b8_in_NUMBER(dest->imag, src->imag, all);
253 }
254
255 /*
256 * swap or copy the rest of the NUMBER elements
257 */
258 if (all) {
259 SWAP_B8_IN_LONG(&dest->links, &src->links);
260 } else {
261 dest->links = src->links;
262 }
263
264 /*
265 * return the result
266 */
267 return dest;
268 }
269
270
271 /*
272 * swap_b16_in_HALFs - swap 16 bits in an array of HALFs
273 *
274 * given:
275 * dest - pointer to where the swapped src will be put or
276 * NULL to allocate the storage
277 * src - pointer to a HALF array to swap
278 * len - length of the src HALF array
279 *
280 * returns:
281 * pointer to where the swapped src has been put
282 */
283 HALF *
swap_b16_in_HALFs(HALF * dest,HALF * src,LEN len)284 swap_b16_in_HALFs(HALF *dest, HALF *src, LEN len)
285 {
286 HALF *ret;
287 LEN i;
288
289 /*
290 * allocate storage if needed
291 */
292 if (dest == NULL) {
293 dest = alloc(len);
294 }
295 ret = dest;
296
297 /*
298 * swap the array
299 */
300 for (i=0; i < len; ++i, ++dest, ++src) {
301 SWAP_B16_IN_HALF(dest, src);
302 }
303
304 /*
305 * return the result
306 */
307 return ret;
308 }
309
310
311 /*
312 * swap_b16_in_ZVALUE - swap 16 bits in a ZVALUE
313 *
314 * given:
315 * dest - pointer to where the swapped src will be put or
316 * NULL to allocate the storage
317 * src - pointer to a ZVALUE to swap
318 * all - TRUE => swap every element, FALSE => swap only the
319 * multi-precision storage
320 *
321 * returns:
322 * pointer to where the swapped src has been put
323 *
324 * This macro will either switch to the opposite byte sex (Big Endian vs.
325 * Little Endian) the elements of a ZVALUE.
326 */
327 ZVALUE *
swap_b16_in_ZVALUE(ZVALUE * dest,ZVALUE * src,BOOL all)328 swap_b16_in_ZVALUE(ZVALUE *dest, ZVALUE *src, BOOL all)
329 {
330 /*
331 * allocate storage if needed
332 */
333 if (dest == NULL) {
334
335 /*
336 * allocate the storage
337 */
338 dest = malloc(sizeof(ZVALUE));
339 if (dest == NULL) {
340 math_error("swap_b16_in_ZVALUE: Not enough memory");
341 /*NOTREACHED*/
342 }
343
344 /*
345 * allocate (by forcing swap_b16_in_ZVALUE) and swap storage
346 */
347 dest->v = swap_b16_in_HALFs(NULL, src->v, src->len);
348
349 } else {
350
351 /*
352 * swap storage
353 */
354 if (dest->v != NULL) {
355 zfree(*dest);
356 }
357 dest->v = swap_b16_in_HALFs(NULL, src->v, src->len);
358 }
359
360 /*
361 * swap or copy the rest of the ZVALUE elements
362 */
363 if (all) {
364 SWAP_B16_IN_LEN(&dest->len, &src->len);
365 SWAP_B16_IN_BOOL(&dest->sign, &src->sign);
366 } else {
367 dest->len = src->len;
368 dest->sign = src->sign;
369 }
370
371 /*
372 * return the result
373 */
374 return dest;
375 }
376
377
378 /*
379 * swap_b16_in_NUMBER - swap 16 bits in a NUMBER
380 *
381 * given:
382 * dest - pointer to where the swapped src will be put or
383 * NULL to allocate the storage
384 * src - pointer to a NUMBER to swap
385 * all - TRUE => swap every element, FALSE => swap only the
386 * multi-precision storage
387 *
388 * returns:
389 * pointer to where the swapped src has been put
390 *
391 * This macro will either switch to the opposite byte sex (Big Endian vs.
392 * Little Endian) the elements of a NUMBER.
393 */
394 NUMBER *
swap_b16_in_NUMBER(NUMBER * dest,NUMBER * src,BOOL all)395 swap_b16_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all)
396 {
397 /*
398 * allocate storage if needed
399 */
400 if (dest == NULL) {
401
402 /*
403 * allocate the storage
404 */
405 dest = malloc(sizeof(NUMBER));
406 if (dest == NULL) {
407 math_error("swap_b16_in_NUMBER: Not enough memory");
408 /*NOTREACHED*/
409 }
410
411 /*
412 * allocate (by forcing swap_b16_in_ZVALUE) and swap storage
413 */
414 dest->num = *swap_b16_in_ZVALUE(NULL, &src->num, all);
415 dest->den = *swap_b16_in_ZVALUE(NULL, &src->den, all);
416
417 } else {
418
419 /*
420 * swap storage
421 */
422 dest->num = *swap_b16_in_ZVALUE(&dest->num, &src->num, all);
423 dest->den = *swap_b16_in_ZVALUE(&dest->den, &src->den, all);
424 }
425
426 /*
427 * swap or copy the rest of the NUMBER elements
428 */
429 if (all) {
430 SWAP_B16_IN_LONG(&dest->links, &src->links);
431 } else {
432 dest->links = src->links;
433 }
434
435 /*
436 * return the result
437 */
438 return dest;
439 }
440
441
442 /*
443 * swap_b16_in_COMPLEX - swap 16 bits in a COMPLEX
444 *
445 * given:
446 * dest - pointer to where the swapped src will be put or
447 * NULL to allocate the storage
448 * src - pointer to a COMPLEX to swap
449 * all - TRUE => swap every element, FALSE => swap only the
450 * multi-precision storage
451 *
452 * returns:
453 * pointer to where the swapped src has been put
454 *
455 * This macro will either switch to the opposite byte sex (Big Endian vs.
456 * Little Endian) the elements of a COMPLEX.
457 */
458 COMPLEX *
swap_b16_in_COMPLEX(COMPLEX * dest,COMPLEX * src,BOOL all)459 swap_b16_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all)
460 {
461 /*
462 * allocate storage if needed
463 */
464 if (dest == NULL) {
465
466 /*
467 * allocate the storage
468 */
469 dest = malloc(sizeof(COMPLEX));
470 if (dest == NULL) {
471 math_error("swap_b16_in_COMPLEX: Not enough memory");
472 /*NOTREACHED*/
473 }
474
475 /*
476 * allocate (by forcing swap_b16_in_ZVALUE) and swap storage
477 */
478 dest->real = swap_b16_in_NUMBER(NULL, src->real, all);
479 dest->imag = swap_b16_in_NUMBER(NULL, src->imag, all);
480
481 } else {
482
483 /*
484 * swap storage
485 */
486 dest->real = swap_b16_in_NUMBER(dest->real, src->real, all);
487 dest->imag = swap_b16_in_NUMBER(dest->imag, src->imag, all);
488 }
489
490 /*
491 * swap or copy the rest of the NUMBER elements
492 */
493 if (all) {
494 SWAP_B16_IN_LONG(&dest->links, &src->links);
495 } else {
496 dest->links = src->links;
497 }
498
499 /*
500 * return the result
501 */
502 return dest;
503 }
504
505
506 /*
507 * swap_HALF_in_ZVALUE - swap HALFs in a ZVALUE
508 *
509 * given:
510 * dest - pointer to where the swapped src will be put or
511 * NULL to allocate the storage
512 * src - pointer to a ZVALUE to swap
513 * all - TRUE => swap every element, FALSE => swap only the
514 * multi-precision storage
515 *
516 * returns:
517 * pointer to where the swapped src has been put
518 *
519 * This macro will either switch to the opposite byte sex (Big Endian vs.
520 * Little Endian) the elements of a ZVALUE.
521 */
522 ZVALUE *
swap_HALF_in_ZVALUE(ZVALUE * dest,ZVALUE * src,BOOL all)523 swap_HALF_in_ZVALUE(ZVALUE *dest, ZVALUE *src, BOOL all)
524 {
525 /*
526 * allocate storage if needed
527 */
528 if (dest == NULL) {
529
530 /*
531 * allocate the storage
532 */
533 dest = malloc(sizeof(ZVALUE));
534 if (dest == NULL) {
535 math_error("swap_HALF_in_ZVALUE: Not enough memory");
536 /*NOTREACHED*/
537 }
538
539 /*
540 * copy storage because we are dealing with HALFs
541 */
542 dest->v = (HALF *) zcopyval(*src, *dest);
543
544 } else {
545
546 /*
547 * copy storage because we are dealing with HALFs
548 */
549 if (dest->v != NULL) {
550 zfree(*dest);
551 dest->v = alloc(src->len);
552 }
553 zcopyval(*src, *dest);
554 }
555
556 /*
557 * swap or copy the rest of the ZVALUE elements
558 */
559 if (all) {
560 SWAP_HALF_IN_LEN(&dest->len, &src->len);
561 SWAP_HALF_IN_BOOL(&dest->sign, &src->sign);
562 } else {
563 dest->len = src->len;
564 dest->sign = src->sign;
565 }
566
567 /*
568 * return the result
569 */
570 return dest;
571 }
572
573
574 /*
575 * swap_HALF_in_NUMBER - swap HALFs in a NUMBER
576 *
577 * given:
578 * dest - pointer to where the swapped src will be put or
579 * NULL to allocate the storage
580 * src - pointer to a NUMBER to swap
581 * all - TRUE => swap every element, FALSE => swap only the
582 * multi-precision storage
583 *
584 * returns:
585 * pointer to where the swapped src has been put
586 *
587 * This macro will either switch to the opposite byte sex (Big Endian vs.
588 * Little Endian) the elements of a NUMBER.
589 */
590 NUMBER *
swap_HALF_in_NUMBER(NUMBER * dest,NUMBER * src,BOOL all)591 swap_HALF_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all)
592 {
593 /*
594 * allocate storage if needed
595 */
596 if (dest == NULL) {
597
598 /*
599 * allocate the storage
600 */
601 dest = malloc(sizeof(NUMBER));
602 if (dest == NULL) {
603 math_error("swap_HALF_in_NUMBER: Not enough memory");
604 /*NOTREACHED*/
605 }
606
607 /*
608 * allocate (by forcing swap_HALF_in_ZVALUE) and swap storage
609 */
610 dest->num = *swap_HALF_in_ZVALUE(NULL, &src->num, all);
611 dest->den = *swap_HALF_in_ZVALUE(NULL, &src->den, all);
612
613 } else {
614
615 /*
616 * swap storage
617 */
618 dest->num = *swap_HALF_in_ZVALUE(&dest->num, &src->num, all);
619 dest->den = *swap_HALF_in_ZVALUE(&dest->den, &src->den, all);
620 }
621
622 /*
623 * swap or copy the rest of the NUMBER elements
624 */
625 if (all) {
626 SWAP_HALF_IN_LONG(&dest->links, &src->links);
627 } else {
628 dest->links = src->links;
629 }
630
631 /*
632 * return the result
633 */
634 return dest;
635 }
636
637
638 /*
639 * swap_HALF_in_COMPLEX - swap HALFs in a COMPLEX
640 *
641 * given:
642 * dest - pointer to where the swapped src will be put or
643 * NULL to allocate the storage
644 * src - pointer to a COMPLEX to swap
645 * all - TRUE => swap every element, FALSE => swap only the
646 * multi-precision storage
647 *
648 * returns:
649 * pointer to where the swapped src has been put
650 *
651 * This macro will either switch to the opposite byte sex (Big Endian vs.
652 * Little Endian) the elements of a COMPLEX.
653 */
654 COMPLEX *
swap_HALF_in_COMPLEX(COMPLEX * dest,COMPLEX * src,BOOL all)655 swap_HALF_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all)
656 {
657 /*
658 * allocate storage if needed
659 */
660 if (dest == NULL) {
661
662 /*
663 * allocate the storage
664 */
665 dest = malloc(sizeof(COMPLEX));
666 if (dest == NULL) {
667 math_error("swap_HALF_in_COMPLEX: Not enough memory");
668 /*NOTREACHED*/
669 }
670
671 /*
672 * allocate (by forcing swap_HALF_in_ZVALUE) and swap storage
673 */
674 dest->real = swap_HALF_in_NUMBER(NULL, src->real, all);
675 dest->imag = swap_HALF_in_NUMBER(NULL, src->imag, all);
676
677 } else {
678
679 /*
680 * swap storage
681 */
682 dest->real = swap_HALF_in_NUMBER(dest->real, src->real, all);
683 dest->imag = swap_HALF_in_NUMBER(dest->imag, src->imag, all);
684 }
685
686 /*
687 * swap or copy the rest of the NUMBER elements
688 */
689 if (all) {
690 SWAP_HALF_IN_LONG(&dest->links, &src->links);
691 } else {
692 dest->links = src->links;
693 }
694
695 /*
696 * return the result
697 */
698 return dest;
699 }
700