version.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
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 "base/logging.h"
8#include "base/string_number_conversions.h"
9#include "base/string_split.h"
10#include "base/string_util.h"
11#include "base/utf_string_conversions.h"
12
13// static
14Version* Version::GetVersionFromString(const std::wstring& version_str) {
15  if (!IsStringASCII(version_str))
16    return NULL;
17  return GetVersionFromString(WideToUTF8(version_str));
18}
19
20// static
21Version* Version::GetVersionFromString(const std::string& version_str) {
22  Version* vers = new Version();
23  if (vers->InitFromString(version_str)) {
24    DCHECK(vers->is_valid_);
25    return vers;
26  }
27  delete vers;
28  return NULL;
29}
30
31Version::Version() : is_valid_(false) {}
32
33bool Version::Equals(const Version& that) const {
34  DCHECK(is_valid_);
35  DCHECK(that.is_valid_);
36  return CompareTo(that) == 0;
37}
38
39int Version::CompareTo(const Version& other) const {
40  DCHECK(is_valid_);
41  DCHECK(other.is_valid_);
42  size_t count = std::min(components_.size(), other.components_.size());
43  for (size_t i = 0; i < count; ++i) {
44    if (components_[i] > other.components_[i])
45      return 1;
46    if (components_[i] < other.components_[i])
47      return -1;
48  }
49  if (components_.size() > other.components_.size()) {
50    for (size_t i = count; i < components_.size(); ++i)
51      if (components_[i] > 0)
52        return 1;
53  } else if (components_.size() < other.components_.size()) {
54    for (size_t i = count; i < other.components_.size(); ++i)
55      if (other.components_[i] > 0)
56        return -1;
57  }
58  return 0;
59}
60
61const std::string Version::GetString() const {
62  DCHECK(is_valid_);
63  std::string version_str;
64  int count = components_.size();
65  for (int i = 0; i < count - 1; ++i) {
66    version_str.append(base::IntToString(components_[i]));
67    version_str.append(".");
68  }
69  version_str.append(base::IntToString(components_[count - 1]));
70  return version_str;
71}
72
73bool Version::InitFromString(const std::string& version_str) {
74  DCHECK(!is_valid_);
75  std::vector<std::string> numbers;
76  SplitString(version_str, '.', &numbers);
77  if (numbers.empty())
78    return false;
79  for (std::vector<std::string>::iterator i = numbers.begin();
80       i != numbers.end(); ++i) {
81    int num;
82    if (!base::StringToInt(*i, &num))
83      return false;
84    if (num < 0)
85      return false;
86    const uint16 max = 0xFFFF;
87    if (num > max)
88      return false;
89    // This throws out things like +3, or 032.
90    if (base::IntToString(num) != *i)
91      return false;
92    uint16 component = static_cast<uint16>(num);
93    components_.push_back(component);
94  }
95  is_valid_ = true;
96  return true;
97}
98