123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- /*
- ****************************************************************************
- *
- * MODULE: Vector library
- *
- * AUTHOR(S): Original author CERL, probably Dave Gerdes.
- * Update to GRASS 5.7 Radim Blazek.
- *
- * PURPOSE: Lower level functions for reading/writing/manipulating vectors.
- *
- * COPYRIGHT: (C) 2001 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public
- * License (>=v2). Read the file COPYING that comes with GRASS
- * for details.
- *
- *****************************************************************************/
- #include <stdio.h>
- #include <grass/Vect.h>
- /*
- ** Written by Dave Gerdes 9/1988
- ** US Army Construction Engineering Research Lab
- */
- /*
- **
- ** This code is a quick hack to allow the writing of portable
- ** binary data files.
- ** The approach is to take known values and compare them against
- ** the current machine's internal representation. A cross reference
- ** table is then built, and then all file reads and writes must go through
- ** through these routines to correct the numbers if need be.
- **
- ** As long as the byte switching is symetrical, the conversion routines
- ** will work both directions.
- ** The integer test patterns are quite simple, and their choice was
- ** arbitrary, but the float and double valued were more critical.
- ** I did not have a specification for IEEE to go by, so it is possible
- ** that I have missed something. My criteria were:
- **
- ** First, true IEEE numbers had to be chosen to avoid getting an FPE.
- ** Second, every byte in the test pattern had to be unique. And
- ** finally, the number had to not be sensitive to rounding by the
- ** specific hardware implementation.
- **
- ** By experimentation it was found that the number 1.3333 met
- ** all these criteria for both floats and doubles
- ** See the discourse at the end of this file for more information
- **
- **
- */
- #define TEST_PATTERN 1.3333
- #define LONG_TEST 0x01020304
- #define INT_TEST 0x01020304
- #define SHORT_TEST 0x0102
- static double u_d = TEST_PATTERN;
- static float u_f = TEST_PATTERN;
- static long u_l = LONG_TEST;
- static int u_i = INT_TEST;
- static short u_s = SHORT_TEST;
- /* dbl_cmpr holds the bytes of an IEEE representation of TEST_PATTERN */
- static const unsigned char dbl_cmpr [] = {0x3f, 0xf5, 0x55, 0x32, 0x61, 0x7c, 0x1b, 0xda};
- /* flt_cmpr holds the bytes of an IEEE representation of TEST_PATTERN */
- static const unsigned char flt_cmpr [] = {0x3f, 0xaa, 0xa9, 0x93};
- static const unsigned char lng_cmpr [] = {0x01, 0x02, 0x03, 0x04};
- static const unsigned char int_cmpr [] = {0x01, 0x02, 0x03, 0x04};
- static const unsigned char shrt_cmpr[] = {0x01, 0x02};
- /* Find native sizes */
- int nat_dbl = sizeof(double);
- int nat_flt = sizeof(float);
- int nat_lng = sizeof(long);
- int nat_int = sizeof(int);
- int nat_shrt = sizeof(short);
- int dbl_order;
- int flt_order;
- int lng_order;
- int int_order;
- int shrt_order;
- unsigned char dbl_cnvrt [sizeof(double)];
- unsigned char flt_cnvrt [sizeof(float )];
- unsigned char lng_cnvrt [sizeof(long )];
- unsigned char int_cnvrt [sizeof(int )];
- unsigned char shrt_cnvrt[sizeof(short )];
- /*
- * match search_value against each char in basis.
- * return offset or -1 if not found
- */
- static int find_offset(const unsigned char *basis, unsigned char search_value, int size)
- {
- int i;
- for (i = 0; i < size; i++)
- if (basis[i] == search_value)
- return (i);
- return (-1);
- }
- static int find_offsets(
- const void *pattern, unsigned char *cnvrt, const unsigned char *cmpr,
- int port_size, int nat_size, const char *typename)
- {
- int big, ltl;
- int i;
- for (i = 0; i < port_size; i++)
- {
- int off = find_offset(pattern, cmpr[i], nat_size);
- if (off < 0)
- G_fatal_error("could not find '%x' in %s", cmpr[i], typename);
- cnvrt[i] = off;
- }
- big = ltl = 1;
- for (i = 0; i < port_size; i++)
- {
- if (cnvrt[i] != (nat_size - port_size + i))
- big = 0; /* isn't big endian */
- if (cnvrt[i] != (port_size - 1 - i))
- ltl = 0; /* isn't little endian */
- }
-
- if (big)
- return ENDIAN_BIG;
- if (ltl)
- return ENDIAN_LITTLE;
- return ENDIAN_OTHER;
- }
- void port_init(void)
- {
- static int done;
- if (done)
- return;
- done = 1;
- /* Following code checks only if all assumptions are fullfilled */
- /* Check sizes */
- if (nat_dbl != PORT_DOUBLE)
- G_fatal_error("sizeof(double) != %d", PORT_DOUBLE);
- if (nat_flt != PORT_FLOAT)
- G_fatal_error("sizeof(float) != %d", PORT_DOUBLE);
- if (nat_lng < PORT_LONG)
- G_fatal_error("sizeof(long) < %d", PORT_LONG);
- if (nat_int < PORT_INT)
- G_fatal_error("sizeof(int) < %d", PORT_INT);
- if (nat_shrt < PORT_SHORT)
- G_fatal_error("sizeof(short) < %d", PORT_SHORT);
-
- /* Find for each byte in big endian test pattern (*_cmpr)
- * offset of corresponding byte in machine native order.
- * Look if native byte order is little or big or some other (pdp)
- * endian.
- */
- dbl_order = find_offsets(&u_d, dbl_cnvrt, dbl_cmpr, PORT_DOUBLE, nat_dbl, "double");
- flt_order = find_offsets(&u_f, flt_cnvrt, flt_cmpr, PORT_FLOAT, nat_flt, "float" );
- lng_order = find_offsets(&u_l, lng_cnvrt, lng_cmpr, PORT_LONG, nat_lng, "long" );
- int_order = find_offsets(&u_i, int_cnvrt, int_cmpr, PORT_INT, nat_int, "int" );
- shrt_order = find_offsets(&u_s, shrt_cnvrt, shrt_cmpr, PORT_SHORT, nat_shrt, "short" );
- }
|