-
Notifications
You must be signed in to change notification settings - Fork 47
/
get_bin.h
88 lines (72 loc) · 3.46 KB
/
get_bin.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/* Copyright (C) 2018, Project Pluto
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* Code to read integers of various sizes and 64-bit double-precision
floats from binary data buffers. See uses in 'vsopson.cpp' and 'lunar2.cpp'
where data is extracted from binary files.
It's assumed that the input data is in Intel (little-Endian) order.
On Intel machines, you can extract such data by type-punning,
even if the data isn't aligned on a word boundary. On some other
machines, the data must be aligned on a word boundary and/or you
may have reverse the byte order.
OpenWATCOM, Microsoft C, Borland, TurboC, and Digital Mars are all
Intel-only. If we're using one of those compilers, we can type-pun.
gcc and clang #define __x86_64__ or __i386__ for Intel hardware.
There are probably other cases where we could type-pun. But the
non-punning code will work in all cases; all we lose by not punning
is a very small amount of speed. If I learn of other cases where
punning is possible, the conditions under which USE_TYPE_PUNNING
is defined can be modified. */
#if defined(__x86_64__) || defined(__i386__) || defined(__WATCOMC__) \
|| defined(_MSC_VER) || defined (__BORLANDC__) \
|| defined (__TURBOC__) || defined( __DMC__)
#define USE_TYPE_PUNNING
#endif
#if defined( __WORD_ORDER__) && (__WORD_ORDER__ == __ORDER_BIG_ENDIAN__)
#define USING_BIG_ENDIAN
#endif
#undef USE_TYPE_PUNNING
#ifdef USE_TYPE_PUNNING
#define get16bits(d) (*((const uint16_t *) (d)))
#define get32bits(d) (*((const uint32_t *) (d)))
#define get64bits(d) (*((const uint64_t *) (d)))
/* Signed integer extraction : */
#define get16sbits(d) (*((const int16_t *) (d)))
#define get32sbits(d) (*((const int32_t *) (d)))
#define get64sbits(d) (*((const int64_t *) (d)))
#define get_double(d) (*((const double *) (d)))
#else /* Can't directly read binary data */
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
+(uint32_t)(((const uint8_t *)(d))[0]) )
#define get32bits(d) ((((uint32_t)(((const uint8_t *)(d))[3])) << 24)\
+(((uint32_t)(((const uint8_t *)(d))[2])) << 16)\
+(((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
+(uint32_t)(((const uint8_t *)(d))[0]) )
#define get16sbits(d) ((int16_t)( get16bits( d)))
#define get32sbits(d) ((int32_t)( get32bits( d)))
#define get64sbits(d) ((int64_t)( get64bits( d)))
static inline double get_double( const void *iptr)
{
const char *idata = (const char *)iptr;
int i;
double rval;
char *buff = (char *)&rval;
#if defined( USING_BIG_ENDIAN)
for( i = 7; i >= 0; i--)
#else
for( i = 0; i < 8; i++)
#endif
buff[i] = *idata++;
return( rval);
}
#endif /* End of code to indirectly read binary data */