aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gen/bits/intconf.c82
-rw-r--r--gen/bits/intconf.h18
-rw-r--r--src/arpa/inet/htonl.c10
-rw-r--r--src/arpa/inet/htonll.c18
-rw-r--r--src/arpa/inet/htons.c11
-rw-r--r--src/arpa/inet/ntohl.c10
-rw-r--r--src/arpa/inet/ntohll.c18
-rw-r--r--src/arpa/inet/ntohs.c12
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
}