diff --git a/source/tanya/conv.d b/source/tanya/conv.d index d80f705..2cd40b3 100644 --- a/source/tanya/conv.d +++ b/source/tanya/conv.d @@ -264,6 +264,30 @@ final class ConvException : Exception } } +package bool stringToInt(R)(R range, ref ushort n) +{ + import tanya.encoding.ascii; + import tanya.range.array; + + size_t i = 1; + uint lPort; + + for (; !range.empty && range.front.isDigit() && i <= 6; ++i, range.popFront()) + { + lPort = lPort * 10 + (range.front - '0'); + } + if (i != 1 && (range.empty || range.front == '/')) + { + if (lPort > ushort.max) + { + return false; + } + n = cast(ushort) lPort; + return true; + } + return false; +} + /** * If the source type $(D_PARAM From) and the target type $(D_PARAM To) are * equal, does nothing. If $(D_PARAM From) can be implicitly converted to diff --git a/source/tanya/net/uri.d b/source/tanya/net/uri.d index df19b56..8b05f8e 100644 --- a/source/tanya/net/uri.d +++ b/source/tanya/net/uri.d @@ -14,6 +14,7 @@ */ module tanya.net.uri; +import tanya.conv; import tanya.encoding.ascii; import tanya.memory; @@ -37,7 +38,7 @@ final class URIException : Exception this(string msg, string file = __FILE__, size_t line = __LINE__, - Throwable next = null) @nogc @safe pure nothrow + Throwable next = null) @nogc nothrow pure @safe { super(msg, file, line, next); } @@ -82,7 +83,7 @@ struct URL * * Throws: $(D_PSYMBOL URIException) if the URL is malformed. */ - this(const char[] source) pure @nogc + this(const char[] source) @nogc pure { ptrdiff_t pos = -1, endPos = source.length, start; @@ -152,16 +153,13 @@ struct URL goto ParsePath; } } - else + else if (!parsePort(source[pos .. $])) { // Schemas like mailto: and zlib: may not have any slash after // them. - if (!parsePort(source[pos .. $])) - { - this.scheme = source[0 .. pos]; - start = pos + 1; - goto ParsePath; - } + this.scheme = source[0 .. pos]; + start = pos + 1; + goto ParsePath; } } else if (pos == 0 && parsePort(source[pos .. $])) @@ -305,26 +303,9 @@ struct URL * * Returns: Whether the port could be found. */ - private bool parsePort(const char[] port) pure nothrow @safe @nogc + private bool parsePort(const(char)[] port) @nogc nothrow pure @safe { - ptrdiff_t i = 1; - float lPort = 0; - - for (; i < port.length && port[i].isDigit() && i <= 6; ++i) - { - lPort += (port[i] - '0') / cast(float) (10 ^^ (i - 1)); - } - if (i != 1 && (i == port.length || port[i] == '/')) - { - lPort *= 10 ^^ (i - 2); - if (lPort > ushort.max) - { - return false; - } - this.port = cast(ushort) lPort; - return true; - } - return false; + return stringToInt(port[1 .. $], this.port); } }