rewrite the endian conversion to fix a big-endian host
Client: py

Change htolell(dub) to htolell(transfer.t) in compact.h, because the
conversion takes a long long, not a double.  This matters on a
big-endian host, where the conversion must swap bytes.

The big-endian letohll(n) failed because ntohl(n) is just n, doesn't
swap n.  Rewrite ntohll(n) and letohll(n) to use the same code with
both big-endian and little-endian hosts.  Expect the compiler to
optimize away one of ntohll(n) or letohll(n) when it doesn't swap n.
diff --git a/lib/py/src/ext/endian.h b/lib/py/src/ext/endian.h
index a2cf594..13c9b6b 100644
--- a/lib/py/src/ext/endian.h
+++ b/lib/py/src/ext/endian.h
@@ -27,70 +27,41 @@
 #else
 #include <winsock2.h>
 #pragma comment(lib, "ws2_32.lib")
-#define BIG_ENDIAN (4321)
-#define LITTLE_ENDIAN (1234)
-#define BYTE_ORDER LITTLE_ENDIAN
 #define inline __inline
 #endif
 
-/* Fix endianness issues on Solaris */
-#if defined(__SVR4) && defined(__sun)
-#if defined(__i386) && !defined(__i386__)
-#define __i386__
-#endif
+static inline unsigned long long ntohll(unsigned long long n) {
+  union {
+    unsigned long long f;
+    unsigned char t[8];
+  } u;
+  u.f = n;
+  return static_cast<unsigned long long>(u.t[0]) << 56
+         | static_cast<unsigned long long>(u.t[1]) << 48
+         | static_cast<unsigned long long>(u.t[2]) << 40
+         | static_cast<unsigned long long>(u.t[3]) << 32
+         | static_cast<unsigned long long>(u.t[4]) << 24
+         | static_cast<unsigned long long>(u.t[5]) << 16
+         | static_cast<unsigned long long>(u.t[6]) << 8 | static_cast<unsigned long long>(u.t[7]);
+}
 
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN (4321)
-#endif
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN (1234)
-#endif
+#define htonll(n) ntohll(n)
 
-/* I386 is LE, even on Solaris */
-#if !defined(BYTE_ORDER) && defined(__i386__)
-#define BYTE_ORDER LITTLE_ENDIAN
-#endif
-#endif
+static inline unsigned long long letohll(unsigned long long n) {
+  union {
+    unsigned long long f;
+    unsigned char t[8];
+  } u;
+  u.f = n;
+  return static_cast<unsigned long long>(u.t[0]) | static_cast<unsigned long long>(u.t[1]) << 8
+         | static_cast<unsigned long long>(u.t[2]) << 16
+         | static_cast<unsigned long long>(u.t[3]) << 24
+         | static_cast<unsigned long long>(u.t[4]) << 32
+         | static_cast<unsigned long long>(u.t[5]) << 40
+         | static_cast<unsigned long long>(u.t[6]) << 48
+         | static_cast<unsigned long long>(u.t[7]) << 56;
+}
 
-#ifndef __BYTE_ORDER
-#if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
-#define __BYTE_ORDER BYTE_ORDER
-#define __LITTLE_ENDIAN LITTLE_ENDIAN
-#define __BIG_ENDIAN BIG_ENDIAN
-#else
-#error "Cannot determine endianness"
-#endif
-#endif
-
-// Same comment as the enum.  Sorry.
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define ntohll(n) (n)
-#define htonll(n) (n)
-#if defined(__GNUC__) && defined(__GLIBC__)
-#include <byteswap.h>
-#define letohll(n) bswap_64(n)
-#define htolell(n) bswap_64(n)
-#else /* GNUC & GLIBC */
-#define letohll(n) ((((unsigned long long)ntohl(n)) << 32) + ntohl(n >> 32))
-#define htolell(n) ((((unsigned long long)htonl(n)) << 32) + htonl(n >> 32))
-#endif
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
-#if defined(__GNUC__) && defined(__GLIBC__)
-#include <byteswap.h>
-#define ntohll(n) bswap_64(n)
-#define htonll(n) bswap_64(n)
-#elif defined(_MSC_VER)
-#include <stdlib.h>
-#define ntohll(n) _byteswap_uint64(n)
-#define htonll(n) _byteswap_uint64(n)
-#else /* GNUC & GLIBC */
-#define ntohll(n) ((((unsigned long long)ntohl(n)) << 32) + ntohl(n >> 32))
-#define htonll(n) ((((unsigned long long)htonl(n)) << 32) + htonl(n >> 32))
-#endif /* GNUC & GLIBC */
-#define letohll(n) (n)
-#define htolell(n) (n)
-#else /* __BYTE_ORDER */
-#error "Can't define htonll or ntohll!"
-#endif
+#define htolell(n) letohll(n)
 
 #endif // THRIFT_PY_ENDIAN_H