forked from zlib-ng/zlib-ng
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzmemory.h
99 lines (87 loc) · 2.89 KB
/
zmemory.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
89
90
91
92
93
94
95
96
97
98
99
/* zmemory.h -- Private inline functions used internally in zlib-ng
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#ifndef _ZMEMORY_H
#define _ZMEMORY_H
#if defined(__GNUC__) && (__GNUC__ >= 4)
# define HAVE_MAY_ALIAS
#endif
static inline uint16_t zng_memread_2(const void *ptr) {
#if defined(HAVE_MAY_ALIAS)
typedef struct { uint16_t val; } __attribute__ ((__packed__, __may_alias__)) unaligned_uint16_t;
return ((const unaligned_uint16_t *)ptr)->val;
#else
uint16_t val;
memcpy(&val, ptr, sizeof(val));
return val;
#endif
}
static inline uint32_t zng_memread_4(const void *ptr) {
#if defined(HAVE_MAY_ALIAS)
typedef struct { uint32_t val; } __attribute__ ((__packed__, __may_alias__)) unaligned_uint32_t;
return ((const unaligned_uint32_t *)ptr)->val;
#else
uint32_t val;
memcpy(&val, ptr, sizeof(val));
return val;
#endif
}
static inline uint64_t zng_memread_8(const void *ptr) {
#if defined(HAVE_MAY_ALIAS)
typedef struct { uint64_t val; } __attribute__ ((__packed__, __may_alias__)) unaligned_uint64_t;
return ((const unaligned_uint64_t *)ptr)->val;
#else
uint64_t val;
memcpy(&val, ptr, sizeof(val));
return val;
#endif
}
static inline void zng_memwrite_2(void *ptr, uint16_t val) {
#if defined(HAVE_MAY_ALIAS)
typedef struct { uint16_t val; } __attribute__ ((__packed__, __may_alias__)) unaligned_uint16_t;
((unaligned_uint16_t *)ptr)->val = val;
#else
memcpy(ptr, &val, sizeof(val));
#endif
}
static inline void zng_memwrite_4(void *ptr, uint32_t val) {
#if defined(HAVE_MAY_ALIAS)
typedef struct { uint32_t val; } __attribute__ ((__packed__, __may_alias__)) unaligned_uint32_t;
((unaligned_uint32_t *)ptr)->val = val;
#else
memcpy(ptr, &val, sizeof(val));
#endif
}
static inline void zng_memwrite_8(void *ptr, uint64_t val) {
#if defined(HAVE_MAY_ALIAS)
typedef struct { uint64_t val; } __attribute__ ((__packed__, __may_alias__)) unaligned_uint64_t;
((unaligned_uint64_t *)ptr)->val = val;
#else
memcpy(ptr, &val, sizeof(val));
#endif
}
/* Use zng_memread_* instead of memcmp to avoid older compilers not converting memcmp
calls to unaligned comparisons when unaligned access is supported. Use memcmp only when
unaligned support is not available to avoid an extra call to memcpy. */
static inline int32_t zng_memcmp_2(const void *src0, const void *src1) {
#if defined(HAVE_MAY_ALIAS)
return zng_memread_2(src0) != zng_memread_2(src1);
#else
return memcmp(src0, src1, 2);
#endif
}
static inline int32_t zng_memcmp_4(const void *src0, const void *src1) {
#if defined(HAVE_MAY_ALIAS)
return zng_memread_4(src0) != zng_memread_4(src1);
#else
return memcmp(src0, src1, 4);
#endif
}
static inline int32_t zng_memcmp_8(const void *src0, const void *src1) {
#if defined(HAVE_MAY_ALIAS)
return zng_memread_8(src0) != zng_memread_8(src1);
#else
return memcmp(src0, src1, 8);
#endif
}
#endif