punaligned.h (8883B)
1 /* 2 * Copyright (c) 2016 Mikkel Fahnøe Jørgensen, dvide.com 3 * 4 * (MIT License) 5 * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 * this software and associated documentation files (the "Software"), to deal in 7 * the Software without restriction, including without limitation the rights to 8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 * the Software, and to permit persons to whom the Software is furnished to do so, 10 * subject to the following conditions: 11 * - The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * - The Software is provided "as is", without warranty of any kind, express or 14 * implied, including but not limited to the warranties of merchantability, 15 * fitness for a particular purpose and noninfringement. In no event shall the 16 * authors or copyright holders be liable for any claim, damages or other 17 * liability, whether in an action of contract, tort or otherwise, arising from, 18 * out of or in connection with the Software or the use or other dealings in the 19 * Software. 20 */ 21 22 #ifndef PUNLIGNED_H 23 #define PUNLIGNED_H 24 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 #ifndef PORTABLE_UNALIGNED_ACCESS 30 31 #if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64) 32 #define PORTABLE_UNALIGNED_ACCESS 1 33 #else 34 #define PORTABLE_UNALIGNED_ACCESS 0 35 #endif 36 37 #endif 38 39 /* `unaligned_read_16` might not be defined if endianness was not determined. */ 40 #if !defined(unaligned_read_le16toh) 41 42 #include "pendian.h" 43 44 #ifndef UINT8_MAX 45 #include <stdint.h> 46 #endif 47 48 #if PORTABLE_UNALIGNED_ACCESS 49 50 #define unaligned_read_16(p) (*(uint16_t*)(p)) 51 #define unaligned_read_32(p) (*(uint32_t*)(p)) 52 #define unaligned_read_64(p) (*(uint64_t*)(p)) 53 54 #define unaligned_read_le16toh(p) le16toh(*(uint16_t*)(p)) 55 #define unaligned_read_le32toh(p) le32toh(*(uint32_t*)(p)) 56 #define unaligned_read_le64toh(p) le64toh(*(uint64_t*)(p)) 57 58 #define unaligned_read_be16toh(p) be16toh(*(uint16_t*)(p)) 59 #define unaligned_read_be32toh(p) be32toh(*(uint32_t*)(p)) 60 #define unaligned_read_be64toh(p) be64toh(*(uint64_t*)(p)) 61 62 #define unaligned_write_16(p, v) (*(uint16_t*)(p) = (uint16_t)(v)) 63 #define unaligned_write_32(p, v) (*(uint32_t*)(p) = (uint32_t)(v)) 64 #define unaligned_write_64(p, v) (*(uint64_t*)(p) = (uint64_t)(v)) 65 66 #define unaligned_write_htole16(p, v) (*(uint16_t*)(p) = htole16(v)) 67 #define unaligned_write_htole32(p, v) (*(uint32_t*)(p) = htole32(v)) 68 #define unaligned_write_htole64(p, v) (*(uint64_t*)(p) = htole64(v)) 69 70 #define unaligned_write_htobe16(p, v) (*(uint16_t*)(p) = htobe16(v)) 71 #define unaligned_write_htobe32(p, v) (*(uint32_t*)(p) = htobe32(v)) 72 #define unaligned_write_htobe64(p, v) (*(uint64_t*)(p) = htobe64(v)) 73 74 #else 75 76 #define unaligned_read_le16toh(p) ( \ 77 (((uint16_t)(((uint8_t *)(p))[0])) << 0) | \ 78 (((uint16_t)(((uint8_t *)(p))[1])) << 8)) 79 80 #define unaligned_read_le32toh(p) ( \ 81 (((uint32_t)(((uint8_t *)(p))[0])) << 0) | \ 82 (((uint32_t)(((uint8_t *)(p))[1])) << 8) | \ 83 (((uint32_t)(((uint8_t *)(p))[2])) << 16) | \ 84 (((uint32_t)(((uint8_t *)(p))[3])) << 24)) 85 86 #define unaligned_read_le64toh(p) ( \ 87 (((uint64_t)(((uint8_t *)(p))[0])) << 0) | \ 88 (((uint64_t)(((uint8_t *)(p))[1])) << 8) | \ 89 (((uint64_t)(((uint8_t *)(p))[2])) << 16) | \ 90 (((uint64_t)(((uint8_t *)(p))[3])) << 24) | \ 91 (((uint64_t)(((uint8_t *)(p))[4])) << 32) | \ 92 (((uint64_t)(((uint8_t *)(p))[5])) << 40) | \ 93 (((uint64_t)(((uint8_t *)(p))[6])) << 48) | \ 94 (((uint64_t)(((uint8_t *)(p))[7])) << 56)) 95 96 #define unaligned_read_be16toh(p) ( \ 97 (((uint16_t)(((uint8_t *)(p))[0])) << 8) | \ 98 (((uint16_t)(((uint8_t *)(p))[1])) << 0)) 99 100 #define unaligned_read_be32toh(p) ( \ 101 (((uint32_t)(((uint8_t *)(p))[0])) << 24) | \ 102 (((uint32_t)(((uint8_t *)(p))[1])) << 16) | \ 103 (((uint32_t)(((uint8_t *)(p))[2])) << 8) | \ 104 (((uint32_t)(((uint8_t *)(p))[3])) << 0)) 105 106 #define unaligned_read_be64toh(p) ( \ 107 (((uint64_t)(((uint8_t *)(p))[0])) << 56) | \ 108 (((uint64_t)(((uint8_t *)(p))[1])) << 48) | \ 109 (((uint64_t)(((uint8_t *)(p))[2])) << 40) | \ 110 (((uint64_t)(((uint8_t *)(p))[3])) << 32) | \ 111 (((uint64_t)(((uint8_t *)(p))[4])) << 24) | \ 112 (((uint64_t)(((uint8_t *)(p))[5])) << 16) | \ 113 (((uint64_t)(((uint8_t *)(p))[6])) << 8) | \ 114 (((uint64_t)(((uint8_t *)(p))[7])) << 0)) 115 116 #define unaligned_write_htole16(p, v) do { \ 117 ((uint8_t *)(p))[0] = (uint8_t)(((uint16_t)(v)) >> 0); \ 118 ((uint8_t *)(p))[1] = (uint8_t)(((uint16_t)(v)) >> 8); \ 119 } while (0) 120 121 #define unaligned_write_htole32(p, v) do { \ 122 ((uint8_t *)(p))[0] = (uint8_t)(((uint32_t)(v)) >> 0); \ 123 ((uint8_t *)(p))[1] = (uint8_t)(((uint32_t)(v)) >> 8); \ 124 ((uint8_t *)(p))[2] = (uint8_t)(((uint32_t)(v)) >> 16); \ 125 ((uint8_t *)(p))[3] = (uint8_t)(((uint32_t)(v)) >> 24); \ 126 } while (0) 127 128 #define unaligned_write_htole64(p) do { \ 129 ((uint8_t *)(p))[0] = (uint8_t)(((uint64_t)(v)) >> 0); \ 130 ((uint8_t *)(p))[1] = (uint8_t)(((uint64_t)(v)) >> 8); \ 131 ((uint8_t *)(p))[2] = (uint8_t)(((uint64_t)(v)) >> 16); \ 132 ((uint8_t *)(p))[3] = (uint8_t)(((uint64_t)(v)) >> 24); \ 133 ((uint8_t *)(p))[4] = (uint8_t)(((uint64_t)(v)) >> 32); \ 134 ((uint8_t *)(p))[5] = (uint8_t)(((uint64_t)(v)) >> 40); \ 135 ((uint8_t *)(p))[6] = (uint8_t)(((uint64_t)(v)) >> 48); \ 136 ((uint8_t *)(p))[7] = (uint8_t)(((uint64_t)(v)) >> 56); \ 137 } while (0) 138 139 #define unaligned_write_htobe16(p, v) do { \ 140 ((uint8_t *)(p))[0] = (uint8_t)(((uint16_t)(v)) >> 8); \ 141 ((uint8_t *)(p))[1] = (uint8_t)(((uint16_t)(v)) >> 0); \ 142 } while (0) 143 144 #define unaligned_write_htobe32(p, v) do { \ 145 ((uint8_t *)(p))[0] = (uint8_t)(((uint32_t)(v)) >> 24); \ 146 ((uint8_t *)(p))[1] = (uint8_t)(((uint32_t)(v)) >> 16); \ 147 ((uint8_t *)(p))[2] = (uint8_t)(((uint32_t)(v)) >> 8); \ 148 ((uint8_t *)(p))[3] = (uint8_t)(((uint32_t)(v)) >> 0); \ 149 } while (0) 150 151 #define unaligned_write_htobe64(p) do { \ 152 ((uint8_t *)(p))[0] = (uint8_t)(((uint64_t)(v)) >> 56); \ 153 ((uint8_t *)(p))[1] = (uint8_t)(((uint64_t)(v)) >> 48); \ 154 ((uint8_t *)(p))[2] = (uint8_t)(((uint64_t)(v)) >> 40); \ 155 ((uint8_t *)(p))[3] = (uint8_t)(((uint64_t)(v)) >> 32); \ 156 ((uint8_t *)(p))[4] = (uint8_t)(((uint64_t)(v)) >> 24); \ 157 ((uint8_t *)(p))[5] = (uint8_t)(((uint64_t)(v)) >> 16); \ 158 ((uint8_t *)(p))[6] = (uint8_t)(((uint64_t)(v)) >> 8); \ 159 ((uint8_t *)(p))[7] = (uint8_t)(((uint64_t)(v)) >> 0); \ 160 } while (0) 161 162 #if __LITTLE_ENDIAN__ 163 #define unaligned_read_16(p) unaligned_read_le16toh(p) 164 #define unaligned_read_32(p) unaligned_read_le32toh(p) 165 #define unaligned_read_64(p) unaligned_read_le64toh(p) 166 167 #define unaligned_write_16(p) unaligned_write_htole16(p) 168 #define unaligned_write_32(p) unaligned_write_htole32(p) 169 #define unaligned_write_64(p) unaligned_write_htole64(p) 170 #endif 171 172 #if __BIG_ENDIAN__ 173 #define unaligned_read_16(p) unaligned_read_be16toh(p) 174 #define unaligned_read_32(p) unaligned_read_be32toh(p) 175 #define unaligned_read_64(p) unaligned_read_be64toh(p) 176 177 #define unaligned_write_16(p) unaligned_write_htobe16(p) 178 #define unaligned_write_32(p) unaligned_write_htobe32(p) 179 #define unaligned_write_64(p) unaligned_write_htobe64(p) 180 #endif 181 182 #endif 183 184 #endif 185 186 #ifdef __cplusplus 187 } 188 #endif 189 190 #endif /* PUNALIGNED_H */