diff options
-rw-r--r-- | gen/bits/intconf.c | 82 | ||||
-rw-r--r-- | gen/bits/intconf.h | 18 | ||||
-rw-r--r-- | src/arpa/inet/htonl.c | 10 | ||||
-rw-r--r-- | src/arpa/inet/htonll.c | 18 | ||||
-rw-r--r-- | src/arpa/inet/htons.c | 11 | ||||
-rw-r--r-- | src/arpa/inet/ntohl.c | 10 | ||||
-rw-r--r-- | src/arpa/inet/ntohll.c | 18 | ||||
-rw-r--r-- | src/arpa/inet/ntohs.c | 12 |
8 files changed, 170 insertions, 9 deletions
diff --git a/gen/bits/intconf.c b/gen/bits/intconf.c index 5a52d12..361dd16 100644 --- a/gen/bits/intconf.c +++ b/gen/bits/intconf.c @@ -140,6 +140,82 @@ static int fast(int bits) /** + * For a 16-bit integer with the value 0x0102, print, + * to a string, the bytes it is constructed by one the + * host machine, in storage order. + * + * @return The bytes in the integer juxtaposed. + */ +static char* byteorder_16(void) +{ + static char buf[16 / 4 + 1]; + union + { + short int all; + struct + { + char a; char b; + }; + } test = { .all = 0x0102 }; + + sprintf(buf, "%02i%02i", test.a, test.b); + return buf; +} + + +/** + * For a 32-bit integer with the value 0x01020304, print, + * to a string, the bytes it is constructed by one the + * host machine, in storage order. + * + * @return The bytes in the integer juxtaposed. + */ +static char* byteorder_32(void) +{ + static char buf[32 / 4 + 1]; + union + { + int all; + struct + { + char a; char b; char c; char d; + }; + } test = { .all = 0x01020304 }; + + sprintf(buf, "%02i%02i%02i%02i", + test.a, test.b, test.c, test.d); + return buf; +} + + +/** + * For a 16-bit integer with the value 0x0102030405060708, + * print, to a string, the bytes it is constructed by one + * the host machine, in storage order. + * + * @return The bytes in the integer juxtaposed. + */ +static char* byteorder_64(void) +{ + static char buf[64 / 4 + 1]; + union + { + long long int all; + struct + { + char a; char b; char c; char d; + char e; char f; char g; char h; + }; + } test = { .all = 0x0102030405060708LL }; + + sprintf(buf, "%02i%02i%02i%02i%02i%02i%02i%02i", + test.a, test.b, test.c, test.d, + test.e, test.f, test.g, test.h); + return buf; +} + + +/** * @param argc The number of command line arguments, should * be either 1 (print integer width information) * or 2 (otherwise). @@ -167,12 +243,18 @@ int main(int argc, char* argv[]) r |= printf("PTR_BIT %zu\n", 8 * sizeof(void*)); r |= printf("WCHAR_BIT %zu\n", 8 * sizeof(L'\0')); + /* Print byte orders. */ + r |= printf("INT16_BYTEORDER 0x%s\n", byteorder_16()); + r |= printf("INT32_BYTEORDER 0x%s\n", byteorder_32()); + r |= printf("INT64_BYTEORDER 0x%sLL\n", byteorder_64()); + /* Print the intrinsic type for specific numbers of bits. */ r |= printf("INT%zu %s\n", 8 * sizeof(char), "char"); r |= printf("INT%zu %s\n", 8 * sizeof(short int), "short int"); r |= printf("INT%zu %s\n", 8 * sizeof(int), "int"); r |= printf("INT%zu %s\n", 8 * sizeof(long int), "long int"); r |= printf("INT%zu %s\n", 8 * sizeof(long long int), "long long int"); + return r < 0 ? 1 : 0; } else if (argc == 2) diff --git a/gen/bits/intconf.h b/gen/bits/intconf.h index 69ea473..4d22435 100644 --- a/gen/bits/intconf.h +++ b/gen/bits/intconf.h @@ -97,6 +97,24 @@ #define __WCHAR_BIT //(bin/gen/bits/intconf | grep ^WCHAR_BIT | sed "s/^[^ ]* //") /** + * The 16-bit integer 0x0102 but with the + * bytes swapped to the storage order. + */ +#define __INT16_BYTEORDER //(bin/gen/bits/intconf | grep ^INT16_BYTEORDER | sed "s/^[^ ]* //") + +/** + * The 32-bit integer 0x01020304 but with + * the bytes swapped to the storage order. + */ +#define __INT32_BYTEORDER //(bin/gen/bits/intconf | grep ^INT32_BYTEORDER | sed "s/^[^ ]* //") + +/** + * The 64-bit integer 0x0102030405060708 but with + * the bytes swapped to the storage order. + */ +#define __INT64_BYTEORDER //(bin/gen/bits/intconf | grep ^INT64_BYTEORDER | sed "s/^[^ ]* //") + +/** * The underlaying intrinsic type for `int8_t` or `uint8_t`. */ #define __INT8 //(bin/gen/bits/intconf | grep ^INT8 | sed "s/^[^ ]* //" | sed 1q) diff --git a/src/arpa/inet/htonl.c b/src/arpa/inet/htonl.c index 7d998d4..8422fdc 100644 --- a/src/arpa/inet/htonl.c +++ b/src/arpa/inet/htonl.c @@ -16,6 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <arpa/inet.h> +#include <bits/intconf.h> + /** @@ -31,11 +33,19 @@ */ uint32_t _htonl(uint32_t value) { +#if __INT32_BYTEORDER == 0x01020304 + return value; +#elif __INT32_BYTEORDER == 0x04030201 + return (value >> 24) | ((value & 0xFF0000) >> 8) | ((value & 0x00FF00) << 8) | (value << 24); +#elif __INT32_BYTEORDER == 0x02010403 + return (value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); +#else char rc[4]; rc[0] = (value >> 24) & 255; rc[1] = (value >> 16) & 255; rc[2] = (value >> 8) & 255; rc[3] = (value >> 0) & 255; return *(uint32_t*)rc; +#endif } diff --git a/src/arpa/inet/htonll.c b/src/arpa/inet/htonll.c index 230d47b..d4509ef 100644 --- a/src/arpa/inet/htonll.c +++ b/src/arpa/inet/htonll.c @@ -16,6 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <arpa/inet.h> +#include <bits/intconf.h> + /** @@ -33,6 +35,21 @@ */ uint64_t _htonll(uint64_t value) { +#if __INT64_BYTEORDER == 0x0102030405060708LL + return value; +#elif __INT64_BYTEORDER == 0x0807060504030201LL + uint64_t rc = value; + /* 08 07 06 05 04 03 02 01 */ + rc = ((rc & 0xFF00FF00FF00FF00ULL) >> 8) || ((rc & 0x00FF00FF00FF00FFULL) << 8); + /* 0708 0506 0304 0102 */ + rc = ((rc & 0xFFFF0000FFFF0000ULL) >> 16) || ((rc & 0x0000FFFF0000FFFFULL) << 16); + /* 05060708 01020304 */ + rc = ((rc & 0xFFFFFFFF00000000ULL) >> 32) || ((rc & 0x00000000FFFFFFFFULL) << 32); + /* 0102030405060708 */ + return rc; +#elif __INT64_BYTEORDER == 0x0201040306050807LL + return (value & 0xFF00FF00FF00FF00ULL) >> 8) | ((value & 0x00FF00FF00FF00FFULL) << 8); +#else char rc[8]; rc[0] = (value >> 56) & 255; rc[1] = (value >> 48) & 255; @@ -43,5 +60,6 @@ uint64_t _htonll(uint64_t value) rc[6] = (value >> 8) & 255; rc[7] = (value >> 0) & 255; return *(uint64_t*)rc; +#endif } diff --git a/src/arpa/inet/htons.c b/src/arpa/inet/htons.c index 78592e9..1aeb39c 100644 --- a/src/arpa/inet/htons.c +++ b/src/arpa/inet/htons.c @@ -16,6 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <arpa/inet.h> +#include <bits/intconf.h> + /** @@ -31,9 +33,10 @@ */ uint16_t _htons(uint16_t value) { - char rc[2]; - rc[0] = (value >> 8) & 255; - rc[1] = (value >> 0) & 255; - return *(uint16_t*)rc; +#if __INT16_BYTEORDER == 0x0102 + return value; +#else + return (value >> 8) | (value << 8); +#endif } diff --git a/src/arpa/inet/ntohl.c b/src/arpa/inet/ntohl.c index 8eb5a3d..7111c28 100644 --- a/src/arpa/inet/ntohl.c +++ b/src/arpa/inet/ntohl.c @@ -16,6 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <arpa/inet.h> +#include <bits/intconf.h> + /** @@ -31,6 +33,13 @@ */ uint32_t _ntohl(uint32_t value) { +#if __INT32_BYTEORDER == 0x01020304 + return value; +#elif __INT32_BYTEORDER == 0x04030201 + return (value >> 24) | ((value & 0xFF0000) >> 8) | ((value & 0x00FF00) << 8) | (value << 24); +#elif __INT32_BYTEORDER == 0x02010403 + return (value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); +#else unsigned char* v = (unsigned char*)&value; uint32_t rc = 0; rc |= (uint32_t)(v[0]) << 24; @@ -38,5 +47,6 @@ uint32_t _ntohl(uint32_t value) rc |= (uint32_t)(v[2]) << 8; rc |= (uint32_t)(v[3]) << 0; return rc; +#endif } diff --git a/src/arpa/inet/ntohll.c b/src/arpa/inet/ntohll.c index f25d64c..411deeb 100644 --- a/src/arpa/inet/ntohll.c +++ b/src/arpa/inet/ntohll.c @@ -16,6 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <arpa/inet.h> +#include <bits/intconf.h> + /** @@ -33,6 +35,21 @@ */ uint64_t _ntohll(uint64_t value) { +#if __INT64_BYTEORDER == 0x0102030405060708LL + return value; +#elif __INT64_BYTEORDER == 0x0807060504030201LL + uint64_t rc = value; + /* 08 07 06 05 04 03 02 01 */ + rc = ((rc & 0xFF00FF00FF00FF00ULL) >> 8) || ((rc & 0x00FF00FF00FF00FFULL) << 8); + /* 0708 0506 0304 0102 */ + rc = ((rc & 0xFFFF0000FFFF0000ULL) >> 16) || ((rc & 0x0000FFFF0000FFFFULL) << 16); + /* 05060708 01020304 */ + rc = ((rc & 0xFFFFFFFF00000000ULL) >> 32) || ((rc & 0x00000000FFFFFFFFULL) << 32); + /* 0102030405060708 */ + return rc; +#elif __INT64_BYTEORDER == 0x0201040306050807LL + return (value & 0xFF00FF00FF00FF00ULL) >> 8) | ((value & 0x00FF00FF00FF00FFULL) << 8); +#else unsigned char* v = (unsigned char*)&value; uint64_t rc = 0; rc |= (uint64_t)(v[0]) << 56; @@ -44,5 +61,6 @@ uint64_t _ntohll(uint64_t value) rc |= (uint64_t)(v[6]) << 8; rc |= (uint64_t)(v[7]) << 0; return rc; +#endif } diff --git a/src/arpa/inet/ntohs.c b/src/arpa/inet/ntohs.c index 7aea8a0..6bf95a5 100644 --- a/src/arpa/inet/ntohs.c +++ b/src/arpa/inet/ntohs.c @@ -16,6 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <arpa/inet.h> +#include <bits/intconf.h> + /** @@ -31,10 +33,10 @@ */ uint16_t _ntohs(uint16_t value) { - unsigned char* v = (unsigned char*)&value; - uint16_t rc = 0; - rc |= (uint16_t)(v[0]) << 8; - rc |= (uint16_t)(v[1]) << 0; - return rc; +#if __INT16_BYTEORDER == 0x0102 + return value; +#else + return (value >> 8) | (value << 8); +#endif } |