GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-d6dec75dd4
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,
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));
196  memcpy(c2, c1, port_off_t_size);
197  }
198  else {
199  if (c1[0] & 0x80)
200  memset(c2, 0xff, sizeof(off_t));
201  memcpy(c2 + nat_off_t - port_off_t_size, c1,
202  port_off_t_size);
203  }
204  c1 += port_off_t_size;
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 */
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];
237  c1 += port_off_t_size;
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  */
262 int 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));
290  memcpy(c2, c1, PORT_LONG);
291  }
292  else {
293  if (c1[0] & 0x80)
294  memset(c2, 0xff, sizeof(long));
295  memcpy(c2 + nat_lng - PORT_LONG, c1, PORT_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 */
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  */
345 int 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));
378  memcpy(c2 + nat_int - PORT_INT, c1, PORT_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 */
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  */
428 int 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));
456  memcpy(c2, c1, PORT_SHORT);
457  }
458  else {
459  if (c1[0] & 0x80)
460  memset(c2, 0xff, sizeof(short));
461  memcpy(c2 + nat_shrt - PORT_SHORT, c1, PORT_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 */
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  */
511 int 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  */
537 int 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  */
559 int 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  */
597 int 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  */
636 int 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++) {
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,
656  port_off_t_size);
657  c1 += sizeof(off_t);
658  c2 += port_off_t_size;
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);
677  c2 += port_off_t_size;
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  */
703 int 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++) {
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, 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++) {
773  if (int_order == ENDIAN_LITTLE)
774  memcpy(c2, c1, PORT_INT);
775  else
776  memcpy(c2, c1 + nat_int - PORT_INT, PORT_INT);
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  */
813 int 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++) {
828  if (shrt_order == ENDIAN_LITTLE)
829  memcpy(c2, c1, PORT_SHORT);
830  else
831  memcpy(c2, c1 + nat_shrt - PORT_SHORT, PORT_SHORT);
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  */
868 int 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  */
886 int 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  */
900 void dig_init_portable(struct Port_info *port, int byte_order)
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  */
996 int dig_set_cur_port(struct Port_info *port)
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:49
int dig_out_of_memory(void)
For now just print message and return error code.
Definition: struct_alloc.c:487
int plus_t
plus_t size
Definition: dig_structs.h:41
#define ENDIAN_LITTLE
Endian check.
Definition: gis.h:409
#define TRUE
Definition: gis.h:79
#define FALSE
Definition: gis.h:83
#define ENDIAN_BIG
Definition: gis.h:410
#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.
Definition: dig_structs.h:181
unsigned char flt_cnvrt[PORT_FLOAT]
Conversion matrices between file and native byte order (float)
Definition: dig_structs.h:198
int flt_quick
Quick reading flag for float.
Definition: dig_structs.h:228
unsigned char lng_cnvrt[PORT_LONG]
Conversion matrices between file and native byte order (long)
Definition: dig_structs.h:202
int dbl_quick
Quick reading flag for double.
Definition: dig_structs.h:221
unsigned char off_t_cnvrt[PORT_OFF_T]
Conversion matrices between file and native byte order (off_t)
Definition: dig_structs.h:214
unsigned char int_cnvrt[PORT_INT]
Conversion matrices between file and native byte order (int)
Definition: dig_structs.h:206
int off_t_quick
Quick reading flag for off_t.
Definition: dig_structs.h:256
int lng_quick
Quick reading flag for long.
Definition: dig_structs.h:235
int int_quick
Quick reading flag for int.
Definition: dig_structs.h:242
unsigned char shrt_cnvrt[PORT_SHORT]
Conversion matrices between file and native byte order (short)
Definition: dig_structs.h:210
unsigned char dbl_cnvrt[PORT_DOUBLE]
Conversion matrices between file and native byte order (double)
Definition: dig_structs.h:194
int shrt_quick
Quick reading flag for short.
Definition: dig_structs.h:249
int byte_order
File byte order.
Definition: dig_structs.h:185
File definition.
Definition: dig_structs.h:94