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