diff options
-rw-r--r-- | base/base.xcodeproj/project.pbxproj | 10 | ||||
-rw-r--r-- | base/base_lib.scons | 2 | ||||
-rw-r--r-- | base/base_unittests.scons | 1 | ||||
-rw-r--r-- | base/build/base.vcproj | 8 | ||||
-rw-r--r-- | base/build/base_unittests.vcproj | 4 | ||||
-rw-r--r-- | base/version.cc | 83 | ||||
-rw-r--r-- | base/version.h | 44 | ||||
-rw-r--r-- | base/version_unittest.cc | 62 |
8 files changed, 214 insertions, 0 deletions
diff --git a/base/base.xcodeproj/project.pbxproj b/base/base.xcodeproj/project.pbxproj index 693a873..a5c5f7d 100644 --- a/base/base.xcodeproj/project.pbxproj +++ b/base/base.xcodeproj/project.pbxproj @@ -35,6 +35,7 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 095DBC1E2E0537F2ABE2F4C5 /* version.cc in Sources */ = {isa = PBXBuildFile; fileRef = 85BBBA65D48C3B2E0571518D /* version.cc */; }; 141593B80EA63EBE00E32418 /* thread_collision_warner_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 146C6A6E0EA63D970029E7B6 /* thread_collision_warner_unittest.cc */; }; 146C6A6B0EA63D4F0029E7B6 /* thread_collision_warner.cc in Sources */ = {isa = PBXBuildFile; fileRef = 146C6A620EA63CAE0029E7B6 /* thread_collision_warner.cc */; }; 232269C2037712E93DA5CC83 /* scoped_temp_dir.cc in Sources */ = {isa = PBXBuildFile; fileRef = 119C3753E442CB1E1212F584 /* scoped_temp_dir.cc */; }; @@ -196,6 +197,7 @@ E49357220E422A36008F8B09 /* timer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 825403850D92D2CF0006B936 /* timer.cc */; }; E4A133440E37A3C400110AA2 /* string_escape.cc in Sources */ = {isa = PBXBuildFile; fileRef = E4A133420E37A3C400110AA2 /* string_escape.cc */; }; E4CE9D7A0E8C1FD400D5378C /* system_monitor.cc in Sources */ = {isa = PBXBuildFile; fileRef = E4CE9D780E8C1FCA00D5378C /* system_monitor.cc */; }; + F330B11E050A9158CB16C98E /* version_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = A65E63ED95E431D2E73DF510 /* version_unittest.cc */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -618,6 +620,7 @@ 82E23FCB0D9C219600F8B40A /* platform_thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform_thread.h; sourceTree = "<group>"; }; 84B581950EDC6ECC00A6B5B3 /* test_file_util_mac.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_file_util_mac.cc; sourceTree = "<group>"; }; 84B5819B0EDC6FBC00A6B5B3 /* test_file_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = test_file_util.h; sourceTree = "<group>"; }; + 85BBBA65D48C3B2E0571518D /* version.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = version.cc; sourceTree = "<group>"; }; 9301C03A0E54C839001EF103 /* waitable_event_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = waitable_event_unittest.cc; sourceTree = "<group>"; }; 93611ADA0E5A7FC500F9405D /* message_loop_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = message_loop_unittest.cc; sourceTree = "<group>"; }; 93611ADB0E5A7FC500F9405D /* message_pump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = message_pump.h; sourceTree = "<group>"; }; @@ -638,6 +641,7 @@ A5A0270A0E4A630D00498DA9 /* file_util_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = file_util_mac.mm; sourceTree = "<group>"; }; A5A0276B0E4BA33700498DA9 /* build_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = build_config.h; path = ../build/build_config.h; sourceTree = SOURCE_ROOT; }; A5A0282D0E4CFA8500498DA9 /* file_util_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_util_unittest.cc; sourceTree = "<group>"; }; + A65E63ED95E431D2E73DF510 /* version_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = version_unittest.cc; sourceTree = "<group>"; }; AB14B6060EBFA74C00FB3807 /* time_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = time_posix.cc; sourceTree = "<group>"; }; AB4FA1390F2A101100D6572F /* event_recorder_stubs.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = event_recorder_stubs.cc; sourceTree = "<group>"; }; ABE1BA290E7574D1009041DA /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<group>"; }; @@ -647,6 +651,7 @@ ABF68B260EB0F93100E72835 /* field_trial_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = field_trial_unittest.cc; sourceTree = "<group>"; }; ABF68B270EB0F93100E72835 /* field_trial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = field_trial.h; sourceTree = "<group>"; }; ABF68B280EB0F93100E72835 /* field_trial.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = field_trial.cc; sourceTree = "<group>"; }; + AE11B49026857EAED66B50E5 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; }; B290BFCBD30E45A63758BFC7 /* waitable_event_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = waitable_event_posix.cc; sourceTree = "<group>"; }; B52C916B0E9428F500208D01 /* clipboard_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = clipboard_unittest.cc; sourceTree = "<group>"; }; B57D788E0F26983200685566 /* scoped_file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scoped_file.h; sourceTree = "<group>"; }; @@ -1098,6 +1103,9 @@ 825403880D92D2CF0006B936 /* values.cc */, 825403890D92D2CF0006B936 /* values.h */, E49E4C980E4CF60300AD47F7 /* values_unittest.cc */, + 85BBBA65D48C3B2E0571518D /* version.cc */, + AE11B49026857EAED66B50E5 /* version.h */, + A65E63ED95E431D2E73DF510 /* version_unittest.cc */, 7BD8F4D10E65B54B00034DE9 /* waitable_event.h */, B290BFCBD30E45A63758BFC7 /* waitable_event_posix.cc */, 9301C03A0E54C839001EF103 /* waitable_event_unittest.cc */, @@ -1487,6 +1495,7 @@ 820EB5020E3A618B009668FC /* tracked.cc in Sources */, 820EB5480E3A64D2009668FC /* tracked_objects.cc in Sources */, ABF4B9C30DC2BD6C00A6E319 /* values.cc in Sources */, + 095DBC1E2E0537F2ABE2F4C5 /* version.cc in Sources */, 9F96D18073B23E12802A3225 /* waitable_event_posix.cc in Sources */, B12E82CF65E36A34852F4B08 /* waitable_event_watcher_posix.cc in Sources */, 4D4C5B5B0EF1B7AE002CA805 /* watchdog.cc in Sources */, @@ -1563,6 +1572,7 @@ BA739A020E5E3242009842A7 /* tracked_objects_unittest.cc in Sources */, 7BD8F4D30E65B55000034DE9 /* tuple_unittest.cc in Sources */, 7B78D3A30E54FE0100609465 /* values_unittest.cc in Sources */, + F330B11E050A9158CB16C98E /* version_unittest.cc in Sources */, 7B78D3A40E54FE0100609465 /* waitable_event_unittest.cc in Sources */, 4D4C5B5E0EF1B7C1002CA805 /* watchdog_unittest.cc in Sources */, 7B78D3A50E54FE0100609465 /* word_iterator_unittest.cc in Sources */, diff --git a/base/base_lib.scons b/base/base_lib.scons index 02467e3..afb82ea 100644 --- a/base/base_lib.scons +++ b/base/base_lib.scons @@ -250,6 +250,8 @@ input_files = ChromeFileList([ 'tuple.h', 'values.cc', 'values.h', + 'version.cc', + 'version.h', 'waitable_event.h', 'waitable_event_watcher.h', 'waitable_event_watcher_win.cc', diff --git a/base/base_unittests.scons b/base/base_unittests.scons index 48eaef8..9b2941a 100644 --- a/base/base_unittests.scons +++ b/base/base_unittests.scons @@ -112,6 +112,7 @@ input_files = ChromeFileList([ 'tracked_objects_unittest.cc', 'tuple_unittest.cc', 'values_unittest.cc', + 'version_unittest.cc', 'waitable_event_unittest.cc', 'waitable_event_watcher_unittest.cc', 'watchdog_unittest.cc', diff --git a/base/build/base.vcproj b/base/build/base.vcproj index ae9ba94..feaeae3 100644 --- a/base/build/base.vcproj +++ b/base/build/base.vcproj @@ -966,6 +966,14 @@ > </File> <File + RelativePath="..\version.cc" + > + </File> + <File + RelativePath="..\version.h" + > + </File> + <File RelativePath="..\waitable_event.h" > </File> diff --git a/base/build/base_unittests.vcproj b/base/build/base_unittests.vcproj index 7d80df8..466ebd2 100644 --- a/base/build/base_unittests.vcproj +++ b/base/build/base_unittests.vcproj @@ -392,6 +392,10 @@ > </File> <File + RelativePath="..\version_unittest.cc" + > + </File> + <File RelativePath="..\waitable_event_unittest.cc" > </File> diff --git a/base/version.cc b/base/version.cc new file mode 100644 index 0000000..1fe5cb4 --- /dev/null +++ b/base/version.cc @@ -0,0 +1,83 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <vector> + +#include "base/string_util.h" +#include "base/version.h" + +// static +Version* Version::GetVersionFromString(const std::wstring& version_str) { + if (!IsStringASCII(version_str)) + return NULL; + return GetVersionFromString(WideToASCII(version_str)); +} + +// static +Version* Version::GetVersionFromString(const std::string& version_str) { + Version* vers = new Version(); + if (vers->InitFromString(version_str)) + return vers; + delete vers; + return NULL; +} + +bool Version::Equals(const Version& that) const { + return CompareTo(that) == 0; +} + +int Version::CompareTo(const Version& other) const { + std::vector<uint16> other_components = other.components(); + size_t count = std::min(components_.size(), other_components.size()); + for (size_t i = 0; i < count; ++i) { + if (components_[i] > other_components[i]) + return 1; + if (components_[i] < other_components[i]) + return -1; + } + if (components_.size() > other_components.size()) { + for (size_t i = count; i < components_.size(); ++i) + if (components_[i] > 0) + return 1; + } else if (components_.size() < other_components.size()) { + for (size_t i = count; i < other_components.size(); ++i) + if (other_components[i] > 0) + return -1; + } + return 0; +} + +const std::string Version::GetString() const { + std::string version_str; + int count = components_.size(); + for (int i = 0; i < count - 1; ++i) { + version_str.append(IntToString(components_[i])); + version_str.append("."); + } + version_str.append(IntToString(components_[count - 1])); + return version_str; +} + +bool Version::InitFromString(const std::string& version_str) { + std::vector<std::string> numbers; + SplitString(version_str, '.', &numbers); + for (std::vector<std::string>::iterator i = numbers.begin(); + i != numbers.end(); ++i) { + int num; + if (!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 (IntToString(num) != *i) + return false; + uint16 component = static_cast<uint16>(num); + components_.push_back(component); + } + return true; +} + diff --git a/base/version.h b/base/version.h new file mode 100644 index 0000000..6e12bb7 --- /dev/null +++ b/base/version.h @@ -0,0 +1,44 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_VERSION_H_ +#define BASE_VERSION_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" + +class Version { +public: + + // The version string must be made up of 1 or more uint16's separated + // by '.'. Returns NULL if string is not in this format. + // Caller is responsible for freeing the Version object once done. + static Version* GetVersionFromString(const std::wstring& version_str); + static Version* GetVersionFromString(const std::string& version_str); + + ~Version() {} + + bool Equals(const Version& other) const; + + // Returns -1, 0, 1 for <, ==, >. + int CompareTo(const Version& other) const; + + // Return the string representation of this version. + const std::string GetString() const; + + const std::vector<uint16>& components() const { return components_; } + +private: + Version() {} + bool InitFromString(const std::string& version_str); + + std::vector<uint16> components_; + + DISALLOW_COPY_AND_ASSIGN(Version); +}; + +#endif // BASE_VERSION_H_ + diff --git a/base/version_unittest.cc b/base/version_unittest.cc new file mode 100644 index 0000000..d2cf98b --- /dev/null +++ b/base/version_unittest.cc @@ -0,0 +1,62 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/scoped_ptr.h" +#include "base/version.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +TEST(Version, GetVersionFromString) { + static const struct version_string { + const char* input; + size_t parts; + bool success; + } cases[] = { + {"0", 1, true}, + {"0.0", 2, true}, + {"65537.0", 0, false}, + {"-1.0", 0, false}, + {"1.-1.0", 0, false}, + {"+1.0", 0, false}, + {"1.+1.0", 0, false}, + {"1.0a", 0, false}, + {"1.2.3.4.5.6.7.8.9.0", 10, true}, + {"02.1", 0, false}, + {"f.1", 0, false}, + }; + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { + scoped_ptr<Version> vers(Version::GetVersionFromString(cases[i].input)); + EXPECT_EQ(cases[i].success, vers.get() != NULL); + if (cases[i].success) + EXPECT_EQ(cases[i].parts, vers->components().size()); + } +} + +TEST(Version, Compare) { + static const struct version_compare { + const char* lhs; + const char* rhs; + int expected; + } cases[] = { + {"1.0", "1.0", 0}, + {"1.0", "0.0", 1}, + {"1.0", "2.0", -1}, + {"1.0", "1.1", -1}, + {"1.1", "1.0", 1}, + {"1.0", "1.0.1", -1}, + {"1.1", "1.0.1", 1}, + {"1.1", "1.0.1", 1}, + {"1.0.0", "1.0", 0}, + {"1.0.3", "1.0.20", -1}, + }; + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { + scoped_ptr<Version> lhs(Version::GetVersionFromString(cases[i].lhs)); + scoped_ptr<Version> rhs(Version::GetVersionFromString(cases[i].rhs)); + EXPECT_EQ(lhs->CompareTo(*rhs), cases[i].expected) << + cases[i].lhs << " ? " << cases[i].rhs; + } +} + +} |