diff options
author | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-07 17:21:30 +0000 |
---|---|---|
committer | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-07 17:21:30 +0000 |
commit | 76002478cf1d6ddf9677401f73198fb7a564fdf7 (patch) | |
tree | 7782f6b6b2e7b06bb7f66da7081790b3fc019675 /base | |
parent | 0985614e49db6b4a94c551fda1107462b53a9aac (diff) | |
download | chromium_src-76002478cf1d6ddf9677401f73198fb7a564fdf7.zip chromium_src-76002478cf1d6ddf9677401f73198fb7a564fdf7.tar.gz chromium_src-76002478cf1d6ddf9677401f73198fb7a564fdf7.tar.bz2 |
Clean up base/Version
It turns out base/Version is really a value object but probably because of some serious accident or by
the machinations of a super villain, forgot his identity and now it thinks is a reference object,
only creatable in the heap and that could only spawn offsprings via cloning.
But fear not 'cause I've seen Version true nature; At its core is just a good 'ol vector<uint16>, which has
very respectable value semantics. Also I have removed the is_valid_ parasite as much as I could.
The old interface (GetVersionFromString and Clone) is kept so existing callers would not need to be modified.
BUG=none
TEST=included
Review URL: http://codereview.chromium.org/7105008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@88143 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/version.cc | 85 | ||||
-rw-r--r-- | base/version.h | 28 | ||||
-rw-r--r-- | base/version_unittest.cc | 18 |
3 files changed, 70 insertions, 61 deletions
diff --git a/base/version.cc b/base/version.cc index 571672c..74c570c 100644 --- a/base/version.cc +++ b/base/version.cc @@ -10,40 +10,63 @@ #include "base/string_number_conversions.h" #include "base/string_split.h" #include "base/string_util.h" -#include "base/utf_string_conversions.h" -Version::Version() : is_valid_(false) {} +Version::Version() { +} + +Version::Version(const std::string& version_str) { + std::vector<std::string> numbers; + base::SplitString(version_str, '.', &numbers); + if (numbers.empty()) + return; + std::vector<uint16> parsed; + for (std::vector<std::string>::iterator i = numbers.begin(); + i != numbers.end(); ++i) { + int num; + if (!base::StringToInt(*i, &num)) + return; + if (num < 0) + return; + const uint16 max = 0xFFFF; + if (num > max) + return; + // This throws out things like +3, or 032. + if (base::IntToString(num) != *i) + return; + parsed.push_back(static_cast<uint16>(num)); + } + components_.swap(parsed); +} -Version::~Version() {} +bool Version::IsValid() const { + return (!components_.empty()); +} -// static +// TODO(cpu): remove this method. Version* Version::GetVersionFromString(const std::string& version_str) { - Version* vers = new Version(); - if (vers->InitFromString(version_str)) { - DCHECK(vers->is_valid_); + Version* vers = new Version(version_str); + if (vers->IsValid()) { return vers; } delete vers; return NULL; } +// TODO(cpu): remove this method. Version* Version::Clone() const { - DCHECK(is_valid_); - Version* copy = new Version(); - copy->components_ = components_; - copy->is_valid_ = true; - return copy; + DCHECK(IsValid()); + return new Version(*this); } bool Version::Equals(const Version& that) const { - DCHECK(is_valid_); - DCHECK(that.is_valid_); - return CompareTo(that) == 0; + DCHECK(IsValid()); + DCHECK(that.IsValid()); + return (CompareTo(that) == 0); } int Version::CompareTo(const Version& other) const { - DCHECK(is_valid_); - DCHECK(other.is_valid_); + DCHECK(IsValid()); + DCHECK(other.IsValid()); size_t count = std::min(components_.size(), other.components_.size()); for (size_t i = 0; i < count; ++i) { if (components_[i] > other.components_[i]) @@ -64,7 +87,7 @@ int Version::CompareTo(const Version& other) const { } const std::string Version::GetString() const { - DCHECK(is_valid_); + DCHECK(IsValid()); std::string version_str; size_t count = components_.size(); for (size_t i = 0; i < count - 1; ++i) { @@ -74,29 +97,3 @@ const std::string Version::GetString() const { version_str.append(base::IntToString(components_[count - 1])); return version_str; } - -bool Version::InitFromString(const std::string& version_str) { - DCHECK(!is_valid_); - std::vector<std::string> numbers; - base::SplitString(version_str, '.', &numbers); - if (numbers.empty()) - return false; - for (std::vector<std::string>::iterator i = numbers.begin(); - i != numbers.end(); ++i) { - int num; - if (!base::StringToInt(*i, &num)) - return false; - if (num < 0) - return false; - const uint16 max = 0xFFFF; - if (num > max) - return false; - // This throws out things like +3, or 032. - if (base::IntToString(num) != *i) - return false; - uint16 component = static_cast<uint16>(num); - components_.push_back(component); - } - is_valid_ = true; - return true; -} diff --git a/base/version.h b/base/version.h index d256d06..7dcefb3 100644 --- a/base/version.h +++ b/base/version.h @@ -15,22 +15,27 @@ // Version represents a dotted version number, like "1.2.3.4", supporting // parsing and comparison. -// Each component is limited to a uint16. class BASE_API Version { public: - // Exposed only so that a Version can be stored in STL containers; - // any call to the methods below on a default-constructed Version - // will DCHECK. + // The only thing you can legally do to a default constructed + // Version object is assign to it. Version(); - ~Version(); + // Initializes from a decimal dotted version number, like "0.1.1". + // Each component is limited to a uint16. Call IsValid() to learn + // the outcome. + explicit Version(const std::string& version_str); - // The version string must be made up of 1 or more uint16's separated - // by '.'. Returns NULL if string is not in this format. + // Returns true if the object contains a valid version number. + bool IsValid() const; + + // Returns NULL if the string is not in the proper format. // Caller is responsible for freeing the Version object once done. + // DO NOT USE FOR NEWER CODE. static Version* GetVersionFromString(const std::string& version_str); - // Creates a copy of this version. Caller takes ownership. + // Creates a copy of this version object. Caller takes ownership. + // DO NOT USE FOR NEWER CODE. Version* Clone() const; bool Equals(const Version& other) const; @@ -44,14 +49,7 @@ class BASE_API Version { const std::vector<uint16>& components() const { return components_; } private: - bool InitFromString(const std::string& version_str); - - bool is_valid_; std::vector<uint16> components_; - - FRIEND_TEST_ALL_PREFIXES(VersionTest, DefaultConstructor); - FRIEND_TEST_ALL_PREFIXES(VersionTest, GetVersionFromString); - FRIEND_TEST_ALL_PREFIXES(VersionTest, Compare); }; #endif // BASE_VERSION_H_ diff --git a/base/version_unittest.cc b/base/version_unittest.cc index 486ef7d..a3b1ac6 100644 --- a/base/version_unittest.cc +++ b/base/version_unittest.cc @@ -11,7 +11,21 @@ class VersionTest : public testing::Test { TEST_F(VersionTest, DefaultConstructor) { Version v; - EXPECT_FALSE(v.is_valid_); + EXPECT_FALSE(v.IsValid()); +} + +TEST_F(VersionTest, ValueSemantics) { + Version v1("1.2.3.4"); + EXPECT_TRUE(v1.IsValid()); + Version v3; + EXPECT_FALSE(v3.IsValid()); + { + Version v2(v1); + v3 = v2; + EXPECT_TRUE(v2.IsValid()); + EXPECT_TRUE(v1.Equals(v2)); + } + EXPECT_TRUE(v3.Equals(v1)); } TEST_F(VersionTest, GetVersionFromString) { @@ -43,7 +57,7 @@ TEST_F(VersionTest, GetVersionFromString) { scoped_ptr<Version> vers(Version::GetVersionFromString(cases[i].input)); EXPECT_EQ(cases[i].success, vers.get() != NULL); if (cases[i].success) { - EXPECT_TRUE(vers->is_valid_); + EXPECT_TRUE(vers->IsValid()); EXPECT_EQ(cases[i].parts, vers->components().size()); } } |