1/*
2 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include <package/PackageVersion.h>
8
9#include <NaturalCompare.h>
10
11#include <package/PackageInfo.h>
12#include <package/hpkg/PackageInfoAttributeValue.h>
13
14
15using BPrivate::NaturalCompare;
16
17
18namespace BPackageKit {
19
20
21BPackageVersion::BPackageVersion()
22	:
23	fRevision(0)
24{
25}
26
27
28BPackageVersion::BPackageVersion(const BPackageVersionData& data)
29{
30	SetTo(data.major, data.minor, data.micro, data.preRelease, data.revision);
31}
32
33
34BPackageVersion::BPackageVersion(const BString& versionString,
35	bool revisionIsOptional)
36{
37	SetTo(versionString, revisionIsOptional);
38}
39
40
41BPackageVersion::BPackageVersion(const BString& major, const BString& minor,
42	const BString& micro, const BString& preRelease, uint32 revision)
43{
44	SetTo(major, minor, micro, preRelease, revision);
45}
46
47
48status_t
49BPackageVersion::InitCheck() const
50{
51	return fMajor.Length() > 0 ? B_OK : B_NO_INIT;
52}
53
54
55const BString&
56BPackageVersion::Major() const
57{
58	return fMajor;
59}
60
61
62const BString&
63BPackageVersion::Minor() const
64{
65	return fMinor;
66}
67
68
69const BString&
70BPackageVersion::Micro() const
71{
72	return fMicro;
73}
74
75
76const BString&
77BPackageVersion::PreRelease() const
78{
79	return fPreRelease;
80}
81
82
83uint32
84BPackageVersion::Revision() const
85{
86	return fRevision;
87}
88
89
90int
91BPackageVersion::Compare(const BPackageVersion& other) const
92{
93	int diff = NaturalCompare(fMajor.String(), other.fMajor.String());
94	if (diff != 0)
95		return diff;
96
97	diff = NaturalCompare(fMinor.String(), other.fMinor.String());
98	if (diff != 0)
99		return diff;
100
101	diff = NaturalCompare(fMicro.String(), other.fMicro.String());
102	if (diff != 0)
103		return diff;
104
105	// The pre-version works differently: The empty string is greater than any
106	// non-empty string (e.g. "R1" is newer than "R1-rc2"). So we catch the
107	// empty string cases first.
108	if (fPreRelease.IsEmpty()) {
109		if (!other.fPreRelease.IsEmpty())
110			return 1;
111	} else if (other.fPreRelease.IsEmpty()) {
112		return -1;
113	} else {
114		// both are non-null -- compare normally
115		diff = NaturalCompare(fPreRelease.String(), other.fPreRelease.String());
116		if (diff != 0)
117			return diff;
118	}
119
120	return (int)fRevision - (int)other.fRevision;
121}
122
123
124BString
125BPackageVersion::ToString() const
126{
127	if (InitCheck() != B_OK)
128		return BString();
129
130	BString string = fMajor;
131
132	if (fMinor.Length() > 0) {
133		string << '.' << fMinor;
134		if (fMicro.Length() > 0)
135			string << '.' << fMicro;
136	}
137
138	if (!fPreRelease.IsEmpty())
139		string << '~' << fPreRelease;
140
141	if (fRevision > 0)
142		string << '-' << fRevision;
143
144	return string;
145}
146
147
148void
149BPackageVersion::SetTo(const BString& major, const BString& minor,
150	const BString& micro, const BString& preRelease, uint32 revision)
151{
152	fMajor = major;
153	fMinor = minor;
154	fMicro = micro;
155	fPreRelease = preRelease;
156	fRevision = revision;
157
158	fMajor.ToLower();
159	fMinor.ToLower();
160	fMicro.ToLower();
161	fPreRelease.ToLower();
162}
163
164
165status_t
166BPackageVersion::SetTo(const BString& versionString, bool revisionIsOptional)
167{
168	Clear();
169	return BPackageInfo::ParseVersionString(versionString, revisionIsOptional,
170		*this);
171}
172
173
174void
175BPackageVersion::Clear()
176{
177	fMajor.Truncate(0);
178	fMinor.Truncate(0);
179	fMicro.Truncate(0);
180	fPreRelease.Truncate(0);
181	fRevision = 0;
182}
183
184
185}	// namespace BPackageKit
186