diff --git a/README.md b/README.md index c5578b5..bb0ff60 100644 --- a/README.md +++ b/README.md @@ -587,7 +587,7 @@ can contain `\NUL` (`\0`) and not necessary NUL-terminated strings. `std::string embed `\0` as well, but please note that when constructing `std::string` from a C-style string the string will be terminated by the first `\0` character. Rather, you need to use the constructor with the `count` parameter explicitly. When unpack a `std::string` that contains `\0`, you need -`.data()`, and `.c_str()` won't work. +`.data()`, ```c++ std::string key = "key-foo\0bar"; diff --git a/tst/EtcdTest.cpp b/tst/EtcdTest.cpp index 5b9f403..ff3a16c 100644 --- a/tst/EtcdTest.cpp +++ b/tst/EtcdTest.cpp @@ -46,59 +46,6 @@ TEST_CASE("read a value from etcd") CHECK("" == etcd.get("/test").get().value().as_string()); // key points to a directory } -TEST_CASE("using binary keys and values, raw char pointer doesn't work") -{ - etcd::Client etcd(etcd_url); - etcd.rmdir("/test", true).wait(); - { - etcd::Response resp = etcd.put("/test/key1\0xyz", "42\0foo").get(); - REQUIRE(resp.is_ok()); - } - { - // should not exist - etcd::Response resp = etcd.get(std::string("/test/key1\0xyz", 14)).get(); - CHECK(!resp.is_ok()); - CHECK(etcd::ERROR_KEY_NOT_FOUND == resp.error_code()); - } - { - // should exist - etcd::Response resp = etcd.get(std::string("/test/key1", 10)).get(); - REQUIRE(resp.is_ok()); - CHECK(std::string("42") == resp.value().as_string()); - CHECK(std::string("42\0foo", 6) != resp.value().as_string()); - } - { - // should exist - etcd::Response resp = etcd.get("/test/key1\0xyz").get(); - REQUIRE(resp.is_ok()); - CHECK(std::string("42") == resp.value().as_string()); - CHECK(std::string("42\0foo", 6) != resp.value().as_string()); - } -} - -TEST_CASE("using binary keys and values, std::string is ok for \\0") -{ - etcd::Client etcd(etcd_url); - etcd.rmdir("/test", true).wait(); - { - etcd::Response resp = etcd.put(std::string("/test/key1\0xyz", 14), std::string("42\0foo", 6)).get(); - REQUIRE(resp.is_ok()); - } - { - // should not exist - etcd::Response resp = etcd.get("/test/key1").get(); - CHECK(!resp.is_ok()); - CHECK(etcd::ERROR_KEY_NOT_FOUND == resp.error_code()); - } - { - // should exist - etcd::Response resp = etcd.get(std::string("/test/key1\0xyz", 14)).get(); - REQUIRE(resp.is_ok()); - CHECK(std::string("42") != resp.value().as_string()); - CHECK(std::string("42\0foo", 6) == resp.value().as_string()); - } -} - TEST_CASE("simplified read") { etcd::Client etcd(etcd_url); @@ -254,6 +201,59 @@ TEST_CASE("deep atomic compare-and-swap") CHECK("etcd-cpp-apiv3: compare failed" == res.error_message()); } +TEST_CASE("using binary keys and values, raw char pointer doesn't work") +{ + etcd::Client etcd(etcd_url); + etcd.rmdir("/test", true).wait(); + { + etcd::Response resp = etcd.put("/test/key1\0xyz", "42\0foo").get(); + REQUIRE(resp.is_ok()); + } + { + // should not exist + etcd::Response resp = etcd.get(std::string("/test/key1\0xyz", 14)).get(); + CHECK(!resp.is_ok()); + CHECK(etcd::ERROR_KEY_NOT_FOUND == resp.error_code()); + } + { + // should exist + etcd::Response resp = etcd.get(std::string("/test/key1", 10)).get(); + REQUIRE(resp.is_ok()); + CHECK(std::string("42") == resp.value().as_string()); + CHECK(std::string("42\0foo", 6) != resp.value().as_string()); + } + { + // should exist + etcd::Response resp = etcd.get("/test/key1\0xyz").get(); + REQUIRE(resp.is_ok()); + CHECK(std::string("42") == resp.value().as_string()); + CHECK(std::string("42\0foo", 6) != resp.value().as_string()); + } +} + +TEST_CASE("using binary keys and values, std::string is ok for \\0") +{ + etcd::Client etcd(etcd_url); + etcd.rmdir("/test", true).wait(); + { + etcd::Response resp = etcd.put(std::string("/test/key1\0xyz", 14), std::string("42\0foo", 6)).get(); + REQUIRE(resp.is_ok()); + } + { + // should not exist + etcd::Response resp = etcd.get("/test/key1").get(); + CHECK(!resp.is_ok()); + CHECK(etcd::ERROR_KEY_NOT_FOUND == resp.error_code()); + } + { + // should exist + etcd::Response resp = etcd.get(std::string("/test/key1\0xyz", 14)).get(); + REQUIRE(resp.is_ok()); + CHECK(std::string("42") != resp.value().as_string()); + CHECK(std::string("42\0foo", 6) == resp.value().as_string()); + } +} + TEST_CASE("list a directory") { etcd::Client etcd(etcd_url);