diff --git a/kit/mcpp.toml b/kit/mcpp.toml index 0412d1a..df896e5 100644 --- a/kit/mcpp.toml +++ b/kit/mcpp.toml @@ -1,7 +1,7 @@ [package] namespace = "mcpplibs" name = "openkal-kit" -version = "0.3.0" +version = "0.3.1" description = "Facilities composed from openkal's interfaces. Not part of the specification, and structurally incapable of being mistaken for it." license = "Apache-2.0" authors = ["mcpplibs"] @@ -98,4 +98,4 @@ openkal = "0.25.0" # same reason: a change spanning the specification and an implementation must be # tested against both halves as written, not against whichever half is published. [target.'cfg(os = "linux")'.dev-dependencies] -openkal-linux = { version = "0.25.0", features = ["standalone"] } +openkal-linux = { version = "0.26.0", features = ["standalone"] } diff --git a/kit/src/endpoint.cppm b/kit/src/endpoint.cppm index 91df6a1..365c32c 100644 --- a/kit/src/endpoint.cppm +++ b/kit/src/endpoint.cppm @@ -104,10 +104,13 @@ constexpr format_result format_v4(const kal_endpoint& ep, char* out, kal_uintptr if (cap < 22) return { 0, false }; kal_uintptr n = 0; + // EVERY DIGIT OF THE NUMBER (0.3.1). An octet has at most three and a port + // five; written as three, port 8080 came out as "080". auto digits = [&](unsigned v) { - if (v >= 100) out[n++] = static_cast('0' + (v / 100) % 10); - if (v >= 10) out[n++] = static_cast('0' + (v / 10) % 10); - out[n++] = static_cast('0' + v % 10); + char reversed[5] = {}; + int k = 0; + do { reversed[k++] = static_cast('0' + v % 10); v /= 10; } while (v != 0 && k < 5); + while (k > 0) out[n++] = reversed[--k]; }; for (int octet = 0; octet < 4; ++octet) { diff --git a/kit/tests/kit.cpp b/kit/tests/kit.cpp index c41b390..5cc2f9c 100644 --- a/kit/tests/kit.cpp +++ b/kit/tests/kit.cpp @@ -71,6 +71,27 @@ void endpoint_section() { std::memcmp(again.ep.addr, ep.addr, 4) == 0, "formatting and parsing are inverses"); } + // EVERY DIGIT OF A PORT (0.3.1). The formatter wrote at most three digits + // of each number, which is every digit of an octet and not of a port: + // 8080 came out as "080". No port is written as none, and each other one + // is written whole and reads back as itself. + { + struct { kal_u32 port; const char* text; } const ports[] = { + { 0, "127.0.0.1" }, + { 80, "127.0.0.1:80" }, + { 8080, "127.0.0.1:8080" }, + { 65535, "127.0.0.1:65535" }, + }; + for (const auto& p : ports) { + char buf[32] = {}; + const auto f = format_v4(loopback_v4(p.port), buf, sizeof buf); + const kal_uintptr len = std::strlen(p.text); + check(f.ok && f.n == len && std::memcmp(buf, p.text, len) == 0, + "a port is written with all its digits"); + const auto again = parse_v4(buf, f.n); + check(again.ok && again.ep.port == p.port, "and reads back as the port it was"); + } + } { char small[8] = {}; const auto f = format_v4(loopback_v4(443), small, sizeof small);