GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
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 
22 extern void port_init(void);
23 
24 extern int nat_dbl;
25 extern int nat_flt;
26 extern int nat_lng;
27 extern int nat_off_t;
28 extern int nat_int;
29 extern int nat_shrt;
30 
31 extern int dbl_order;
32 extern int flt_order;
33 extern int off_t_order;
34 extern int lng_order;
35 extern int int_order;
36 extern int shrt_order;
37 
38 extern unsigned char dbl_cnvrt[sizeof(double)];
39 extern unsigned char flt_cnvrt[sizeof(float)];
40 extern unsigned char off_t_cnvrt[sizeof(off_t)];
41 extern unsigned char lng_cnvrt[sizeof(long)];
42 extern unsigned char int_cnvrt[sizeof(int)];
43 extern unsigned char shrt_cnvrt[sizeof(short)];
44 
46 
47 static char *buffer = NULL;
48 static int buf_alloced = 0;
49 
50 static 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 */
79 int 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 */
123 int 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 */
167 int dig__fread_port_O(off_t *buf, size_t cnt, struct gvfile * fp, size_t port_off_t_size)
168 {
169  unsigned int i, j;
170  int ret;
171  unsigned char *c1, *c2;
172 
173  if (Cur_Head->off_t_quick) {
174  if (nat_off_t == port_off_t_size) {
175  ret = dig_fread(buf, port_off_t_size, cnt, fp);
176  if (ret != (int) cnt)
177  return 0;
178  }
179  else if (nat_off_t > port_off_t_size) {
180  /* read into buffer */
181  buf_alloc(cnt * port_off_t_size);
182  ret = dig_fread(buffer, port_off_t_size, cnt, fp);
183  if (ret != (int) cnt)
184  return 0;
185  /* set buffer to zero (positive numbers) */
186  memset(buf, 0, cnt * sizeof(off_t));
187  /* read from buffer in changed order */
188  c1 = (unsigned char *)buffer;
189  c2 = (unsigned char *)buf;
190  for (i = 0; i < cnt; i++) {
191  /* set to FF if the value is negative */
192  if (off_t_order == ENDIAN_LITTLE) {
193  if (c1[port_off_t_size - 1] & 0x80)
194  memset(c2, 0xff, sizeof(off_t));
195  memcpy(c2, c1, port_off_t_size);
196  }
197  else {
198  if (c1[0] & 0x80)
199  memset(c2, 0xff, sizeof(off_t));
200  memcpy(c2 + nat_off_t - port_off_t_size, c1, port_off_t_size);
201  }
202  c1 += port_off_t_size;
203  c2 += sizeof(off_t);
204  }
205  }
206  else if (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 (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];
235  c1 += port_off_t_size;
236  c2 += sizeof(off_t);
237  }
238  }
239  else if (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 */
260 int 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));
288  memcpy(c2, c1, PORT_LONG);
289  }
290  else {
291  if (c1[0] & 0x80)
292  memset(c2, 0xff, sizeof(long));
293  memcpy(c2 + nat_lng - PORT_LONG, c1, PORT_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 */
343 int 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));
376  memcpy(c2 + nat_int - PORT_INT, c1, PORT_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 */
426 int 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));
454  memcpy(c2, c1, PORT_SHORT);
455  }
456  else {
457  if (c1[0] & 0x80)
458  memset(c2, 0xff, sizeof(short));
459  memcpy(c2 + nat_shrt - PORT_SHORT, c1, PORT_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 */
509 int 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 */
535 int 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 */
557 int dig__fwrite_port_D(const double *buf,
558  size_t cnt, struct gvfile * fp)
559 {
560  unsigned int i, j;
561  unsigned char *c1, *c2;
562 
563  if (Cur_Head->dbl_quick) {
564  if (dig_fwrite(buf, PORT_DOUBLE, cnt, fp) == cnt)
565  return 1;
566  }
567  else {
568  buf_alloc(cnt * PORT_DOUBLE);
569  c1 = (unsigned char *)buf;
570  c2 = (unsigned char *)buffer;
571  for (i = 0; i < cnt; i++) {
572  for (j = 0; j < PORT_DOUBLE; j++)
573  c2[j] = c1[Cur_Head->dbl_cnvrt[j]];
574  c1 += sizeof(double);
575  c2 += PORT_DOUBLE;
576  }
577  if (dig_fwrite(buffer, PORT_DOUBLE, cnt, fp) == cnt)
578  return 1;
579  }
580  return 0;
581 }
582 
583 /*!
584  \brief Write floats to the Portable Vector Format
585 
586  These routines must handle any type size conversions between the
587  portable format and the native machine.
588 
589  \param buf data buffer
590  \param cnt number of members
591  \param[in,out] fp pointer to struct gvfile
592 
593  \return 0 error
594  \return 1 OK
595 */
596 int dig__fwrite_port_F(const float *buf,
597  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 */
636 int dig__fwrite_port_O(const off_t *buf,
637  size_t cnt, struct gvfile * fp, 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 (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 (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++) {
652  if (off_t_order == ENDIAN_LITTLE)
653  memcpy(c2, c1, port_off_t_size);
654  else
655  memcpy(c2, c1 + nat_off_t - port_off_t_size, port_off_t_size);
656  c1 += sizeof(off_t);
657  c2 += port_off_t_size;
658  }
659  if (dig_fwrite(buffer, port_off_t_size, cnt, fp) == cnt)
660  return 1;
661  }
662  else if (nat_off_t < port_off_t_size) {
663  /* should never happen */
664  G_fatal_error("Vector exceeds supported file size limit");
665  }
666  }
667  else {
668  if (nat_off_t >= port_off_t_size) {
669  buf_alloc(cnt * port_off_t_size);
670  c1 = (unsigned char *)buf;
671  c2 = (unsigned char *)buffer;
672  for (i = 0; i < cnt; i++) {
673  for (j = 0; j < port_off_t_size; j++)
674  c2[j] = c1[Cur_Head->off_t_cnvrt[j]];
675  c1 += sizeof(off_t);
676  c2 += port_off_t_size;
677  }
678  if (dig_fwrite(buffer, port_off_t_size, cnt, fp) == cnt)
679  return 1;
680  }
681  else if (nat_off_t < port_off_t_size) {
682  /* should never happen */
683  G_fatal_error(_("Vector exceeds supported file size limit"));
684  }
685  }
686  return 0;
687 }
688 
689 /*!
690  \brief Write longs to the Portable Vector Format
691 
692  These routines must handle any type size conversions between the
693  portable format and the native machine.
694 
695  \param buf data buffer
696  \param cnt number of members
697  \param[in,out] fp pointer to struct gvfile
698 
699  \return 0 error
700  \return 1 OK
701 */
702 int dig__fwrite_port_L(const long *buf,
703  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++) {
718  if (lng_order == ENDIAN_LITTLE)
719  memcpy(c2, c1, PORT_LONG);
720  else
721  memcpy(c2, c1 + nat_lng - PORT_LONG, PORT_LONG);
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 */
758 int dig__fwrite_port_I(const int *buf,
759  size_t cnt, struct gvfile * fp)
760 {
761  unsigned int i, j;
762  unsigned char *c1, *c2;
763 
764  if (Cur_Head->int_quick) {
765  if (nat_int == PORT_INT) {
766  if (dig_fwrite(buf, PORT_INT, cnt, fp) == cnt)
767  return 1;
768  }
769  else {
770  buf_alloc(cnt * PORT_INT);
771  c1 = (unsigned char *)buf;
772  c2 = (unsigned char *)buffer;
773  for (i = 0; i < cnt; i++) {
774  if (int_order == ENDIAN_LITTLE)
775  memcpy(c2, c1, PORT_INT);
776  else
777  memcpy(c2, c1 + nat_int - PORT_INT, PORT_INT);
778  c1 += sizeof(int);
779  c2 += PORT_INT;
780  }
781  if (dig_fwrite(buffer, PORT_INT, cnt, fp) == cnt)
782  return 1;
783  }
784  }
785  else {
786  buf_alloc(cnt * PORT_INT);
787  c1 = (unsigned char *)buf;
788  c2 = (unsigned char *)buffer;
789  for (i = 0; i < cnt; i++) {
790  for (j = 0; j < PORT_INT; j++)
791  c2[j] = c1[Cur_Head->int_cnvrt[j]];
792  c1 += sizeof(int);
793  c2 += PORT_INT;
794  }
795  if (dig_fwrite(buffer, PORT_INT, cnt, fp) == cnt)
796  return 1;
797  }
798  return 0;
799 }
800 
801 /*!
802  \brief Write shorts to the Portable Vector Format
803 
804  These routines must handle any type size conversions between the
805  portable format and the native machine.
806 
807  \param buf data buffer
808  \param cnt number of members
809  \param[in,out] fp pointer to struct gvfile
810 
811  \return 0 error
812  \return 1 OK
813 */
814 int dig__fwrite_port_S(const short *buf,
815  size_t cnt, struct gvfile * fp)
816 {
817  unsigned int i, j;
818  unsigned char *c1, *c2;
819 
820  if (Cur_Head->shrt_quick) {
821  if (nat_shrt == PORT_SHORT) {
822  if (dig_fwrite(buf, PORT_SHORT, cnt, fp) == cnt)
823  return 1;
824  }
825  else {
826  buf_alloc(cnt * PORT_SHORT);
827  c1 = (unsigned char *)buf;
828  c2 = (unsigned char *)buffer;
829  for (i = 0; i < cnt; i++) {
830  if (shrt_order == ENDIAN_LITTLE)
831  memcpy(c2, c1, PORT_SHORT);
832  else
833  memcpy(c2, c1 + nat_shrt - PORT_SHORT, PORT_SHORT);
834  c1 += sizeof(short);
835  c2 += PORT_SHORT;
836  }
837  if (dig_fwrite(buffer, PORT_SHORT, cnt, fp) == cnt)
838  return 1;
839  }
840  }
841  else {
842  buf_alloc(cnt * PORT_SHORT);
843  c1 = (unsigned char *)buf;
844  c2 = (unsigned char *)buffer;
845  for (i = 0; i < cnt; i++) {
846  for (j = 0; j < PORT_SHORT; j++)
847  c2[j] = c1[Cur_Head->shrt_cnvrt[j]];
848  c1 += sizeof(short);
849  c2 += PORT_SHORT;
850  }
851  if (dig_fwrite(buffer, PORT_SHORT, cnt, fp) == cnt)
852  return 1;
853  }
854  return 0;
855 }
856 
857 
858 /*!
859  \brief Write plus_t to the Portable Vector Format
860 
861  These routines must handle any type size conversions between the
862  portable format and the native machine.
863 
864  \param buf data buffer
865  \param cnt number of members
866  \param[in,out] fp pointer to struct gvfile
867 
868  \return 0 error
869  \return 1 OK
870 */
871 int dig__fwrite_port_P(const plus_t * buf,
872  size_t cnt, struct gvfile * fp)
873 {
874  return (dig__fwrite_port_I((int *)buf, cnt, fp));
875 }
876 
877 /*!
878  \brief Write chars to the Portable Vector Format
879 
880  These routines must handle any type size conversions between the
881  portable format and the native machine.
882 
883  \param buf data buffer
884  \param cnt number of members
885  \param[in,out] fp pointer to struct gvfile
886 
887  \return 0 error
888  \return 1 OK
889 */
890 int dig__fwrite_port_C(const char *buf,
891  size_t cnt, struct gvfile * fp)
892 {
893  if (dig_fwrite(buf, PORT_CHAR, cnt, fp) == cnt)
894  return 1;
895 
896  return 0;
897 }
898 
899 /*!
900  \brief Set Port_info structure to byte order of file
901 
902  \param port pointer to Port_info structure
903  \param byte_order ENDIAN_BIG or ENDIAN_LITTLE
904 */
905 void dig_init_portable(struct Port_info *port, int byte_order)
906 {
907  unsigned int i;
908 
909  port_init();
910 
911  port->byte_order = byte_order;
912 
913  /* double */
914  if (port->byte_order == dbl_order)
915  port->dbl_quick = TRUE;
916  else
917  port->dbl_quick = FALSE;
918 
919  for (i = 0; i < PORT_DOUBLE; i++) {
920  if (port->byte_order == ENDIAN_BIG)
921  port->dbl_cnvrt[i] = dbl_cnvrt[i];
922  else
923  port->dbl_cnvrt[i] = dbl_cnvrt[PORT_DOUBLE - i - 1];
924  }
925 
926  /* float */
927  if (port->byte_order == flt_order)
928  port->flt_quick = TRUE;
929  else
930  port->flt_quick = FALSE;
931 
932  for (i = 0; i < PORT_FLOAT; i++) {
933  if (port->byte_order == ENDIAN_BIG)
934  port->flt_cnvrt[i] = flt_cnvrt[i];
935  else
936  port->flt_cnvrt[i] = flt_cnvrt[PORT_FLOAT - i - 1];
937  }
938 
939  /* long */
940  if (port->byte_order == lng_order)
941  port->lng_quick = TRUE;
942  else
943  port->lng_quick = FALSE;
944 
945  for (i = 0; i < PORT_LONG; i++) {
946  if (port->byte_order == ENDIAN_BIG)
947  port->lng_cnvrt[i] = lng_cnvrt[i];
948  else
949  port->lng_cnvrt[i] = lng_cnvrt[PORT_LONG - i - 1];
950  }
951 
952  /* int */
953  if (port->byte_order == int_order)
954  port->int_quick = TRUE;
955  else
956  port->int_quick = FALSE;
957 
958  for (i = 0; i < PORT_INT; i++) {
959  if (port->byte_order == ENDIAN_BIG)
960  port->int_cnvrt[i] = int_cnvrt[i];
961  else
962  port->int_cnvrt[i] = int_cnvrt[PORT_INT - i - 1];
963  }
964 
965  /* short */
966  if (port->byte_order == shrt_order)
967  port->shrt_quick = TRUE;
968  else
969  port->shrt_quick = FALSE;
970 
971  for (i = 0; i < PORT_SHORT; i++) {
972  if (port->byte_order == ENDIAN_BIG)
973  port->shrt_cnvrt[i] = shrt_cnvrt[i];
974  else
975  port->shrt_cnvrt[i] = shrt_cnvrt[PORT_SHORT - i - 1];
976  }
977 
978  /* off_t */
979  if (port->byte_order == off_t_order)
980  port->off_t_quick = TRUE;
981  else
982  port->off_t_quick = FALSE;
983 
984  for (i = 0; i < nat_off_t; i++) {
985  if (port->byte_order == ENDIAN_BIG)
986  port->off_t_cnvrt[i] = off_t_cnvrt[i];
987  else
988  port->off_t_cnvrt[i] = off_t_cnvrt[nat_off_t - i - 1];
989  }
990 
991  return;
992 }
993 
994 /*!
995  \brief Set current Port_info structure
996 
997  \param port pointer to Port_info structure
998 
999  \return 0
1000 */
1001 int dig_set_cur_port(struct Port_info *port)
1002 {
1003  Cur_Head = port;
1004  return 0;
1005 }
1006 
1007 /*!
1008  \brief Get byte order
1009 
1010  \return ENDIAN_LITTLE
1011  \return ENDIAN_BIG
1012 */
1014 {
1015  if (dbl_order == ENDIAN_LITTLE)
1016  return (ENDIAN_LITTLE);
1017  else
1018  return (ENDIAN_BIG);
1019 }
#define PORT_FLOAT
Definition: dig_defines.h:46
int dig__fread_port_I(int *buf, size_t cnt, struct gvfile *fp)
Read integers from the Portable Vector Format.
Definition: portable.c:343
#define TRUE
Definition: gis.h:59
#define ENDIAN_LITTLE
Endian check.
Definition: gis.h:380
#define PORT_SHORT
Definition: dig_defines.h:49
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
int flt_quick
Quick reading flag for float.
Definition: dig_structs.h:234
int plus_t
plus_t size
Definition: dig_structs.h:41
#define PORT_CHAR
Definition: dig_defines.h:50
unsigned char dbl_cnvrt[PORT_DOUBLE]
Conversion matrices between file and native byte order (double)
Definition: dig_structs.h:200
int dig__fwrite_port_S(const short *buf, size_t cnt, struct gvfile *fp)
Write shorts to the Portable Vector Format.
Definition: portable.c:814
int dig_set_cur_port(struct Port_info *port)
Set current Port_info structure.
Definition: portable.c:1001
int flt_order
Definition: port_init.c:118
size_t dig_fwrite(const void *ptr, size_t size, size_t nmemb, struct gvfile *file)
Write struct gvfile.
Definition: file.c:156
int dbl_quick
Quick reading flag for double.
Definition: dig_structs.h:227
unsigned char flt_cnvrt[PORT_FLOAT]
Conversion matrices between file and native byte order (float)
Definition: dig_structs.h:204
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
unsigned char shrt_cnvrt[PORT_SHORT]
Conversion matrices between file and native byte order (short)
Definition: dig_structs.h:216
int nat_int
Definition: port_init.c:114
int shrt_quick
Quick reading flag for short.
Definition: dig_structs.h:255
unsigned char shrt_cnvrt[sizeof(short)]
Definition: port_init.c:129
int nat_flt
Definition: port_init.c:111
int dig_out_of_memory(void)
For now just print message and return error code.
Definition: struct_alloc.c:492
void dig_init_portable(struct Port_info *port, int byte_order)
Set Port_info structure to byte order of file.
Definition: portable.c:905
#define NULL
Definition: ccmath.h:32
#define PORT_LONG
Definition: dig_defines.h:47
int int_quick
Quick reading flag for int.
Definition: dig_structs.h:248
size_t dig_fread(void *ptr, size_t size, size_t nmemb, struct gvfile *file)
Read struct gvfile.
Definition: file.c:124
#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
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 nat_off_t
Definition: port_init.c:112
int int_order
Definition: port_init.c:121
#define ENDIAN_BIG
Definition: gis.h:381
unsigned char dbl_cnvrt[sizeof(double)]
Definition: port_init.c:124
int dig__fwrite_port_L(const long *buf, size_t cnt, struct gvfile *fp)
Write longs to the Portable Vector Format.
Definition: portable.c:702
#define FALSE
Definition: gis.h:63
unsigned char int_cnvrt[PORT_INT]
Conversion matrices between file and native byte order (int)
Definition: dig_structs.h:212
int shrt_order
Definition: port_init.c:122
void port_init(void)
Initialize Port_info structures.
Definition: port_init.c:184
unsigned char lng_cnvrt[PORT_LONG]
Conversion matrices between file and native byte order (long)
Definition: dig_structs.h:208
struct Port_info * Cur_Head
Definition: portable.c:45
int off_t_quick
Quick reading flag for off_t.
Definition: dig_structs.h:262
void * dig__alloc_space(int, int *, int, void *, int)
Definition: allocation.c:50
int dig__fread_port_F(float *buf, size_t cnt, struct gvfile *fp)
Read floats from the Portable Vector Format.
Definition: portable.c:123
unsigned char int_cnvrt[sizeof(int)]
Definition: port_init.c:128
int byte_order
File byte order.
Definition: dig_structs.h:191
unsigned char off_t_cnvrt[PORT_OFF_T]
Conversion matrices between file and native byte order (off_t)
Definition: dig_structs.h:220
int lng_order
Definition: port_init.c:120
int nat_lng
Definition: port_init.c:113
int nat_dbl
Definition: port_init.c:110
int nat_shrt
Definition: port_init.c:115
Portability info.
Definition: dig_structs.h:186
#define _(str)
Definition: glocale.h:10
unsigned char flt_cnvrt[sizeof(float)]
Definition: port_init.c:125
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 dig__fread_port_S(short *buf, size_t cnt, struct gvfile *fp)
Read shorts from the Portable Vector Format.
Definition: portable.c:426
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 off_t_order
Definition: port_init.c:119
int dig__byte_order_out()
Get byte order.
Definition: portable.c:1013
int dig__fwrite_port_C(const char *buf, size_t cnt, struct gvfile *fp)
Write chars to the Portable Vector Format.
Definition: portable.c:890
int dig__fwrite_port_F(const float *buf, size_t cnt, struct gvfile *fp)
Write floats to the Portable Vector Format.
Definition: portable.c:596
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:871
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
int dig__fread_port_L(long *buf, size_t cnt, struct gvfile *fp)
Read longs from the Portable Vector Format.
Definition: portable.c:260
File definition.
Definition: dig_structs.h:96
#define PORT_INT
Definition: dig_defines.h:48
int lng_quick
Quick reading flag for long.
Definition: dig_structs.h:241
int dbl_order
Definition: port_init.c:117
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
unsigned char off_t_cnvrt[sizeof(off_t)]
Definition: port_init.c:126
unsigned char lng_cnvrt[sizeof(long)]
Definition: port_init.c:127
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