version.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
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
33Version::~Version() {}
34
35bool Version::Equals(const Version& that) const {
36  DCHECK(is_valid_);
37  DCHECK(that.is_valid_);
38  return CompareTo(that) == 0;
39}
40
41int Version::CompareTo(const Version& other) const {
42  DCHECK(is_valid_);
43  DCHECK(other.is_valid_);
44  size_t count = std::min(components_.size(), other.components_.size());
45  for (size_t i = 0; i < count; ++i) {
46    if (components_[i] > other.components_[i])
47      return 1;
48    if (components_[i] < other.components_[i])
49      return -1;
50  }
51  if (components_.size() > other.components_.size()) {
52    for (size_t i = count; i < components_.size(); ++i)
53      if (components_[i] > 0)
54        return 1;
55  } else if (components_.size() < other.components_.size()) {
56    for (size_t i = count; i < other.components_.size(); ++i)
57      if (other.components_[i] > 0)
58        return -1;
59  }
60  return 0;
61}
62
63const std::string Version::GetString() const {
64  DCHECK(is_valid_);
65  std::string version_str;
66  int count = components_.size();
67  for (int i = 0; i < count - 1; ++i) {
68    version_str.append(base::IntToString(components_[i]));
69    version_str.append(".");
70  }
71  version_str.append(base::IntToString(components_[count - 1]));
72  return version_str;
73}
74
75bool Version::InitFromString(const std::string& version_str) {
76  DCHECK(!is_valid_);
77  std::vector<std::string> numbers;
78  base::SplitString(version_str, '.', &numbers);
79  if (numbers.empty())
80    return false;
81  for (std::vector<std::string>::iterator i = numbers.begin();
82       i != numbers.end(); ++i) {
83    int num;
84    if (!base::StringToInt(*i, &num))
85      return false;
86    if (num < 0)
87      return false;
88    const uint16 max = 0xFFFF;
89    if (num > max)
90      return false;
91    // This throws out things like +3, or 032.
92    if (base::IntToString(num) != *i)
93      return false;
94    uint16 component = static_cast<uint16>(num);
95    components_.push_back(component);
96  }
97  is_valid_ = true;
98  return true;
99}
100