Home | History | Annotate | Download | only in base
      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