GRASS 8 Programmer's Manual 8.6.0dev(2026)-1878fdfec5
Loading...
Searching...
No Matches
portable.c
Go to the documentation of this file.
1/*!
2 \file diglib/file.c
3
4 \brief Vector library - portability (lower level functions)
5
6 Lower level functions for reading/writing/manipulating vectors.
7
8 SPDX-FileCopyrightText: 2001-2009 GRASS Development Team
9 SPDX-License-Identifier: GPL-2.0-or-later
10
11 \author Original author CERL, probably Dave Gerdes
12 \author Update to GRASS 5.7 Radim Blazek
13 */
14
15#include <sys/types.h>
16#include <string.h>
17#include <grass/vector.h>
18#include <grass/glocale.h>
19
20extern void port_init(void);
21
22extern int nat_dbl;
23extern int nat_flt;
24extern int nat_lng;
25extern int nat_off_t;
26extern int nat_int;
27extern int nat_shrt;
28
29extern int dbl_order;
30extern int flt_order;
31extern int off_t_order;
32extern int lng_order;
33extern int int_order;
34extern int shrt_order;
35
36extern unsigned char dbl_cnvrt[sizeof(double)];
37extern unsigned char flt_cnvrt[sizeof(float)];
38extern unsigned char off_t_cnvrt[sizeof(off_t)];
39extern unsigned char lng_cnvrt[sizeof(long)];
40extern unsigned char int_cnvrt[sizeof(int)];
41extern unsigned char shrt_cnvrt[sizeof(short)];
42
44
45static char *buffer = NULL;
46static int buf_alloced = 0;
47
48static int buf_alloc(int needed)
49{
50 char *p;
51 int cnt;
52
53 if (needed <= buf_alloced)
54 return (0);
55 cnt = buf_alloced;
56 p = dig__alloc_space(needed, &cnt, 100, buffer, 1);
57 if (p == NULL)
58 return (dig_out_of_memory());
59 buffer = p;
60 buf_alloced = cnt;
61 return (0);
62}
63
64/*!
65 \brief Read doubles from the Portable Vector Format
66
67 These routines must handle any type size conversions between the
68 portable format and the native machine.
69
70 \param[out] buf data buffer
71 \param cnt number of members
72 \param fp pointer to struct gvfile
73
74 \return 0 error
75 \return 1 OK
76 */
77int dig__fread_port_D(double *buf, size_t cnt, struct gvfile *fp)
78{
79 unsigned int i, j;
80 int ret;
81 unsigned char *c1, *c2;
82
83 if (Cur_Head->dbl_quick) {
84 ret = dig_fread(buf, PORT_DOUBLE, cnt, fp);
85 if (ret != (int)cnt)
86 return 0;
87 }
88 else {
89 /* read into buffer */
90 buf_alloc(cnt * PORT_DOUBLE);
91 ret = dig_fread(buffer, PORT_DOUBLE, cnt, fp);
92 if (ret != (int)cnt)
93 return 0;
94 /* read from buffer in changed order */
95 c1 = (unsigned char *)buffer;
96 c2 = (unsigned char *)buf;
97 for (i = 0; i < cnt; i++) {
98 for (j = 0; j < PORT_DOUBLE; j++) {
99 c2[Cur_Head->dbl_cnvrt[j]] = c1[j];
100 }
101 c1 += PORT_DOUBLE;
102 c2 += sizeof(double);
103 }
104 }
105 return 1;
106}
107
108/*!
109 \brief Read floats from the Portable Vector Format
110
111 These routines must handle any type size conversions between the
112 portable format and the native machine.
113
114 \param[out] buf data buffer
115 \param cnt number of members
116 \param fp pointer to struct gvfile
117
118 \return 0 error
119 \return 1 OK
120 */
121int dig__fread_port_F(float *buf, size_t cnt, struct gvfile *fp)
122{
123 unsigned int i, j;
124 int ret;
125 unsigned char *c1, *c2;
126
127 if (Cur_Head->flt_quick) {
128 ret = dig_fread(buf, PORT_FLOAT, cnt, fp);
129 if (ret != (int)cnt)
130 return 0;
131 }
132 else {
133 /* read into buffer */
134 buf_alloc(cnt * PORT_FLOAT);
135 ret = dig_fread(buffer, PORT_FLOAT, cnt, fp);
136 if (ret != (int)cnt)
137 return 0;
138 /* read from buffer in changed order */
139 c1 = (unsigned char *)buffer;
140 c2 = (unsigned char *)buf;
141 for (i = 0; i < cnt; i++) {
142 for (j = 0; j < PORT_FLOAT; j++) {
143 c2[Cur_Head->flt_cnvrt[j]] = c1[j];
144 }
145 c1 += PORT_FLOAT;
146 c2 += sizeof(float);
147 }
148 }
149 return 1;
150}
151
152/*!
153 \brief Read off_ts from the Portable Vector Format
154
155 These routines must handle any type size conversions between the
156 portable format and the native machine.
157
158 \param[out] buf data buffer
159 \param cnt number of members
160 \param fp pointer to struct gvfile
161 \param port_off_t_size offset
162 \return 0 error
163 \return 1 OK
164 */
165int dig__fread_port_O(off_t *buf, size_t cnt, struct gvfile *fp,
166 size_t port_off_t_size)
167{
168 unsigned int i, j;
169 int ret;
170 unsigned char *c1, *c2;
171
172 if (Cur_Head->off_t_quick) {
173 if ((size_t)nat_off_t == port_off_t_size) {
174 ret = dig_fread(buf, port_off_t_size, cnt, fp);
175 if (ret != (int)cnt)
176 return 0;
177 }
178 else if ((size_t)nat_off_t > port_off_t_size) {
179 /* read into buffer */
180 buf_alloc(cnt * port_off_t_size);
181 ret = dig_fread(buffer, port_off_t_size, cnt, fp);
182 if (ret != (int)cnt)
183 return 0;
184 /* set buffer to zero (positive numbers) */
185 memset(buf, 0, cnt * sizeof(off_t));
186 /* read from buffer in changed order */
187 c1 = (unsigned char *)buffer;
188 c2 = (unsigned char *)buf;
189 for (i = 0; i < cnt; i++) {
190 /* set to FF if the value is negative */
191 if (off_t_order == ENDIAN_LITTLE) {
192 if (c1[port_off_t_size - 1] & 0x80)
193 memset(c2, 0xff, sizeof(off_t));
195 }
196 else {
197 if (c1[0] & 0x80)
198 memset(c2, 0xff, sizeof(off_t));
201 }
203 c2 += sizeof(off_t);
204 }
205 }
206 else if ((size_t)nat_off_t < port_off_t_size) {
207 /* should never happen */
208 G_fatal_error(_("Vector exceeds supported file size limit"));
209 }
210 }
211 else {
212 if ((size_t)nat_off_t >= port_off_t_size) {
213 /* read into buffer */
214 buf_alloc(cnt * port_off_t_size);
215 ret = dig_fread(buffer, port_off_t_size, cnt, fp);
216 if (ret != (int)cnt)
217 return 0;
218 /* set buffer to zero (positive numbers) */
219 memset(buf, 0, cnt * sizeof(off_t));
220 /* read from buffer in changed order */
221 c1 = (unsigned char *)buffer;
222 c2 = (unsigned char *)buf;
223 for (i = 0; i < cnt; i++) {
224 /* set to FF if the value is negative */
225 if (Cur_Head->byte_order == ENDIAN_LITTLE) {
226 if (c1[port_off_t_size - 1] & 0x80)
227 memset(c2, 0xff, sizeof(off_t));
228 }
229 else {
230 if (c1[0] & 0x80)
231 memset(c2, 0xff, sizeof(off_t));
232 }
233 for (j = 0; j < port_off_t_size; j++)
234 c2[Cur_Head->off_t_cnvrt[j]] = c1[j];
236 c2 += sizeof(off_t);
237 }
238 }
239 else if ((size_t)nat_off_t < port_off_t_size) {
240 /* should never happen */
241 G_fatal_error(_("Vector exceeds supported file size limit"));
242 }
243 }
244 return 1;
245}
246
247/*!
248 \brief Read longs from the Portable Vector Format
249
250 These routines must handle any type size conversions between the
251 portable format and the native machine.
252
253 \param[out] buf data buffer
254 \param cnt number of members
255 \param fp pointer to struct gvfile
256
257 \return 0 error
258 \return 1 OK
259 */
260int dig__fread_port_L(long *buf, size_t cnt, struct gvfile *fp)
261{
262 unsigned int i, j;
263 int ret;
264 unsigned char *c1, *c2;
265
266 if (Cur_Head->lng_quick) {
267 if (nat_lng == PORT_LONG) {
268 ret = dig_fread(buf, PORT_LONG, cnt, fp);
269 if (ret != (int)cnt)
270 return 0;
271 }
272 else {
273 /* read into buffer */
274 buf_alloc(cnt * PORT_LONG);
275 ret = dig_fread(buffer, PORT_LONG, cnt, fp);
276 if (ret != (int)cnt)
277 return 0;
278 /* set buffer to zero (positive numbers) */
279 memset(buf, 0, cnt * sizeof(long));
280 /* read from buffer in changed order */
281 c1 = (unsigned char *)buffer;
282 c2 = (unsigned char *)buf;
283 for (i = 0; i < cnt; i++) {
284 /* set to FF if the value is negative */
285 if (lng_order == ENDIAN_LITTLE) {
286 if (c1[PORT_LONG - 1] & 0x80)
287 memset(c2, 0xff, sizeof(long));
289 }
290 else {
291 if (c1[0] & 0x80)
292 memset(c2, 0xff, sizeof(long));
294 }
295 c1 += PORT_LONG;
296 c2 += sizeof(long);
297 }
298 }
299 }
300 else {
301 /* read into buffer */
302 buf_alloc(cnt * PORT_LONG);
303 ret = dig_fread(buffer, PORT_LONG, cnt, fp);
304 if (ret != (int)cnt)
305 return 0;
306 /* set buffer to zero (positive numbers) */
307 memset(buf, 0, cnt * sizeof(long));
308 /* read from buffer in changed order */
309 c1 = (unsigned char *)buffer;
310 c2 = (unsigned char *)buf;
311 for (i = 0; i < cnt; i++) {
312 /* set to FF if the value is negative */
313 if (Cur_Head->byte_order == ENDIAN_LITTLE) {
314 if (c1[PORT_LONG - 1] & 0x80)
315 memset(c2, 0xff, sizeof(long));
316 }
317 else {
318 if (c1[0] & 0x80)
319 memset(c2, 0xff, sizeof(long));
320 }
321 for (j = 0; j < PORT_LONG; j++)
322 c2[Cur_Head->lng_cnvrt[j]] = c1[j];
323 c1 += PORT_LONG;
324 c2 += sizeof(long);
325 }
326 }
327 return 1;
328}
329
330/*!
331 \brief Read integers from the Portable Vector Format
332
333 These routines must handle any type size conversions between the
334 portable format and the native machine.
335
336 \param[out] buf data buffer
337 \param cnt number of members
338 \param fp pointer to struct gvfile
339
340 \return 0 error
341 \return 1 OK
342 */
343int dig__fread_port_I(int *buf, size_t cnt, struct gvfile *fp)
344{
345 unsigned int i, j;
346 int ret;
347 unsigned char *c1, *c2;
348
349 if (Cur_Head->int_quick) {
350 if (nat_int == PORT_INT) {
351 ret = dig_fread(buf, PORT_INT, cnt, fp);
352 if (ret != (int)cnt)
353 return 0;
354 }
355 else {
356 /* read into buffer */
357 buf_alloc(cnt * PORT_INT);
358 ret = dig_fread(buffer, PORT_INT, cnt, fp);
359 if (ret != (int)cnt)
360 return 0;
361 /* set buffer to zero (positive numbers) */
362 memset(buf, 0, cnt * sizeof(int));
363 /* read from buffer in changed order */
364 c1 = (unsigned char *)buffer;
365 c2 = (unsigned char *)buf;
366 for (i = 0; i < cnt; i++) {
367 /* set to FF if the value is negative */
368 if (int_order == ENDIAN_LITTLE) {
369 if (c1[PORT_INT - 1] & 0x80)
370 memset(c2, 0xff, sizeof(int));
371 memcpy(c2, c1, PORT_INT);
372 }
373 else {
374 if (c1[0] & 0x80)
375 memset(c2, 0xff, sizeof(int));
377 }
378 c1 += PORT_INT;
379 c2 += sizeof(int);
380 }
381 }
382 }
383 else {
384 /* read into buffer */
385 buf_alloc(cnt * PORT_INT);
386 ret = dig_fread(buffer, PORT_INT, cnt, fp);
387 if (ret != (int)cnt)
388 return 0;
389 /* set buffer to zero (positive numbers) */
390 memset(buf, 0, cnt * sizeof(int));
391 /* read from buffer in changed order */
392 c1 = (unsigned char *)buffer;
393 c2 = (unsigned char *)buf;
394 for (i = 0; i < cnt; i++) {
395 /* set to FF if the value is negative */
396 if (Cur_Head->byte_order == ENDIAN_LITTLE) {
397 if (c1[PORT_INT - 1] & 0x80)
398 memset(c2, 0xff, sizeof(int));
399 }
400 else {
401 if (c1[0] & 0x80)
402 memset(c2, 0xff, sizeof(int));
403 }
404 for (j = 0; j < PORT_INT; j++)
405 c2[Cur_Head->int_cnvrt[j]] = c1[j];
406 c1 += PORT_INT;
407 c2 += sizeof(int);
408 }
409 }
410 return 1;
411}
412
413/*!
414 \brief Read shorts from the Portable Vector Format
415
416 These routines must handle any type size conversions between the
417 portable format and the native machine.
418
419 \param[out] buf data buffer
420 \param cnt number of members
421 \param fp pointer to struct gvfile
422
423 \return 0 error
424 \return 1 OK
425 */
426int dig__fread_port_S(short *buf, size_t cnt, struct gvfile *fp)
427{
428 unsigned int i, j;
429 int ret;
430 unsigned char *c1, *c2;
431
432 if (Cur_Head->shrt_quick) {
433 if (nat_shrt == PORT_SHORT) {
434 ret = dig_fread(buf, PORT_SHORT, cnt, fp);
435 if (ret != (int)cnt)
436 return 0;
437 }
438 else {
439 /* read into buffer */
440 buf_alloc(cnt * PORT_SHORT);
441 if (0 >= (ret = dig_fread(buffer, PORT_SHORT, cnt, fp)))
442 if (ret != (int)cnt)
443 return 0;
444 /* set buffer to zero (positive numbers) */
445 memset(buf, 0, cnt * sizeof(short));
446 /* read from buffer in changed order */
447 c1 = (unsigned char *)buffer;
448 c2 = (unsigned char *)buf;
449 for (i = 0; i < cnt; i++) {
450 /* set to FF if the value is negative */
451 if (shrt_order == ENDIAN_LITTLE) {
452 if (c1[PORT_SHORT - 1] & 0x80)
453 memset(c2, 0xff, sizeof(short));
455 }
456 else {
457 if (c1[0] & 0x80)
458 memset(c2, 0xff, sizeof(short));
460 }
461 c1 += PORT_SHORT;
462 c2 += sizeof(short);
463 }
464 }
465 }
466 else {
467 /* read into buffer */
468 buf_alloc(cnt * PORT_SHORT);
469 ret = dig_fread(buffer, PORT_SHORT, cnt, fp);
470 if (ret != (int)cnt)
471 return 0;
472 /* set buffer to zero (positive numbers) */
473 memset(buf, 0, cnt * sizeof(short));
474 /* read from buffer in changed order */
475 c1 = (unsigned char *)buffer;
476 c2 = (unsigned char *)buf;
477 for (i = 0; i < cnt; i++) {
478 /* set to FF if the value is negative */
479 if (Cur_Head->byte_order == ENDIAN_LITTLE) {
480 if (c1[PORT_SHORT - 1] & 0x80)
481 memset(c2, 0xff, sizeof(short));
482 }
483 else {
484 if (c1[0] & 0x80)
485 memset(c2, 0xff, sizeof(short));
486 }
487 for (j = 0; j < PORT_SHORT; j++)
488 c2[Cur_Head->shrt_cnvrt[j]] = c1[j];
489 c1 += PORT_SHORT;
490 c2 += sizeof(short);
491 }
492 }
493 return 1;
494}
495
496/*!
497 \brief Read chars from the Portable Vector Format
498
499 These routines must handle any type size conversions between the
500 portable format and the native machine.
501
502 \param[out] buf data buffer
503 \param cnt number of members
504 \param fp pointer to gvfile structure
505
506 \return 0 error
507 \return 1 OK
508 */
509int dig__fread_port_C(char *buf, size_t cnt, struct gvfile *fp)
510{
511 int ret;
512
513 ret = dig_fread(buf, PORT_CHAR, cnt, fp);
514 if (ret != (int)cnt)
515 return 0;
516 return 1;
517}
518
519/*!
520 \brief Read plus_t from the Portable Vector Format
521
522 These routines must handle any type size conversions between the
523 portable format and the native machine.
524
525 plus_t is defined as int so we only retype pointer and use int
526 function.
527
528 \param[out] buf data buffer
529 \param cnt number of members
530 \param fp pointer to struct gvfile
531
532 \return 0 error
533 \return 1 OK
534 */
535int dig__fread_port_P(plus_t *buf, size_t cnt, struct gvfile *fp)
536{
537 int *ibuf;
538
539 ibuf = (int *)buf;
540
541 return (dig__fread_port_I(ibuf, cnt, fp));
542}
543
544/*!
545 \brief Write doubles to the Portable Vector Format
546
547 These routines must handle any type size conversions between the
548 portable format and the native machine.
549
550 \param buf data buffer
551 \param cnt number of members
552 \param[in,out] fp pointer to struct gvfile
553
554 \return 0 error
555 \return 1 OK
556 */
557int dig__fwrite_port_D(const double *buf, size_t cnt, struct gvfile *fp)
558{
559 unsigned int i, j;
560 unsigned char *c1, *c2;
561
562 if (Cur_Head->dbl_quick) {
563 if (dig_fwrite(buf, PORT_DOUBLE, cnt, fp) == cnt)
564 return 1;
565 }
566 else {
567 buf_alloc(cnt * PORT_DOUBLE);
568 c1 = (unsigned char *)buf;
569 c2 = (unsigned char *)buffer;
570 for (i = 0; i < cnt; i++) {
571 for (j = 0; j < PORT_DOUBLE; j++)
572 c2[j] = c1[Cur_Head->dbl_cnvrt[j]];
573 c1 += sizeof(double);
574 c2 += PORT_DOUBLE;
575 }
576 if (dig_fwrite(buffer, PORT_DOUBLE, cnt, fp) == cnt)
577 return 1;
578 }
579 return 0;
580}
581
582/*!
583 \brief Write floats to the Portable Vector Format
584
585 These routines must handle any type size conversions between the
586 portable format and the native machine.
587
588 \param buf data buffer
589 \param cnt number of members
590 \param[in,out] fp pointer to struct gvfile
591
592 \return 0 error
593 \return 1 OK
594 */
595int dig__fwrite_port_F(const float *buf, size_t cnt, struct gvfile *fp)
596{
597 unsigned int i, j;
598 unsigned char *c1, *c2;
599
600 if (Cur_Head->flt_quick) {
601 if (dig_fwrite(buf, PORT_FLOAT, cnt, fp) == cnt)
602 return 1;
603 }
604 else {
605 buf_alloc(cnt * PORT_FLOAT);
606 c1 = (unsigned char *)buf;
607 c2 = (unsigned char *)buffer;
608 for (i = 0; i < cnt; i++) {
609 for (j = 0; j < PORT_FLOAT; j++)
610 c2[j] = c1[Cur_Head->flt_cnvrt[j]];
611 c1 += sizeof(float);
612 c2 += PORT_FLOAT;
613 }
614 if (dig_fwrite(buffer, PORT_FLOAT, cnt, fp) == cnt)
615 return 1;
616 }
617 return 0;
618}
619
620/*!
621 \brief Write off_ts to the Portable Vector Format
622
623 These routines must handle any type size conversions between the
624 portable format and the native machine.
625
626 \param buf data buffer
627 \param cnt number of members
628 \param[in,out] fp pointer to struct gvfile
629 \param port_off_t_size
630
631 \return 0 error
632 \return 1 OK
633 */
634int dig__fwrite_port_O(const off_t *buf, size_t cnt, struct gvfile *fp,
635 size_t port_off_t_size)
636{
637 unsigned int i, j;
638 unsigned char *c1, *c2;
639
640 if (Cur_Head->off_t_quick) {
641 if ((size_t)nat_off_t == port_off_t_size) {
642 if (dig_fwrite(buf, port_off_t_size, cnt, fp) == cnt)
643 return 1;
644 }
645 else if ((size_t)nat_off_t > port_off_t_size) {
646 buf_alloc(cnt * port_off_t_size);
647 c1 = (unsigned char *)buf;
648 c2 = (unsigned char *)buffer;
649 for (i = 0; i < cnt; i++) {
652 else
655 c1 += sizeof(off_t);
657 }
658 if (dig_fwrite(buffer, port_off_t_size, cnt, fp) == cnt)
659 return 1;
660 }
661 else if ((size_t)nat_off_t < port_off_t_size) {
662 /* should never happen */
663 G_fatal_error("Vector exceeds supported file size limit");
664 }
665 }
666 else {
667 if ((size_t)nat_off_t >= port_off_t_size) {
668 buf_alloc(cnt * port_off_t_size);
669 c1 = (unsigned char *)buf;
670 c2 = (unsigned char *)buffer;
671 for (i = 0; i < cnt; i++) {
672 for (j = 0; j < port_off_t_size; j++)
673 c2[j] = c1[Cur_Head->off_t_cnvrt[j]];
674 c1 += sizeof(off_t);
676 }
677 if (dig_fwrite(buffer, port_off_t_size, cnt, fp) == cnt)
678 return 1;
679 }
680 else if ((size_t)nat_off_t < port_off_t_size) {
681 /* should never happen */
682 G_fatal_error(_("Vector exceeds supported file size limit"));
683 }
684 }
685 return 0;
686}
687
688/*!
689 \brief Write longs to the Portable Vector Format
690
691 These routines must handle any type size conversions between the
692 portable format and the native machine.
693
694 \param buf data buffer
695 \param cnt number of members
696 \param[in,out] fp pointer to struct gvfile
697
698 \return 0 error
699 \return 1 OK
700 */
701int dig__fwrite_port_L(const long *buf, size_t cnt, struct gvfile *fp)
702{
703 unsigned int i, j;
704 unsigned char *c1, *c2;
705
706 if (Cur_Head->lng_quick) {
707 if (nat_lng == PORT_LONG) {
708 if (dig_fwrite(buf, PORT_LONG, cnt, fp) == cnt)
709 return 1;
710 }
711 else {
712 buf_alloc(cnt * PORT_LONG);
713 c1 = (unsigned char *)buf;
714 c2 = (unsigned char *)buffer;
715 for (i = 0; i < cnt; i++) {
718 else
720 c1 += sizeof(long);
721 c2 += PORT_LONG;
722 }
723 if (dig_fwrite(buffer, PORT_LONG, cnt, fp) == cnt)
724 return 1;
725 }
726 }
727 else {
728 buf_alloc(cnt * PORT_LONG);
729 c1 = (unsigned char *)buf;
730 c2 = (unsigned char *)buffer;
731 for (i = 0; i < cnt; i++) {
732 for (j = 0; j < PORT_LONG; j++)
733 c2[j] = c1[Cur_Head->lng_cnvrt[j]];
734 c1 += sizeof(long);
735 c2 += PORT_LONG;
736 }
737 if (dig_fwrite(buffer, PORT_LONG, cnt, fp) == cnt)
738 return 1;
739 }
740 return 0;
741}
742
743/*!
744 \brief Write integers to the Portable Vector Format
745
746 These routines must handle any type size conversions between the
747 portable format and the native machine.
748
749 \param buf data buffer
750 \param cnt number of members
751 \param[in,out] fp pointer to struct gvfile
752
753 \return 0 error
754 \return 1 OK
755 */
756int dig__fwrite_port_I(const int *buf, size_t cnt, struct gvfile *fp)
757{
758 unsigned int i, j;
759 unsigned char *c1, *c2;
760
761 if (Cur_Head->int_quick) {
762 if (nat_int == PORT_INT) {
763 if (dig_fwrite(buf, PORT_INT, cnt, fp) == cnt)
764 return 1;
765 }
766 else {
767 buf_alloc(cnt * PORT_INT);
768 c1 = (unsigned char *)buf;
769 c2 = (unsigned char *)buffer;
770 for (i = 0; i < cnt; i++) {
772 memcpy(c2, c1, PORT_INT);
773 else
775 c1 += sizeof(int);
776 c2 += PORT_INT;
777 }
778 if (dig_fwrite(buffer, PORT_INT, cnt, fp) == cnt)
779 return 1;
780 }
781 }
782 else {
783 buf_alloc(cnt * PORT_INT);
784 c1 = (unsigned char *)buf;
785 c2 = (unsigned char *)buffer;
786 for (i = 0; i < cnt; i++) {
787 for (j = 0; j < PORT_INT; j++)
788 c2[j] = c1[Cur_Head->int_cnvrt[j]];
789 c1 += sizeof(int);
790 c2 += PORT_INT;
791 }
792 if (dig_fwrite(buffer, PORT_INT, cnt, fp) == cnt)
793 return 1;
794 }
795 return 0;
796}
797
798/*!
799 \brief Write shorts to the Portable Vector Format
800
801 These routines must handle any type size conversions between the
802 portable format and the native machine.
803
804 \param buf data buffer
805 \param cnt number of members
806 \param[in,out] fp pointer to struct gvfile
807
808 \return 0 error
809 \return 1 OK
810 */
811int dig__fwrite_port_S(const short *buf, size_t cnt, struct gvfile *fp)
812{
813 unsigned int i, j;
814 unsigned char *c1, *c2;
815
816 if (Cur_Head->shrt_quick) {
817 if (nat_shrt == PORT_SHORT) {
818 if (dig_fwrite(buf, PORT_SHORT, cnt, fp) == cnt)
819 return 1;
820 }
821 else {
822 buf_alloc(cnt * PORT_SHORT);
823 c1 = (unsigned char *)buf;
824 c2 = (unsigned char *)buffer;
825 for (i = 0; i < cnt; i++) {
828 else
830 c1 += sizeof(short);
831 c2 += PORT_SHORT;
832 }
833 if (dig_fwrite(buffer, PORT_SHORT, cnt, fp) == cnt)
834 return 1;
835 }
836 }
837 else {
838 buf_alloc(cnt * PORT_SHORT);
839 c1 = (unsigned char *)buf;
840 c2 = (unsigned char *)buffer;
841 for (i = 0; i < cnt; i++) {
842 for (j = 0; j < PORT_SHORT; j++)
843 c2[j] = c1[Cur_Head->shrt_cnvrt[j]];
844 c1 += sizeof(short);
845 c2 += PORT_SHORT;
846 }
847 if (dig_fwrite(buffer, PORT_SHORT, cnt, fp) == cnt)
848 return 1;
849 }
850 return 0;
851}
852
853/*!
854 \brief Write plus_t to the Portable Vector Format
855
856 These routines must handle any type size conversions between the
857 portable format and the native machine.
858
859 \param buf data buffer
860 \param cnt number of members
861 \param[in,out] fp pointer to struct gvfile
862
863 \return 0 error
864 \return 1 OK
865 */
866int dig__fwrite_port_P(const plus_t *buf, size_t cnt, struct gvfile *fp)
867{
868 return (dig__fwrite_port_I((int *)buf, cnt, fp));
869}
870
871/*!
872 \brief Write chars to the Portable Vector Format
873
874 These routines must handle any type size conversions between the
875 portable format and the native machine.
876
877 \param buf data buffer
878 \param cnt number of members
879 \param[in,out] fp pointer to struct gvfile
880
881 \return 0 error
882 \return 1 OK
883 */
884int dig__fwrite_port_C(const char *buf, size_t cnt, struct gvfile *fp)
885{
886 if (dig_fwrite(buf, PORT_CHAR, cnt, fp) == cnt)
887 return 1;
888
889 return 0;
890}
891
892/*!
893 \brief Set Port_info structure to byte order of file
894
895 \param port pointer to Port_info structure
896 \param byte_order ENDIAN_BIG or ENDIAN_LITTLE
897 */
899{
900 unsigned int i;
901
902 port_init();
903
904 port->byte_order = byte_order;
905
906 /* double */
907 if (port->byte_order == dbl_order)
908 port->dbl_quick = TRUE;
909 else
910 port->dbl_quick = FALSE;
911
912 for (i = 0; i < PORT_DOUBLE; i++) {
913 if (port->byte_order == ENDIAN_BIG)
914 port->dbl_cnvrt[i] = dbl_cnvrt[i];
915 else
916 port->dbl_cnvrt[i] = dbl_cnvrt[PORT_DOUBLE - i - 1];
917 }
918
919 /* float */
920 if (port->byte_order == flt_order)
921 port->flt_quick = TRUE;
922 else
923 port->flt_quick = FALSE;
924
925 for (i = 0; i < PORT_FLOAT; i++) {
926 if (port->byte_order == ENDIAN_BIG)
927 port->flt_cnvrt[i] = flt_cnvrt[i];
928 else
929 port->flt_cnvrt[i] = flt_cnvrt[PORT_FLOAT - i - 1];
930 }
931
932 /* long */
933 if (port->byte_order == lng_order)
934 port->lng_quick = TRUE;
935 else
936 port->lng_quick = FALSE;
937
938 for (i = 0; i < PORT_LONG; i++) {
939 if (port->byte_order == ENDIAN_BIG)
940 port->lng_cnvrt[i] = lng_cnvrt[i];
941 else
942 port->lng_cnvrt[i] = lng_cnvrt[PORT_LONG - i - 1];
943 }
944
945 /* int */
946 if (port->byte_order == int_order)
947 port->int_quick = TRUE;
948 else
949 port->int_quick = FALSE;
950
951 for (i = 0; i < PORT_INT; i++) {
952 if (port->byte_order == ENDIAN_BIG)
953 port->int_cnvrt[i] = int_cnvrt[i];
954 else
955 port->int_cnvrt[i] = int_cnvrt[PORT_INT - i - 1];
956 }
957
958 /* short */
959 if (port->byte_order == shrt_order)
960 port->shrt_quick = TRUE;
961 else
962 port->shrt_quick = FALSE;
963
964 for (i = 0; i < PORT_SHORT; i++) {
965 if (port->byte_order == ENDIAN_BIG)
966 port->shrt_cnvrt[i] = shrt_cnvrt[i];
967 else
968 port->shrt_cnvrt[i] = shrt_cnvrt[PORT_SHORT - i - 1];
969 }
970
971 /* off_t */
972 if (port->byte_order == off_t_order)
973 port->off_t_quick = TRUE;
974 else
975 port->off_t_quick = FALSE;
976
977 for (i = 0; i < (size_t)nat_off_t; i++) {
978 if (port->byte_order == ENDIAN_BIG)
979 port->off_t_cnvrt[i] = off_t_cnvrt[i];
980 else
981 port->off_t_cnvrt[i] = off_t_cnvrt[nat_off_t - i - 1];
982 }
983
984 return;
985}
986
987/*!
988 \brief Set current Port_info structure
989
990 \param port pointer to Port_info structure
991
992 \return 0
993 */
995{
996 Cur_Head = port;
997 return 0;
998}
999
1000/*!
1001 \brief Get byte order
1002
1003 \return ENDIAN_LITTLE
1004 \return ENDIAN_BIG
1005 */
1007{
1008 if (dbl_order == ENDIAN_LITTLE)
1009 return (ENDIAN_LITTLE);
1010 else
1011 return (ENDIAN_BIG);
1012}
#define NULL
Definition ccmath.h:32
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
#define PORT_LONG
Definition dig_defines.h:47
#define PORT_SHORT
Definition dig_defines.h:49
#define PORT_DOUBLE
Sizes of types used in portable format (different names used in Vlib/ and diglib/ for the same thing)
Definition dig_defines.h:45
#define PORT_FLOAT
Definition dig_defines.h:46
#define PORT_INT
Definition dig_defines.h:48
#define PORT_CHAR
Definition dig_defines.h:50
size_t dig_fwrite(const void *ptr, size_t size, size_t nmemb, struct gvfile *file)
Write struct gvfile.
Definition file.c:154
size_t dig_fread(void *ptr, size_t size, size_t nmemb, struct gvfile *file)
Read struct gvfile.
Definition file.c:122
void * dig__alloc_space(int, int *, int, void *, int)
Definition allocation.c:45
int dig_out_of_memory(void)
For now just print message and return error code.
int plus_t
plus_t size
Definition dig_structs.h:39
#define ENDIAN_LITTLE
Endian check.
Definition gis.h:412
#define TRUE
Definition gis.h:75
#define FALSE
Definition gis.h:79
#define ENDIAN_BIG
Definition gis.h:413
#define _(str)
Definition glocale.h:10
int dig__fread_port_S(short *buf, size_t cnt, struct gvfile *fp)
Read shorts from the Portable Vector Format.
Definition portable.c:426
unsigned char flt_cnvrt[sizeof(float)]
Definition port_init.c:124
int dig__fwrite_port_F(const float *buf, size_t cnt, struct gvfile *fp)
Write floats to the Portable Vector Format.
Definition portable.c:595
int dig__fread_port_O(off_t *buf, size_t cnt, struct gvfile *fp, size_t port_off_t_size)
Read off_ts from the Portable Vector Format.
Definition portable.c:165
int dig__fread_port_D(double *buf, size_t cnt, struct gvfile *fp)
Read doubles from the Portable Vector Format.
Definition portable.c:77
int nat_lng
Definition port_init.c:112
int dig__fread_port_C(char *buf, size_t cnt, struct gvfile *fp)
Read chars from the Portable Vector Format.
Definition portable.c:509
int dig__byte_order_out(void)
Get byte order.
Definition portable.c:1006
int shrt_order
Definition port_init.c:121
int dig__fread_port_L(long *buf, size_t cnt, struct gvfile *fp)
Read longs from the Portable Vector Format.
Definition portable.c:260
unsigned char dbl_cnvrt[sizeof(double)]
Definition port_init.c:123
int flt_order
Definition port_init.c:117
int dig__fread_port_P(plus_t *buf, size_t cnt, struct gvfile *fp)
Read plus_t from the Portable Vector Format.
Definition portable.c:535
int dbl_order
Definition port_init.c:116
int int_order
Definition port_init.c:120
int nat_dbl
Definition port_init.c:109
unsigned char lng_cnvrt[sizeof(long)]
Definition port_init.c:126
int off_t_order
Definition port_init.c:118
int dig__fwrite_port_S(const short *buf, size_t cnt, struct gvfile *fp)
Write shorts to the Portable Vector Format.
Definition portable.c:811
int lng_order
Definition port_init.c:119
int dig__fwrite_port_I(const int *buf, size_t cnt, struct gvfile *fp)
Write integers to the Portable Vector Format.
Definition portable.c:756
int dig__fwrite_port_D(const double *buf, size_t cnt, struct gvfile *fp)
Write doubles to the Portable Vector Format.
Definition portable.c:557
unsigned char off_t_cnvrt[sizeof(off_t)]
Definition port_init.c:125
struct Port_info * Cur_Head
Definition portable.c:43
int dig__fread_port_I(int *buf, size_t cnt, struct gvfile *fp)
Read integers from the Portable Vector Format.
Definition portable.c:343
int nat_off_t
Definition port_init.c:111
int nat_shrt
Definition port_init.c:114
int nat_int
Definition port_init.c:113
void dig_init_portable(struct Port_info *port, int byte_order)
Set Port_info structure to byte order of file.
Definition portable.c:898
unsigned char shrt_cnvrt[sizeof(short)]
Definition port_init.c:128
int dig_set_cur_port(struct Port_info *port)
Set current Port_info structure.
Definition portable.c:994
int dig__fwrite_port_C(const char *buf, size_t cnt, struct gvfile *fp)
Write chars to the Portable Vector Format.
Definition portable.c:884
void port_init(void)
Initialize Port_info structures.
Definition port_init.c:183
int dig__fwrite_port_O(const off_t *buf, size_t cnt, struct gvfile *fp, size_t port_off_t_size)
Write off_ts to the Portable Vector Format.
Definition portable.c:634
int dig__fwrite_port_L(const long *buf, size_t cnt, struct gvfile *fp)
Write longs to the Portable Vector Format.
Definition portable.c:701
unsigned char int_cnvrt[sizeof(int)]
Definition port_init.c:127
int dig__fread_port_F(float *buf, size_t cnt, struct gvfile *fp)
Read floats from the Portable Vector Format.
Definition portable.c:121
int nat_flt
Definition port_init.c:110
int dig__fwrite_port_P(const plus_t *buf, size_t cnt, struct gvfile *fp)
Write plus_t to the Portable Vector Format.
Definition portable.c:866
Portability info.
unsigned char flt_cnvrt[PORT_FLOAT]
Conversion matrices between file and native byte order (float)
int flt_quick
Quick reading flag for float.
unsigned char lng_cnvrt[PORT_LONG]
Conversion matrices between file and native byte order (long)
int dbl_quick
Quick reading flag for double.
unsigned char off_t_cnvrt[PORT_OFF_T]
Conversion matrices between file and native byte order (off_t)
unsigned char int_cnvrt[PORT_INT]
Conversion matrices between file and native byte order (int)
int off_t_quick
Quick reading flag for off_t.
int lng_quick
Quick reading flag for long.
int int_quick
Quick reading flag for int.
unsigned char shrt_cnvrt[PORT_SHORT]
Conversion matrices between file and native byte order (short)
unsigned char dbl_cnvrt[PORT_DOUBLE]
Conversion matrices between file and native byte order (double)
int shrt_quick
Quick reading flag for short.
int byte_order
File byte order.
File definition.
Definition dig_structs.h:92