diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2014-05-12 16:04:46 -0700 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2014-05-12 17:29:01 -0700 |
commit | 794c162c9e92cbcdad73cb82f545876a47afae92 (patch) | |
tree | 3b663d40f96fc32d0848d0ae513185bdd4367a92 /src/ints | |
parent | c87b1dc338eadc68accac02563a487d7d8e1c9a0 (diff) | |
download | tmwa-794c162c9e92cbcdad73cb82f545876a47afae92.tar.gz tmwa-794c162c9e92cbcdad73cb82f545876a47afae92.tar.bz2 tmwa-794c162c9e92cbcdad73cb82f545876a47afae92.tar.xz tmwa-794c162c9e92cbcdad73cb82f545876a47afae92.zip |
Implement proto v2
Diffstat (limited to 'src/ints')
-rw-r--r-- | src/ints/little.cpp | 21 | ||||
-rw-r--r-- | src/ints/little.hpp | 131 |
2 files changed, 152 insertions, 0 deletions
diff --git a/src/ints/little.cpp b/src/ints/little.cpp new file mode 100644 index 0000000..2f81954 --- /dev/null +++ b/src/ints/little.cpp @@ -0,0 +1,21 @@ +#include "little.hpp" +// little.cpp - integers of known endianness +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// 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 <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" diff --git a/src/ints/little.hpp b/src/ints/little.hpp new file mode 100644 index 0000000..d7d57ff --- /dev/null +++ b/src/ints/little.hpp @@ -0,0 +1,131 @@ +#ifndef TMWA_INTS_LITTLE_HPP +#define TMWA_INTS_LITTLE_HPP +// little.hpp - integers of known endianness +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// 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 <http://www.gnu.org/licenses/>. + +# include "fwd.hpp" + +# include <endian.h> + +# include <cstdint> + +// We implement our own actual swapping, because glibc emits assembly +// instead of letting the *compiler* do what it does best. +# if __BYTE_ORDER != __BIG_ENDIAN && __BYTE_ORDER != __LITTLE_ENDIAN +# error "broken endians" +# endif + +namespace ints +{ + // TODO hoist this to byte.hpp and also implement big.hpp + struct Byte + { + uint8_t value; + }; + + struct Little16 + { + uint8_t data[2]; + }; + + struct Little32 + { + uint8_t data[4]; + }; + + struct Little64 + { + uint8_t data[8]; + }; + + inline __attribute__((warn_unused_result)) + bool native_to_network(Byte *net, uint8_t nat) + { + net->value = nat; + return true; + } + inline __attribute__((warn_unused_result)) + bool native_to_network(Little16 *net, uint16_t nat) + { + if (__BYTE_ORDER == __BIG_ENDIAN) + nat = __builtin_bswap16(nat); + __builtin_memcpy(net, &nat, 2); + return true; + } + inline __attribute__((warn_unused_result)) + bool native_to_network(Little32 *net, uint32_t nat) + { + if (__BYTE_ORDER == __BIG_ENDIAN) + nat = __builtin_bswap32(nat); + __builtin_memcpy(net, &nat, 2); + return true; + } + inline __attribute__((warn_unused_result)) + bool native_to_network(Little64 *net, uint64_t nat) + { + if (__BYTE_ORDER == __BIG_ENDIAN) + nat = __builtin_bswap64(nat); + __builtin_memcpy(net, &nat, 2); + return true; + } + + inline __attribute__((warn_unused_result)) + bool network_to_native(uint8_t *nat, Byte net) + { + *nat = net.value; + return true; + } + inline __attribute__((warn_unused_result)) + bool network_to_native(uint16_t *nat, Little16 net) + { + uint16_t tmp; + __builtin_memcpy(&tmp, &net, 2); + if (__BYTE_ORDER == __BIG_ENDIAN) + tmp = __builtin_bswap16(tmp); + *nat = tmp; + return true; + } + inline __attribute__((warn_unused_result)) + bool network_to_native(uint32_t *nat, Little32 net) + { + uint32_t tmp; + __builtin_memcpy(&tmp, &net, 4); + if (__BYTE_ORDER == __BIG_ENDIAN) + tmp = __builtin_bswap32(tmp); + *nat = tmp; + return true; + } + inline __attribute__((warn_unused_result)) + bool network_to_native(uint64_t *nat, Little64 net) + { + uint64_t tmp; + __builtin_memcpy(&tmp, &net, 8); + if (__BYTE_ORDER == __BIG_ENDIAN) + tmp = __builtin_bswap64(tmp); + *nat = tmp; + return true; + } +} // namespace ints + +using ints::Byte; +using ints::Little16; +using ints::Little32; +using ints::Little64; + +#endif // TMWA_INTS_LITTLE_HPP |