From dd569f0fa4758fe9dfd771b68518c37fe2e356b7 Mon Sep 17 00:00:00 2001 From: Ingo Ruhnke Date: Thu, 19 May 2011 19:52:10 +0200 Subject: [PATCH] Added endian clean unpack routines --- src/unpack.hpp | 104 +++++++++++++++++++++++++++++++++++++++++++ test/unpack_test.cpp | 37 +++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 src/unpack.hpp create mode 100644 test/unpack_test.cpp diff --git a/src/unpack.hpp b/src/unpack.hpp new file mode 100644 index 0000000..57f5f74 --- /dev/null +++ b/src/unpack.hpp @@ -0,0 +1,104 @@ +/* +** Xbox360 USB Gamepad Userspace Driver +** Copyright (C) 2011 Ingo Ruhnke +** +** This program is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program. If not, see . +*/ + +#ifndef HEADER_XBOXDRV_ENDIAN_HPP +#define HEADER_XBOXDRV_ENDIAN_HPP + +#include + +namespace unpack { + +inline bool is_big_endian() +{ + union { + uint32_t i; + char c[4]; + } bint = {0x01020304}; + + return bint.c[0] == 1; +} + +inline uint16_t swap16(uint16_t v) +{ + return (v<<8) | (v>>8); +} + +inline uint32_t swap32(uint32_t v) +{ + return (v<<24) | ((v<<8) & 0x00ff0000) | ((v>>8) & 0x0000ff00) | (v>>24); +} + + +inline int16_t int16le(uint8_t* data) +{ + if (is_big_endian()) return swap16(*reinterpret_cast(data)); + else return *reinterpret_cast(data); +} + +inline uint16_t uint16le(uint8_t* data) +{ + if (is_big_endian()) return swap16(*reinterpret_cast(data)); + else return *reinterpret_cast(data); +} + + +inline int32_t int32le(uint8_t* data) +{ + if (is_big_endian()) return swap32(*reinterpret_cast(data)); + else return *reinterpret_cast(data); +} + +inline uint32_t uint32le(uint8_t* data) +{ + if (is_big_endian()) return swap32(*reinterpret_cast(data)); + else return *reinterpret_cast(data); +} + + + +inline int16_t int16be(uint8_t* data) +{ + if (!is_big_endian()) return swap16(*reinterpret_cast(data)); + else return *reinterpret_cast(data); +} + +inline uint16_t uint16be(uint8_t* data) +{ + if (!is_big_endian()) return swap16(*reinterpret_cast(data)); + else return *reinterpret_cast(data); +} + + +inline int32_t int32be(uint8_t* data) +{ + if (!is_big_endian()) return swap32(*reinterpret_cast(data)); + else return *reinterpret_cast(data); +} + +inline uint32_t uint32be(uint8_t* data) +{ + if (!is_big_endian()) return swap32(*reinterpret_cast(data)); + else return *reinterpret_cast(data); +} + + +} // namespace unpack + +#endif + +/* EOF */ diff --git a/test/unpack_test.cpp b/test/unpack_test.cpp new file mode 100644 index 0000000..5c92230 --- /dev/null +++ b/test/unpack_test.cpp @@ -0,0 +1,37 @@ +/* +** Xbox360 USB Gamepad Userspace Driver +** Copyright (C) 2011 Ingo Ruhnke +** +** This program is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program. If not, see . +*/ + +#include + +#include "unpack.hpp" + +int main(int argc, char** argv) +{ + uint8_t data[] = { 0x04, 0x03, 0x02, 0x01 }; + + std::cout << std::hex; + std::cout << "uint16be: " << unpack::uint16be(data) << std::endl; + std::cout << "uint16le: " << unpack::uint16le(data) << std::endl; + + std::cout << "uint32be: " << unpack::uint32be(data) << std::endl; + std::cout << "uint32le: " << unpack::uint32le(data) << std::endl; + + return 0; +} + +/* EOF */