summaryrefslogtreecommitdiff
path: root/xpcom/glue/nsVersionComparator.h
blob: 0dbf8532b0b6645d41f99926e3393c2a1abb9779 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef nsVersionComparator_h__
#define nsVersionComparator_h__

#include "nscore.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#if defined(XP_WIN) && !defined(UPDATER_NO_STRING_GLUE_STL)
#include <wchar.h>
#include "nsStringGlue.h"
#endif

/**
 * In order to compare version numbers in Mozilla, you need to use the
 * mozilla::Version class.  You can construct an object of this type by passing
 * in a string version number to the constructor.  Objects of this type can be
 * compared using the standard comparison operators.
 *
 * For example, let's say that you want to make sure that a given version
 * number is not older than 15.a2.  Here's how you would write a function to
 * do that.
 *
 * bool IsVersionValid(const char* version) {
 *   return mozilla::Version("15.a2") <= mozilla::Version(version);
 * }
 *
 * Or, since Version's constructor is implicit, you can simplify this code:
 *
 * bool IsVersionValid(const char* version) {
 *   return mozilla::Version("15.a2") <= version;
 * }
 *
 * On Windows, if your version strings are wide characters, you should use the
 * mozilla::VersionW variant instead.  The semantics of that class is the same
 * as Version.
 */

namespace mozilla {

int32_t CompareVersions(const char* aStrA, const char* aStrB);

#ifdef XP_WIN
int32_t CompareVersions(const char16_t* aStrA, const char16_t* aStrB);
#endif

struct Version
{
  explicit Version(const char* aVersionString)
  {
    versionContent = strdup(aVersionString);
  }

  const char* ReadContent() const
  {
    return versionContent;
  }

  ~Version()
  {
    free(versionContent);
  }

  bool operator<(const Version& aRhs) const
  {
    return CompareVersions(versionContent, aRhs.ReadContent()) == -1;
  }
  bool operator<=(const Version& aRhs) const
  {
    return CompareVersions(versionContent, aRhs.ReadContent()) < 1;
  }
  bool operator>(const Version& aRhs) const
  {
    return CompareVersions(versionContent, aRhs.ReadContent()) == 1;
  }
  bool operator>=(const Version& aRhs) const
  {
    return CompareVersions(versionContent, aRhs.ReadContent()) > -1;
  }
  bool operator==(const Version& aRhs) const
  {
    return CompareVersions(versionContent, aRhs.ReadContent()) == 0;
  }
  bool operator!=(const Version& aRhs) const
  {
    return CompareVersions(versionContent, aRhs.ReadContent()) != 0;
  }
  bool operator<(const char* aRhs) const
  {
    return CompareVersions(versionContent, aRhs) == -1;
  }
  bool operator<=(const char* aRhs) const
  {
    return CompareVersions(versionContent, aRhs) < 1;
  }
  bool operator>(const char* aRhs) const
  {
    return CompareVersions(versionContent, aRhs) == 1;
  }
  bool operator>=(const char* aRhs) const
  {
    return CompareVersions(versionContent, aRhs) > -1;
  }
  bool operator==(const char* aRhs) const
  {
    return CompareVersions(versionContent, aRhs) == 0;
  }
  bool operator!=(const char* aRhs) const
  {
    return CompareVersions(versionContent, aRhs) != 0;
  }

private:
  char* versionContent;
};

#ifdef XP_WIN
struct VersionW
{
  VersionW(const char16_t* aVersionStringW)
  {
    versionContentW =
      reinterpret_cast<char16_t*>(wcsdup(char16ptr_t(aVersionStringW)));
  }

  const char16_t* ReadContentW() const
  {
    return versionContentW;
  }

  ~VersionW()
  {
    free(versionContentW);
  }

  bool operator<(const VersionW& aRhs) const
  {
    return CompareVersions(versionContentW, aRhs.ReadContentW()) == -1;
  }
  bool operator<=(const VersionW& aRhs) const
  {
    return CompareVersions(versionContentW, aRhs.ReadContentW()) < 1;
  }
  bool operator>(const VersionW& aRhs) const
  {
    return CompareVersions(versionContentW, aRhs.ReadContentW()) == 1;
  }
  bool operator>=(const VersionW& aRhs) const
  {
    return CompareVersions(versionContentW, aRhs.ReadContentW()) > -1;
  }
  bool operator==(const VersionW& aRhs) const
  {
    return CompareVersions(versionContentW, aRhs.ReadContentW()) == 0;
  }
  bool operator!=(const VersionW& aRhs) const
  {
    return CompareVersions(versionContentW, aRhs.ReadContentW()) != 0;
  }

private:
  char16_t* versionContentW;
};
#endif

} // namespace mozilla

#endif // nsVersionComparator_h__