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 3 // found in the LICENSE file. 4 5 #include "base/version.h" 6 7 #include <algorithm> 8 9 #include "base/logging.h" 10 #include "base/string_number_conversions.h" 11 #include "base/string_split.h" 12 #include "base/string_util.h" 13 #include "base/utf_string_conversions.h" 14 15 Version::Version() : is_valid_(false) {} 16 17 Version::~Version() {} 18 19 // static 20 Version* Version::GetVersionFromString(const std::string& version_str) { 21 Version* vers = new Version(); 22 if (vers->InitFromString(version_str)) { 23 DCHECK(vers->is_valid_); 24 return vers; 25 } 26 delete vers; 27 return NULL; 28 } 29 30 Version* Version::Clone() const { 31 DCHECK(is_valid_); 32 Version* copy = new Version(); 33 copy->components_ = components_; 34 copy->is_valid_ = true; 35 return copy; 36 } 37 38 bool Version::Equals(const Version& that) const { 39 DCHECK(is_valid_); 40 DCHECK(that.is_valid_); 41 return CompareTo(that) == 0; 42 } 43 44 int Version::CompareTo(const Version& other) const { 45 DCHECK(is_valid_); 46 DCHECK(other.is_valid_); 47 size_t count = std::min(components_.size(), other.components_.size()); 48 for (size_t i = 0; i < count; ++i) { 49 if (components_[i] > other.components_[i]) 50 return 1; 51 if (components_[i] < other.components_[i]) 52 return -1; 53 } 54 if (components_.size() > other.components_.size()) { 55 for (size_t i = count; i < components_.size(); ++i) 56 if (components_[i] > 0) 57 return 1; 58 } else if (components_.size() < other.components_.size()) { 59 for (size_t i = count; i < other.components_.size(); ++i) 60 if (other.components_[i] > 0) 61 return -1; 62 } 63 return 0; 64 } 65 66 const std::string Version::GetString() const { 67 DCHECK(is_valid_); 68 std::string version_str; 69 size_t count = components_.size(); 70 for (size_t i = 0; i < count - 1; ++i) { 71 version_str.append(base::IntToString(components_[i])); 72 version_str.append("."); 73 } 74 version_str.append(base::IntToString(components_[count - 1])); 75 return version_str; 76 } 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 } 103