GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
port_init.c
Go to the documentation of this file.
1 /*
2  ****************************************************************************
3  *
4  * MODULE: Vector library
5  *
6  * AUTHOR(S): Original author CERL, probably Dave Gerdes.
7  * Update to GRASS 5.7 Radim Blazek.
8  *
9  * PURPOSE: Lower level functions for reading/writing/manipulating vectors.
10  *
11  * COPYRIGHT: (C) 2001 by the GRASS Development Team
12  *
13  * This program is free software under the GNU General Public
14  * License (>=v2). Read the file COPYING that comes with GRASS
15  * for details.
16  *
17  *****************************************************************************/
18 #include <stdio.h>
19 #include <grass/Vect.h>
20 
21 /*
22  ** Written by Dave Gerdes 9/1988
23  ** US Army Construction Engineering Research Lab
24  */
25 
26 
27 /*
28  **
29  ** This code is a quick hack to allow the writing of portable
30  ** binary data files.
31  ** The approach is to take known values and compare them against
32  ** the current machine's internal representation. A cross reference
33  ** table is then built, and then all file reads and writes must go through
34  ** through these routines to correct the numbers if need be.
35  **
36  ** As long as the byte switching is symetrical, the conversion routines
37  ** will work both directions.
38 
39  ** The integer test patterns are quite simple, and their choice was
40  ** arbitrary, but the float and double valued were more critical.
41 
42  ** I did not have a specification for IEEE to go by, so it is possible
43  ** that I have missed something. My criteria were:
44  **
45  ** First, true IEEE numbers had to be chosen to avoid getting an FPE.
46  ** Second, every byte in the test pattern had to be unique. And
47  ** finally, the number had to not be sensitive to rounding by the
48  ** specific hardware implementation.
49  **
50  ** By experimentation it was found that the number 1.3333 met
51  ** all these criteria for both floats and doubles
52 
53  ** See the discourse at the end of this file for more information
54  **
55  **
56  */
57 
58 #define TEST_PATTERN 1.3333
59 #define LONG_TEST 0x01020304
60 #define INT_TEST 0x01020304
61 #define SHORT_TEST 0x0102
62 
63 static double u_d = TEST_PATTERN;
64 static float u_f = TEST_PATTERN;
65 static long u_l = LONG_TEST;
66 static int u_i = INT_TEST;
67 static short u_s = SHORT_TEST;
68 
69 /* dbl_cmpr holds the bytes of an IEEE representation of TEST_PATTERN */
70 static const unsigned char dbl_cmpr[] =
71  { 0x3f, 0xf5, 0x55, 0x32, 0x61, 0x7c, 0x1b, 0xda };
72 /* flt_cmpr holds the bytes of an IEEE representation of TEST_PATTERN */
73 static const unsigned char flt_cmpr[] = { 0x3f, 0xaa, 0xa9, 0x93 };
74 static const unsigned char lng_cmpr[] = { 0x01, 0x02, 0x03, 0x04 };
75 static const unsigned char int_cmpr[] = { 0x01, 0x02, 0x03, 0x04 };
76 static const unsigned char shrt_cmpr[] = { 0x01, 0x02 };
77 
78 /* Find native sizes */
79 int nat_dbl = sizeof(double);
80 int nat_flt = sizeof(float);
81 int nat_lng = sizeof(long);
82 int nat_int = sizeof(int);
83 int nat_shrt = sizeof(short);
84 
90 
91 unsigned char dbl_cnvrt[sizeof(double)];
92 unsigned char flt_cnvrt[sizeof(float)];
93 unsigned char lng_cnvrt[sizeof(long)];
94 unsigned char int_cnvrt[sizeof(int)];
95 unsigned char shrt_cnvrt[sizeof(short)];
96 
97 /*
98  * match search_value against each char in basis.
99  * return offset or -1 if not found
100  */
101 
102 static int find_offset(const unsigned char *basis, unsigned char search_value,
103  int size)
104 {
105  int i;
106 
107  for (i = 0; i < size; i++)
108  if (basis[i] == search_value)
109  return (i);
110 
111  return (-1);
112 }
113 
114 static int find_offsets(const void *pattern, unsigned char *cnvrt,
115  const unsigned char *cmpr, int port_size,
116  int nat_size, const char *typename)
117 {
118  int big, ltl;
119  int i;
120 
121  for (i = 0; i < port_size; i++) {
122  int off = find_offset(pattern, cmpr[i], nat_size);
123 
124  if (off < 0)
125  G_fatal_error("could not find '%x' in %s", cmpr[i], typename);
126 
127  cnvrt[i] = off;
128  }
129 
130  big = ltl = 1;
131 
132  for (i = 0; i < port_size; i++) {
133  if (cnvrt[i] != (nat_size - port_size + i))
134  big = 0; /* isn't big endian */
135  if (cnvrt[i] != (port_size - 1 - i))
136  ltl = 0; /* isn't little endian */
137  }
138 
139  if (big)
140  return ENDIAN_BIG;
141 
142  if (ltl)
143  return ENDIAN_LITTLE;
144 
145  return ENDIAN_OTHER;
146 }
147 
148 void port_init(void)
149 {
150  static int done;
151 
152  if (done)
153  return;
154 
155  done = 1;
156 
157  /* Following code checks only if all assumptions are fullfilled */
158  /* Check sizes */
159  if (nat_dbl != PORT_DOUBLE)
160  G_fatal_error("sizeof(double) != %d", PORT_DOUBLE);
161  if (nat_flt != PORT_FLOAT)
162  G_fatal_error("sizeof(float) != %d", PORT_DOUBLE);
163  if (nat_lng < PORT_LONG)
164  G_fatal_error("sizeof(long) < %d", PORT_LONG);
165  if (nat_int < PORT_INT)
166  G_fatal_error("sizeof(int) < %d", PORT_INT);
167  if (nat_shrt < PORT_SHORT)
168  G_fatal_error("sizeof(short) < %d", PORT_SHORT);
169 
170  /* Find for each byte in big endian test pattern (*_cmpr)
171  * offset of corresponding byte in machine native order.
172  * Look if native byte order is little or big or some other (pdp)
173  * endian.
174  */
175 
176  dbl_order =
177  find_offsets(&u_d, dbl_cnvrt, dbl_cmpr, PORT_DOUBLE, nat_dbl,
178  "double");
179  flt_order =
180  find_offsets(&u_f, flt_cnvrt, flt_cmpr, PORT_FLOAT, nat_flt, "float");
181  lng_order =
182  find_offsets(&u_l, lng_cnvrt, lng_cmpr, PORT_LONG, nat_lng, "long");
183  int_order =
184  find_offsets(&u_i, int_cnvrt, int_cmpr, PORT_INT, nat_int, "int");
185  shrt_order =
186  find_offsets(&u_s, shrt_cnvrt, shrt_cmpr, PORT_SHORT, nat_shrt,
187  "short");
188 }
#define TEST_PATTERN
Definition: port_init.c:58
unsigned char lng_cnvrt[sizeof(long)]
Definition: port_init.c:93
int nat_lng
Definition: port_init.c:81
int nat_dbl
Definition: port_init.c:79
int nat_flt
Definition: port_init.c:80
int flt_order
Definition: port_init.c:86
tuple size
value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
Definition: tools.py:2334
unsigned char dbl_cnvrt[sizeof(double)]
Definition: port_init.c:91
#define INT_TEST
Definition: port_init.c:60
int
Definition: g3dcolor.c:48
int dbl_order
Definition: port_init.c:85
int nat_shrt
Definition: port_init.c:83
int nat_int
Definition: port_init.c:82
int int_order
Definition: port_init.c:88
int lng_order
Definition: port_init.c:87
int shrt_order
Definition: port_init.c:89
unsigned char int_cnvrt[sizeof(int)]
Definition: port_init.c:94
#define LONG_TEST
Definition: port_init.c:59
unsigned char shrt_cnvrt[sizeof(short)]
Definition: port_init.c:95
#define SHORT_TEST
Definition: port_init.c:61
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
unsigned char flt_cnvrt[sizeof(float)]
Definition: port_init.c:92
void port_init(void)
Definition: port_init.c:148