summaryrefslogtreecommitdiff
path: root/neozip/zmemory.h
diff options
context:
space:
mode:
Diffstat (limited to 'neozip/zmemory.h')
-rw-r--r--neozip/zmemory.h99
1 files changed, 99 insertions, 0 deletions
diff --git a/neozip/zmemory.h b/neozip/zmemory.h
new file mode 100644
index 0000000000..fc850a7227
--- /dev/null
+++ b/neozip/zmemory.h
@@ -0,0 +1,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