EdB <edb+m...@sigluy.net> writes: > otherwise c_str() is not safe > --- > src/gallium/state_trackers/clover/util/compat.hpp | 54 > ++++++++++++++++++++--- > 1 file changed, 48 insertions(+), 6 deletions(-) > > diff --git a/src/gallium/state_trackers/clover/util/compat.hpp > b/src/gallium/state_trackers/clover/util/compat.hpp > index 6f0f7cc..7ca1f85 100644 > --- a/src/gallium/state_trackers/clover/util/compat.hpp > +++ b/src/gallium/state_trackers/clover/util/compat.hpp > @@ -197,7 +197,7 @@ namespace clover { > return _p[i]; > } > > - private: > + protected: > iterator _p; //memory array > size_type _s; //size > size_type _c; //capacity > @@ -306,18 +306,56 @@ namespace clover { > > class string : public vector<char> { > public: > - string() : vector() { > + string() : vector(0, 1) { > + _p[_s - 1] = '\0'; > } > > - string(const char *p) : vector(p, std::strlen(p)) { > + string(const char *p) : vector(p, std::strlen(p) + 1) { > + _p[_s - 1] = '\0'; > } > > template<typename C> > - string(const C &v) : vector(v) { > + string(const C &v) : vector(&*v.begin(), v.size() + 1) { > + _p[_s - 1] = '\0'; > } > > - operator std::string() const { > - return std::string(begin(), end()); > + void > + reserve(size_type m) { > + vector::reserve(m + 1); > + } > + > + void > + resize(size_type m, char x = '\0') { > + vector::resize(m + 1, x); > + _p[_s - 1] = '\0'; > + } > + > + void > + push_back(char &x) { > + reserve(_s + 1); > + _p[_s - 1] = x; > + _p[_s] = '\0'; > + ++_s; > + } > + > + size_type > + size() const { > + return _s - 1; > + } > + > + size_type > + capacity() const { > + return _c - 1; > + } > + > + iterator > + end() { > + return _p + size(); > + } > + > + const_iterator > + end() const { > + return _p + size(); > } >
At this point where all methods from the base class need to be redefined it probably stops making sense to use inheritance instead of aggregation. Once we've done that fixing c_str() gets a lot easier (two lines of code) because we can just declare the container as mutable and fix up the NULL terminator when c_str() is called. Both changes attached. > const char * > @@ -325,6 +363,10 @@ namespace clover { > return begin(); > } > > + operator std::string() const { > + return std::string(begin(), end()); > + } > + > const char * > find(const string &s) const { > for (size_t i = 0; i + s.size() < size(); ++i) { > -- > 2.0.4 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev
From e1e97e017f25f4ed1c75bae71095ffa116374654 Mon Sep 17 00:00:00 2001 From: Francisco Jerez <curroje...@riseup.net> Date: Mon, 18 Aug 2014 15:21:52 +0300 Subject: [PATCH 1/2] clover/util: Implement compat::string using aggregation instead of inheritance. --- src/gallium/state_trackers/clover/util/compat.hpp | 76 +++++++++++++++++++++-- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/src/gallium/state_trackers/clover/util/compat.hpp b/src/gallium/state_trackers/clover/util/compat.hpp index a4e3938..e0ab965 100644 --- a/src/gallium/state_trackers/clover/util/compat.hpp +++ b/src/gallium/state_trackers/clover/util/compat.hpp @@ -280,20 +280,83 @@ namespace clover { size_t offset; }; - class string : public vector<char> { + class string { public: - string() : vector() { + typedef char *iterator; + typedef const char *const_iterator; + typedef char value_type; + typedef char &reference; + typedef const char &const_reference; + typedef std::ptrdiff_t difference_type; + typedef std::size_t size_type; + + string() : v() { } - string(const char *p) : vector(p, std::strlen(p)) { + string(const char *p) : v(p, std::strlen(p)) { } template<typename C> - string(const C &v) : vector(v) { + string(const C &v) : v(v) { } operator std::string() const { - return std::string(begin(), end()); + return std::string(v.begin(), v.end()); + } + + void + reserve(size_type n) { + v.reserve(n); + } + + void + resize(size_type n, char x = char()) { + v.resize(n, x); + } + + void + push_back(char x) { + v.push_back(x); + } + + size_type + size() const { + return v.size(); + } + + size_type + capacity() const { + return v.capacity(); + } + + iterator + begin() { + return v.begin(); + } + + const_iterator + begin() const { + return v.begin(); + } + + iterator + end() { + return v.end(); + } + + const_iterator + end() const { + return v.end(); + } + + reference + operator[](size_type i) { + return v[i]; + } + + const_reference + operator[](size_type i) const { + return v[i]; } const char * @@ -310,6 +373,9 @@ namespace clover { return end(); } + + private: + mutable vector<char> v; }; template<typename T> -- 2.0.4
From 07e990c54df270e8dc632eb95338beb5b0aeebf3 Mon Sep 17 00:00:00 2001 From: Francisco Jerez <curroje...@riseup.net> Date: Mon, 18 Aug 2014 15:25:35 +0300 Subject: [PATCH 2/2] clover/util: Null-terminate the result of compat::string::c_str(). Reported-by: EdB <edb+m...@sigluy.net> --- src/gallium/state_trackers/clover/util/compat.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gallium/state_trackers/clover/util/compat.hpp b/src/gallium/state_trackers/clover/util/compat.hpp index e0ab965..7305577 100644 --- a/src/gallium/state_trackers/clover/util/compat.hpp +++ b/src/gallium/state_trackers/clover/util/compat.hpp @@ -361,7 +361,9 @@ namespace clover { const char * c_str() const { - return begin(); + v.reserve(size() + 1); + *v.end() = 0; + return v.begin(); } const char * -- 2.0.4
pgp7apTYGBBwq.pgp
Description: PGP signature
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev