OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/version.h" | 5 #include "base/version.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
11 #include "base/string_split.h" | 11 #include "base/string_split.h" |
12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
13 #include "base/utf_string_conversions.h" | |
14 | 13 |
15 Version::Version() : is_valid_(false) {} | 14 Version::Version() { |
| 15 } |
16 | 16 |
17 Version::~Version() {} | 17 Version::Version(const std::string& version_str) { |
| 18 std::vector<std::string> numbers; |
| 19 base::SplitString(version_str, '.', &numbers); |
| 20 if (numbers.empty()) |
| 21 return; |
| 22 std::vector<uint16> parsed; |
| 23 for (std::vector<std::string>::iterator i = numbers.begin(); |
| 24 i != numbers.end(); ++i) { |
| 25 int num; |
| 26 if (!base::StringToInt(*i, &num)) |
| 27 return; |
| 28 if (num < 0) |
| 29 return; |
| 30 const uint16 max = 0xFFFF; |
| 31 if (num > max) |
| 32 return; |
| 33 // This throws out things like +3, or 032. |
| 34 if (base::IntToString(num) != *i) |
| 35 return; |
| 36 parsed.push_back(static_cast<uint16>(num)); |
| 37 } |
| 38 components_.swap(parsed); |
| 39 } |
18 | 40 |
19 // static | 41 bool Version::IsValid() const { |
| 42 return (!components_.empty()); |
| 43 } |
| 44 |
| 45 // TODO(cpu): remove this method. |
20 Version* Version::GetVersionFromString(const std::string& version_str) { | 46 Version* Version::GetVersionFromString(const std::string& version_str) { |
21 Version* vers = new Version(); | 47 Version* vers = new Version(version_str); |
22 if (vers->InitFromString(version_str)) { | 48 if (vers->IsValid()) { |
23 DCHECK(vers->is_valid_); | |
24 return vers; | 49 return vers; |
25 } | 50 } |
26 delete vers; | 51 delete vers; |
27 return NULL; | 52 return NULL; |
28 } | 53 } |
29 | 54 |
| 55 // TODO(cpu): remove this method. |
30 Version* Version::Clone() const { | 56 Version* Version::Clone() const { |
31 DCHECK(is_valid_); | 57 DCHECK(IsValid()); |
32 Version* copy = new Version(); | 58 return new Version(*this); |
33 copy->components_ = components_; | |
34 copy->is_valid_ = true; | |
35 return copy; | |
36 } | 59 } |
37 | 60 |
38 bool Version::Equals(const Version& that) const { | 61 bool Version::Equals(const Version& that) const { |
39 DCHECK(is_valid_); | 62 DCHECK(IsValid()); |
40 DCHECK(that.is_valid_); | 63 DCHECK(that.IsValid()); |
41 return CompareTo(that) == 0; | 64 return (CompareTo(that) == 0); |
42 } | 65 } |
43 | 66 |
44 int Version::CompareTo(const Version& other) const { | 67 int Version::CompareTo(const Version& other) const { |
45 DCHECK(is_valid_); | 68 DCHECK(IsValid()); |
46 DCHECK(other.is_valid_); | 69 DCHECK(other.IsValid()); |
47 size_t count = std::min(components_.size(), other.components_.size()); | 70 size_t count = std::min(components_.size(), other.components_.size()); |
48 for (size_t i = 0; i < count; ++i) { | 71 for (size_t i = 0; i < count; ++i) { |
49 if (components_[i] > other.components_[i]) | 72 if (components_[i] > other.components_[i]) |
50 return 1; | 73 return 1; |
51 if (components_[i] < other.components_[i]) | 74 if (components_[i] < other.components_[i]) |
52 return -1; | 75 return -1; |
53 } | 76 } |
54 if (components_.size() > other.components_.size()) { | 77 if (components_.size() > other.components_.size()) { |
55 for (size_t i = count; i < components_.size(); ++i) | 78 for (size_t i = count; i < components_.size(); ++i) |
56 if (components_[i] > 0) | 79 if (components_[i] > 0) |
57 return 1; | 80 return 1; |
58 } else if (components_.size() < other.components_.size()) { | 81 } else if (components_.size() < other.components_.size()) { |
59 for (size_t i = count; i < other.components_.size(); ++i) | 82 for (size_t i = count; i < other.components_.size(); ++i) |
60 if (other.components_[i] > 0) | 83 if (other.components_[i] > 0) |
61 return -1; | 84 return -1; |
62 } | 85 } |
63 return 0; | 86 return 0; |
64 } | 87 } |
65 | 88 |
66 const std::string Version::GetString() const { | 89 const std::string Version::GetString() const { |
67 DCHECK(is_valid_); | 90 DCHECK(IsValid()); |
68 std::string version_str; | 91 std::string version_str; |
69 size_t count = components_.size(); | 92 size_t count = components_.size(); |
70 for (size_t i = 0; i < count - 1; ++i) { | 93 for (size_t i = 0; i < count - 1; ++i) { |
71 version_str.append(base::IntToString(components_[i])); | 94 version_str.append(base::IntToString(components_[i])); |
72 version_str.append("."); | 95 version_str.append("."); |
73 } | 96 } |
74 version_str.append(base::IntToString(components_[count - 1])); | 97 version_str.append(base::IntToString(components_[count - 1])); |
75 return version_str; | 98 return version_str; |
76 } | 99 } |
77 | |
78 bool Version::InitFromString(const std::string& version_str) { | |
79 DCHECK(!is_valid_); | |
80 std::vector<std::string> numbers; | |
81 base::SplitString(version_str, '.', &numbers); | |
82 if (numbers.empty()) | |
83 return false; | |
84 for (std::vector<std::string>::iterator i = numbers.begin(); | |
85 i != numbers.end(); ++i) { | |
86 int num; | |
87 if (!base::StringToInt(*i, &num)) | |
88 return false; | |
89 if (num < 0) | |
90 return false; | |
91 const uint16 max = 0xFFFF; | |
92 if (num > max) | |
93 return false; | |
94 // This throws out things like +3, or 032. | |
95 if (base::IntToString(num) != *i) | |
96 return false; | |
97 uint16 component = static_cast<uint16>(num); | |
98 components_.push_back(component); | |
99 } | |
100 is_valid_ = true; | |
101 return true; | |
102 } | |
OLD | NEW |