summaryrefslogtreecommitdiff
path: root/src/ints
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2014-05-12 16:04:46 -0700
committerBen Longbons <b.r.longbons@gmail.com>2014-05-12 17:29:01 -0700
commit794c162c9e92cbcdad73cb82f545876a47afae92 (patch)
tree3b663d40f96fc32d0848d0ae513185bdd4367a92 /src/ints
parentc87b1dc338eadc68accac02563a487d7d8e1c9a0 (diff)
downloadtmwa-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.cpp21
-rw-r--r--src/ints/little.hpp131
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