diff --git a/endian_swap.h b/endian_swap.h index a462f9a..aec6295 100644 --- a/endian_swap.h +++ b/endian_swap.h @@ -3,6 +3,16 @@ #include #include +#include "assert_helpers.h" + +#ifdef BOWTIE_64BIT_INDEX +# define endianSwapU(x) endianSwapU64(x) +# define endianSwapI(x) endianSwapI64(x) +#else +# define endianSwapU(x) endianSwapU32(x) +# define endianSwapI(x) endianSwapI32(x) +#endif + /** * Return true iff the machine running this program is big-endian. @@ -54,25 +64,55 @@ static inline int32_t endianSwapI32(int32_t i) { } /** - * Convert uint32_t argument to the specified endianness. It's assumed + * Return copy of int64_t argument with byte order reversed. + */ +static inline int64_t endianSwapI64(int64_t u) { + int64_t tmp = 0; + tmp |= ((u >> 56) & (0xffull << 0)); + tmp |= ((u >> 40) & (0xffull << 8)); + tmp |= ((u >> 24) & (0xffull << 16)); + tmp |= ((u >> 8) & (0xffull << 24)); + tmp |= ((u << 8) & (0xffull << 32)); + tmp |= ((u << 24) & (0xffull << 40)); + tmp |= ((u << 40) & (0xffull << 48)); + tmp |= ((u << 56) & (0xffull << 56)); + return tmp; +} + +/** + * Convert uint32_t/uint64_t argument to the specified endianness. It's assumed * that u currently has the endianness of the current machine. */ -static inline uint32_t endianizeU32(uint32_t u, bool toBig) { +template +static inline T endianizeU(T u, bool toBig) { if(toBig == currentlyBigEndian()) { return u; } - return endianSwapU32(u); + if(sizeof(T) == 4) { + return endianSwapU32((uint32_t)u); + } else if(sizeof(T) == 8) { + return endianSwapU64((uint64_t)u); + } else { + assert(false); + } } /** - * Convert int32_t argument to the specified endianness. It's assumed + * Convert int32_t/int64_t argument to the specified endianness. It's assumed * that u currently has the endianness of the current machine. */ -static inline int32_t endianizeI32(int32_t i, bool toBig) { +template +static inline T endianizeI(T i, bool toBig) { if(toBig == currentlyBigEndian()) { return i; } - return endianSwapI32(i); + if(sizeof(T) == 4) { + return endianSwapI32((int32_t)i); + } else if(sizeof(T) == 8) { + return endianSwapI64((int64_t)i); + } else { + assert(false); + } } #endif diff --git a/word_io.h b/word_io.h index 1ec051e..b2752a3 100644 --- a/word_io.h +++ b/word_io.h @@ -9,131 +9,115 @@ #include "btypes.h" /** - * Write a 32-bit unsigned to an output stream being careful to + * Write a 32/64 bit unsigned to an output stream being careful to * re-endianize if caller-requested endianness differs from current * host. */ -static inline void writeU32(std::ostream& out, uint32_t x, bool toBigEndian) { - uint32_t y = endianizeU32(x, toBigEndian); - out.write((const char*)&y, 4); +template +static inline void writeU(std::ostream& out, T x, bool toBigEndian) { + T y = endianizeU(x, toBigEndian); + out.write((const char*)&y, sizeof(T)); } /** - * Write a 32-bit unsigned to an output stream using the native + * Write a 32/64 bit unsigned to an output stream using the native * endianness. */ -static inline void writeU32(std::ostream& out, uint32_t x) { - out.write((const char*)&x, 4); +template +static inline void writeU(std::ostream& out, T x) { + out.write((const char*)&x, sizeof(T)); } /** - * Write a 32-bit signed int to an output stream being careful to + * Write a 32/64 bit signed int to an output stream being careful to * re-endianize if caller-requested endianness differs from current * host. */ -static inline void writeI32(std::ostream& out, int32_t x, bool toBigEndian) { - int32_t y = endianizeI32(x, toBigEndian); - out.write((const char*)&y, 4); +template +static inline void writeI(std::ostream& out, T x, bool toBigEndian) { + T y = endianizeI(x, toBigEndian); + out.write((const char*)&y, sizeof(T)); } /** - * Write a 32-bit unsigned to an output stream using the native + * Write a 32/64 bit unsigned to an output stream using the native * endianness. */ -static inline void writeI32(std::ostream& out, int32_t x) { - out.write((const char*)&x, 4); +template +static inline void writeI(std::ostream& out, T x) { + out.write((const char*)&x, sizeof(T)); } -/** - * Read a 32-bit unsigned from an input stream, inverting endianness - * if necessary. - */ -static inline uint32_t readU32(std::istream& in, bool swap) { - uint32_t x; - in.read((char *)&x, 4); - assert_eq(4, in.gcount()); +template +static inline T readU(std::istream& in, bool swap) { + T x; + in.read((char *)&x, sizeof(T)); + assert_eq(sizeof(T), in.gcount()); if(swap) { - return endianSwapU32(x); + if(sizeof(T) == 4) { + return endianSwapU32(x); + } else if(sizeof(T) == 8) { + return endianSwapU64(x); + } else { + assert(false); + } } else { return x; } } -/** - * Read a 32-bit unsigned from a file descriptor, optionally inverting - * endianness. - */ -static inline uint32_t readU32(int in, bool swap) { - uint32_t x; - if(read(in, (void *)&x, 4) != 4) { - assert(false); - } - if(swap) { - return endianSwapU32(x); - } else { - return x; - } -} -/** - * Read a 32-bit unsigned from a FILE*, optionally inverting - * endianness. - */ -static inline uint32_t readU32(FILE* in, bool swap) { - uint32_t x; - if(fread((void *)&x, 1, 4, in) != 4) { +template +static inline T readU(FILE* in, bool swap) { + T x; + if(fread((void *)&x, 1, sizeof(T), in) != sizeof(T)) { assert(false); } if(swap) { - return endianSwapU32(x); - } else { - return x; - } -} - - -/** - * Read a 32-bit signed from an input stream, inverting endianness - * if necessary. - */ -static inline int32_t readI32(std::istream& in, bool swap) { - int32_t x; - in.read((char *)&x, 4); - assert_eq(4, in.gcount()); - if(swap) { - return endianSwapI32(x); + if(sizeof(T) == 4) { + return endianSwapU32(x); + } else if(sizeof(T) == 8) { + return endianSwapU64(x); + } else { + assert(false); + } } else { return x; } } -/** - * Read a 32-bit unsigned from a file descriptor, optionally inverting - * endianness. - */ -static inline uint32_t readI32(int in, bool swap) { - int32_t x; - if(read(in, (void *)&x, 4) != 4) { - assert(false); - } +template +static inline T readI(std::istream& in, bool swap) { + T x; + in.read((char *)&x, sizeof(T)); + assert_eq(sizeof(T), in.gcount()); if(swap) { - return endianSwapI32(x); + if(sizeof(T) == 4) { + return endianSwapI32(x); + } else if(sizeof(T) == 8) { + return endianSwapI64(x); + } else { + assert(false); + } } else { return x; } } -/** - * Read a 32-bit unsigned from a FILE*, optionally inverting - * endianness. - */ -static inline uint32_t readI32(FILE* in, bool swap) { - int32_t x; - if(fread((void *)&x, 1, 4, in) != 4) { +template +static inline T readI(FILE* in, bool swap) { + T x; + if(fread((void *)&x, 1, sizeof(T), in) != sizeof(T)) { assert(false); } if(swap) { - return endianSwapI32(x); + if(sizeof(T) == 4) { + return endianSwapI32(x); + } else if(sizeof(T) == 8) { + return endianSwapI64(x); + } else { + assert(false); + } } else { return x; }