From 592f988ae2fe8d59959f2bdca5c1b5b372b7059c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 17 Jun 2013 20:42:23 +0100 Subject: [PATCH] os: Improve String with more comments and checks. Thanks to Alexander Monakov for drawing attention to inconsistencies in os::String::truncate(void). --- common/os_string.hpp | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/common/os_string.hpp b/common/os_string.hpp index 35156a1..996c619 100644 --- a/common/os_string.hpp +++ b/common/os_string.hpp @@ -68,8 +68,20 @@ namespace os { /** - * Vector based zero-terminate string, suitable for passing strings or paths - * to/from OS calls. + * Class to represent zero-terminated strings, based upon std::vector, + * suitable for passing strings or paths to/from OS calls. + * + * Both Win32 and POSIX APIs return strings as zero length buffers. Although + * std::string provides an easy method to obtain a read-only pointer to a zero + * terminated string, it lacks the ability to return a read-write pointer. So + * there is no way to tell OS calls to write into a std::string directly -- a + * temporary malloc'ed string would be necessary --, which would be + * unnecessarily inefficient, specially considering that these strings would + * ultimately passed back to the OS, which would again expect zero-terminated + * strings. + * + * This class is not, however, a full replacement for std::string, which should + * be otherwise used whenever possible. */ class String { protected: @@ -312,6 +324,15 @@ public: buffer.erase(first, last); } + /** + * Get a writable buffer with the specified size. + * + * truncate() must be called after the buffer is written, and before any other + * method is called. + * + * Between the call to buf() and truncate() methods, the `buffer.back() == + * 0` invariant will not hold true. + */ char *buf(size_t size) { buffer.resize(size); return &buffer[0]; @@ -324,14 +345,21 @@ public: return size - 1; } + /** + * Truncate the string to the specified length. + */ void truncate(size_t length) { assert(length < buffer.size()); buffer[length] = 0; + assert(strlen(&buffer[0]) == length); buffer.resize(length + 1); } + /** + * Truncate the string to the first zero character. + */ void truncate(void) { - truncate(strlen(str())); + truncate(strlen(&buffer[0])); } -- 2.43.0