summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2017-06-13 10:42:35 +0200
committerEugen Wissner <belka@caraus.de>2017-06-13 10:42:35 +0200
commit4b0134713c7db3c542dd4dece6db43656518abb6 (patch)
treeaab609eb71e29689cea079ee917d4278874f8632 /source
parent5b90286b70e4393f65e6aeda6deeb6cadfaac4ab (diff)
downloadtanya-4b0134713c7db3c542dd4dece6db43656518abb6.tar.gz
Move new network modules into tanya.net package
tanya.net will combine tanya.async and tanya.network and provide one API for blocking and non-blocking socket programming.
Diffstat (limited to 'source')
-rw-r--r--source/tanya/net/inet.d356
-rw-r--r--source/tanya/net/package.d15
-rw-r--r--source/tanya/network/inet.d349
3 files changed, 377 insertions, 343 deletions
diff --git a/source/tanya/net/inet.d b/source/tanya/net/inet.d
new file mode 100644
index 0000000..2f47ae8
--- /dev/null
+++ b/source/tanya/net/inet.d
@@ -0,0 +1,356 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Internet utilities.
+ *
+ * Copyright: Eugene Wissner 2016-2017.
+ * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
+ * Mozilla Public License, v. 2.0).
+ * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
+ */
+module tanya.net.inet;
+
+import std.math;
+import std.range.primitives;
+import std.traits;
+
+version (unittest)
+{
+ version (Windows)
+ {
+ import core.sys.windows.winsock2;
+ version = PlattformUnittest;
+ }
+ else version (Posix)
+ {
+ import core.sys.posix.arpa.inet;
+ version = PlattformUnittest;
+ }
+}
+
+/**
+ * Represents an unsigned integer as an $(D_KEYWORD ubyte) range.
+ *
+ * The range is bidirectional. The byte order is always big-endian.
+ *
+ * It can accept any unsigned integral type but the value should fit
+ * in $(D_PARAM L) bytes.
+ *
+ * Params:
+ * L = Desired range length.
+ */
+struct NetworkOrder(uint L)
+ if (L > ubyte.sizeof && L <= ulong.sizeof)
+{
+ static if (L > uint.sizeof)
+ {
+ private alias StorageType = ulong;
+ }
+ else static if (L > ushort.sizeof)
+ {
+ private alias StorageType = uint;
+ }
+ else static if (L > ubyte.sizeof)
+ {
+ private alias StorageType = ushort;
+ }
+ else
+ {
+ private alias StorageType = ubyte;
+ }
+
+ private StorageType value;
+ private size_t size = L;
+
+ const pure nothrow @safe @nogc invariant
+ {
+ assert(this.size <= L);
+ }
+
+ /**
+ * Constructs a new range.
+ *
+ * $(D_PARAM T) can be any unsigned type but $(D_PARAM value) cannot be
+ * larger than the maximum can be stored in $(D_PARAM L) bytes. Otherwise
+ * an assertion failure will be caused.
+ *
+ * Params:
+ * T = Value type.
+ * value = The value should be represented by this range.
+ *
+ * Precondition: $(D_INLINECODE value <= 2 ^^ (length * 8) - 1).
+ */
+ this(T)(const T value)
+ if (isUnsigned!T)
+ in
+ {
+ assert(value <= pow(2, L * 8) - 1);
+ }
+ body
+ {
+ this.value = value & StorageType.max;
+ }
+
+ /**
+ * Returns: LSB.
+ *
+ * Precondition: $(D_INLINECODE length > 0).
+ */
+ @property ubyte back() const
+ in
+ {
+ assert(this.length > 0);
+ }
+ body
+ {
+ return this.value & 0xff;
+ }
+
+ /**
+ * Returns: MSB.
+ *
+ * Precondition: $(D_INLINECODE length > 0).
+ */
+ @property ubyte front() const
+ in
+ {
+ assert(this.length > 0);
+ }
+ body
+ {
+ return (this.value >> ((this.length - 1) * 8)) & 0xff;
+ }
+
+ /**
+ * Eliminates the LSB.
+ *
+ * Precondition: $(D_INLINECODE length > 0).
+ */
+ void popBack()
+ in
+ {
+ assert(this.length > 0);
+ }
+ body
+ {
+ this.value >>= 8;
+ --this.size;
+ }
+
+ /**
+ * Eliminates the MSB.
+ *
+ * Precondition: $(D_INLINECODE length > 0).
+ */
+ void popFront()
+ in
+ {
+ assert(this.length > 0);
+ }
+ body
+ {
+ this.value &= StorageType.max >> ((StorageType.sizeof - this.length) * 8);
+ --this.size;
+ }
+
+ /**
+ * Returns: Copy of this range.
+ */
+ typeof(this) save() const
+ {
+ return this;
+ }
+
+ /**
+ * Returns: Whether the range is empty.
+ */
+ @property bool empty() const
+ {
+ return this.length == 0;
+ }
+
+ /**
+ * Returns: Byte length.
+ */
+ @property size_t length() const
+ {
+ return this.size;
+ }
+}
+
+///
+pure nothrow @safe @nogc unittest
+{
+ auto networkOrder = NetworkOrder!3(0xae34e2u);
+ assert(!networkOrder.empty);
+ assert(networkOrder.front == 0xae);
+
+ networkOrder.popFront();
+ assert(networkOrder.length == 2);
+ assert(networkOrder.front == 0x34);
+ assert(networkOrder.back == 0xe2);
+
+ networkOrder.popBack();
+ assert(networkOrder.length == 1);
+ assert(networkOrder.front == 0x34);
+ assert(networkOrder.front == 0x34);
+
+ networkOrder.popFront();
+ assert(networkOrder.empty);
+}
+
+// Static.
+private unittest
+{
+ static assert(isBidirectionalRange!(NetworkOrder!4));
+ static assert(isBidirectionalRange!(NetworkOrder!8));
+ static assert(!is(NetworkOrder!9));
+ static assert(!is(NetworkOrder!1));
+}
+
+// Tests against the system's htonl, htons.
+version (PlattformUnittest)
+{
+ private unittest
+ {
+ for (uint counter; counter <= 8 * uint.sizeof; ++counter)
+ {
+ const value = pow(2, counter) - 1;
+ const inNetworkOrder = htonl(value);
+ const p = cast(ubyte*) &inNetworkOrder;
+ auto networkOrder = NetworkOrder!4(value);
+
+ assert(networkOrder.length == 4);
+ assert(!networkOrder.empty);
+ assert(networkOrder.front == *p);
+ assert(networkOrder.back == *(p + 3));
+
+ networkOrder.popBack();
+ assert(networkOrder.length == 3);
+ assert(networkOrder.front == *p);
+ assert(networkOrder.back == *(p + 2));
+
+ networkOrder.popFront();
+ assert(networkOrder.length == 2);
+ assert(networkOrder.front == *(p + 1));
+ assert(networkOrder.back == *(p + 2));
+
+ networkOrder.popFront();
+ assert(networkOrder.length == 1);
+ assert(networkOrder.front == *(p + 2));
+ assert(networkOrder.back == *(p + 2));
+
+ networkOrder.popBack();
+ assert(networkOrder.length == 0);
+ assert(networkOrder.empty);
+ }
+
+ for (ushort counter; counter <= 8 * ushort.sizeof; ++counter)
+ {
+ const value = cast(ushort) (pow(2, counter) - 1);
+ const inNetworkOrder = htons(value);
+ const p = cast(ubyte*) &inNetworkOrder;
+
+ auto networkOrder = NetworkOrder!2(value);
+
+ assert(networkOrder.length == 2);
+ assert(!networkOrder.empty);
+ assert(networkOrder.front == *p);
+ assert(networkOrder.back == *(p + 1));
+
+ networkOrder.popBack();
+ assert(networkOrder.length == 1);
+ assert(networkOrder.front == *p);
+ assert(networkOrder.back == *p);
+
+ networkOrder.popBack();
+ assert(networkOrder.length == 0);
+ assert(networkOrder.empty);
+
+ networkOrder = NetworkOrder!2(value);
+
+ networkOrder.popFront();
+ assert(networkOrder.length == 1);
+ assert(networkOrder.front == *(p + 1));
+ assert(networkOrder.back == *(p + 1));
+
+ networkOrder.popFront();
+ assert(networkOrder.length == 0);
+ assert(networkOrder.empty);
+ }
+ }
+}
+
+/**
+ * Converts the $(D_KEYWORD ubyte) input range $(D_PARAM range) to
+ * $(D_PARAM T).
+ *
+ * The byte order of $(D_PARAM r) is assumed to be big-endian. The length
+ * cannot be larger than $(D_INLINECODE T.sizeof). Otherwise an assertion
+ * failure will be caused.
+ *
+ * Params:
+ * T = Desired return type.
+ * R = Range type.
+ * range = Input range.
+ *
+ * Returns: Integral representation of $(D_PARAM range) with the host byte
+ * order.
+ */
+T toHostOrder(T = size_t, R)(R range)
+ if (isInputRange!R
+ && !isInfinite!R
+ && is(Unqual!(ElementType!R) == ubyte)
+ && isUnsigned!T)
+{
+ T ret;
+ ushort pos = T.sizeof * 8;
+
+ for (; !range.empty && range.front == 0; pos -= 8, range.popFront())
+ {
+ }
+ for (; !range.empty; range.popFront())
+ {
+ assert(pos != 0);
+ pos -= 8;
+ ret |= (cast(T) range.front) << pos;
+ }
+
+ return ret >> pos;
+}
+
+///
+pure nothrow @safe @nogc unittest
+{
+ const value = 0xae34e2u;
+ auto networkOrder = NetworkOrder!4(value);
+ assert(networkOrder.toHostOrder() == value);
+}
+
+// Tests against the system's htonl, htons.
+version (PlattformUnittest)
+{
+ private unittest
+ {
+ for (uint counter; counter <= 8 * uint.sizeof; ++counter)
+ {
+ const value = pow(2, counter) - 1;
+ const inNetworkOrder = htonl(value);
+ const p = cast(ubyte*) &inNetworkOrder;
+ auto networkOrder = NetworkOrder!4(value);
+
+ assert(p[0 .. uint.sizeof].toHostOrder() == value);
+ }
+ for (ushort counter; counter <= 8 * ushort.sizeof; ++counter)
+ {
+ const value = cast(ushort) (pow(2, counter) - 1);
+ const inNetworkOrder = htons(value);
+ const p = cast(ubyte*) &inNetworkOrder;
+ auto networkOrder = NetworkOrder!2(value);
+
+ assert(p[0 .. ushort.sizeof].toHostOrder() == value);
+ }
+ }
+}
diff --git a/source/tanya/net/package.d b/source/tanya/net/package.d
new file mode 100644
index 0000000..e056a87
--- /dev/null
+++ b/source/tanya/net/package.d
@@ -0,0 +1,15 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Network programming.
+ *
+ * Copyright: Eugene Wissner 2017.
+ * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
+ * Mozilla Public License, v. 2.0).
+ * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
+ */
+module tanya.net;
+
+public import tanya.net.inet;
diff --git a/source/tanya/network/inet.d b/source/tanya/network/inet.d
index 9b0f28a..964f58b 100644
--- a/source/tanya/network/inet.d
+++ b/source/tanya/network/inet.d
@@ -5,352 +5,15 @@
/**
* Internet utilities.
*
- * Copyright: Eugene Wissner 2016-2017.
+ * $(RED Deprecated. Use $(D_PSYMBOL tanya.net.inet) instead.
+ * This module will be removed in 0.8.0.)
+ *
+ * Copyright: Eugene Wissner 2017.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
*/
+deprecated("Use tanya.net.inet instead")
module tanya.network.inet;
-import std.math;
-import std.range.primitives;
-import std.traits;
-
-version (unittest)
-{
- version (Windows)
- {
- import core.sys.windows.winsock2;
- version = PlattformUnittest;
- }
- else version (Posix)
- {
- import core.sys.posix.arpa.inet;
- version = PlattformUnittest;
- }
-}
-
-/**
- * Represents an unsigned integer as an $(D_KEYWORD ubyte) range.
- *
- * The range is bidirectional. The byte order is always big-endian.
- *
- * It can accept any unsigned integral type but the value should fit
- * in $(D_PARAM L) bytes.
- *
- * Params:
- * L = Desired range length.
- */
-struct NetworkOrder(uint L)
- if (L > ubyte.sizeof && L <= ulong.sizeof)
-{
- static if (L > uint.sizeof)
- {
- private alias StorageType = ulong;
- }
- else static if (L > ushort.sizeof)
- {
- private alias StorageType = uint;
- }
- else static if (L > ubyte.sizeof)
- {
- private alias StorageType = ushort;
- }
- else
- {
- private alias StorageType = ubyte;
- }
-
- private StorageType value;
- private size_t size = L;
-
- const pure nothrow @safe @nogc invariant
- {
- assert(this.size <= L);
- }
-
- /**
- * Constructs a new range.
- *
- * $(D_PARAM T) can be any unsigned type but $(D_PARAM value) cannot be
- * larger than the maximum can be stored in $(D_PARAM L) bytes. Otherwise
- * an assertion failure will be caused.
- *
- * Params:
- * T = Value type.
- * value = The value should be represented by this range.
- *
- * Precondition: $(D_INLINECODE value <= 2 ^^ (length * 8) - 1).
- */
- this(T)(const T value)
- if (isUnsigned!T)
- in
- {
- assert(value <= pow(2, L * 8) - 1);
- }
- body
- {
- this.value = value & StorageType.max;
- }
-
- /**
- * Returns: LSB.
- *
- * Precondition: $(D_INLINECODE length > 0).
- */
- @property ubyte back() const
- in
- {
- assert(this.length > 0);
- }
- body
- {
- return this.value & 0xff;
- }
-
- /**
- * Returns: MSB.
- *
- * Precondition: $(D_INLINECODE length > 0).
- */
- @property ubyte front() const
- in
- {
- assert(this.length > 0);
- }
- body
- {
- return (this.value >> ((this.length - 1) * 8)) & 0xff;
- }
-
- /**
- * Eliminates the LSB.
- *
- * Precondition: $(D_INLINECODE length > 0).
- */
- void popBack()
- in
- {
- assert(this.length > 0);
- }
- body
- {
- this.value >>= 8;
- --this.size;
- }
-
- /**
- * Eliminates the MSB.
- *
- * Precondition: $(D_INLINECODE length > 0).
- */
- void popFront()
- in
- {
- assert(this.length > 0);
- }
- body
- {
- this.value &= StorageType.max >> ((StorageType.sizeof - this.length) * 8);
- --this.size;
- }
-
- /**
- * Returns: Copy of this range.
- */
- typeof(this) save() const
- {
- return this;
- }
-
- /**
- * Returns: Whether the range is empty.
- */
- @property bool empty() const
- {
- return this.length == 0;
- }
-
- /**
- * Returns: Byte length.
- */
- @property size_t length() const
- {
- return this.size;
- }
-}
-
-///
-pure nothrow @safe @nogc unittest
-{
- auto networkOrder = NetworkOrder!3(0xae34e2u);
- assert(!networkOrder.empty);
- assert(networkOrder.front == 0xae);
-
- networkOrder.popFront();
- assert(networkOrder.length == 2);
- assert(networkOrder.front == 0x34);
- assert(networkOrder.back == 0xe2);
-
- networkOrder.popBack();
- assert(networkOrder.length == 1);
- assert(networkOrder.front == 0x34);
- assert(networkOrder.front == 0x34);
-
- networkOrder.popFront();
- assert(networkOrder.empty);
-}
-
-// Static.
-private unittest
-{
- static assert(isBidirectionalRange!(NetworkOrder!4));
- static assert(isBidirectionalRange!(NetworkOrder!8));
- static assert(!is(NetworkOrder!9));
- static assert(!is(NetworkOrder!1));
-}
-
-// Tests against the system's htonl, htons.
-version (PlattformUnittest)
-{
- private unittest
- {
- for (uint counter; counter <= 8 * uint.sizeof; ++counter)
- {
- const value = pow(2, counter) - 1;
- const inNetworkOrder = htonl(value);
- const p = cast(ubyte*) &inNetworkOrder;
- auto networkOrder = NetworkOrder!4(value);
-
- assert(networkOrder.length == 4);
- assert(!networkOrder.empty);
- assert(networkOrder.front == *p);
- assert(networkOrder.back == *(p + 3));
-
- networkOrder.popBack();
- assert(networkOrder.length == 3);
- assert(networkOrder.front == *p);
- assert(networkOrder.back == *(p + 2));
-
- networkOrder.popFront();
- assert(networkOrder.length == 2);
- assert(networkOrder.front == *(p + 1));
- assert(networkOrder.back == *(p + 2));
-
- networkOrder.popFront();
- assert(networkOrder.length == 1);
- assert(networkOrder.front == *(p + 2));
- assert(networkOrder.back == *(p + 2));
-
- networkOrder.popBack();
- assert(networkOrder.length == 0);
- assert(networkOrder.empty);
- }
-
- for (ushort counter; counter <= 8 * ushort.sizeof; ++counter)
- {
- const value = cast(ushort) (pow(2, counter) - 1);
- const inNetworkOrder = htons(value);
- const p = cast(ubyte*) &inNetworkOrder;
-
- auto networkOrder = NetworkOrder!2(value);
-
- assert(networkOrder.length == 2);
- assert(!networkOrder.empty);
- assert(networkOrder.front == *p);
- assert(networkOrder.back == *(p + 1));
-
- networkOrder.popBack();
- assert(networkOrder.length == 1);
- assert(networkOrder.front == *p);
- assert(networkOrder.back == *p);
-
- networkOrder.popBack();
- assert(networkOrder.length == 0);
- assert(networkOrder.empty);
-
- networkOrder = NetworkOrder!2(value);
-
- networkOrder.popFront();
- assert(networkOrder.length == 1);
- assert(networkOrder.front == *(p + 1));
- assert(networkOrder.back == *(p + 1));
-
- networkOrder.popFront();
- assert(networkOrder.length == 0);
- assert(networkOrder.empty);
- }
- }
-}
-
-/**
- * Converts the $(D_KEYWORD ubyte) input range $(D_PARAM range) to
- * $(D_PARAM T).
- *
- * The byte order of $(D_PARAM r) is assumed to be big-endian. The length
- * cannot be larger than $(D_INLINECODE T.sizeof). Otherwise an assertion
- * failure will be caused.
- *
- * Params:
- * T = Desired return type.
- * R = Range type.
- * range = Input range.
- *
- * Returns: Integral representation of $(D_PARAM range) with the host byte
- * order.
- */
-T toHostOrder(T = size_t, R)(R range)
- if (isInputRange!R
- && !isInfinite!R
- && is(Unqual!(ElementType!R) == ubyte)
- && isUnsigned!T)
-{
- T ret;
- ushort pos = T.sizeof * 8;
-
- for (; !range.empty && range.front == 0; pos -= 8, range.popFront())
- {
- }
- for (; !range.empty; range.popFront())
- {
- assert(pos != 0);
- pos -= 8;
- ret |= (cast(T) range.front) << pos;
- }
-
- return ret >> pos;
-}
-
-///
-pure nothrow @safe @nogc unittest
-{
- const value = 0xae34e2u;
- auto networkOrder = NetworkOrder!4(value);
- assert(networkOrder.toHostOrder() == value);
-}
-
-// Tests against the system's htonl, htons.
-version (PlattformUnittest)
-{
- private unittest
- {
- for (uint counter; counter <= 8 * uint.sizeof; ++counter)
- {
- const value = pow(2, counter) - 1;
- const inNetworkOrder = htonl(value);
- const p = cast(ubyte*) &inNetworkOrder;
- auto networkOrder = NetworkOrder!4(value);
-
- assert(p[0 .. uint.sizeof].toHostOrder() == value);
- }
- for (ushort counter; counter <= 8 * ushort.sizeof; ++counter)
- {
- const value = cast(ushort) (pow(2, counter) - 1);
- const inNetworkOrder = htons(value);
- const p = cast(ubyte*) &inNetworkOrder;
- auto networkOrder = NetworkOrder!2(value);
-
- assert(p[0 .. ushort.sizeof].toHostOrder() == value);
- }
- }
-}
+public import tanya.net.inet;