xref: /haiku/src/kits/package/PackageVersion.cpp (revision 02354704729d38c3b078c696adc1bbbd33cbcf72)
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 
15 using BPrivate::NaturalCompare;
16 
17 
18 namespace BPackageKit {
19 
20 
21 BPackageVersion::BPackageVersion()
22 	:
23 	fRevision(0)
24 {
25 }
26 
27 
28 BPackageVersion::BPackageVersion(const BPackageVersionData& data)
29 {
30 	SetTo(data.major, data.minor, data.micro, data.preRelease, data.revision);
31 }
32 
33 
34 BPackageVersion::BPackageVersion(const BString& versionString,
35 	bool revisionIsOptional)
36 {
37 	SetTo(versionString, revisionIsOptional);
38 }
39 
40 
41 BPackageVersion::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 
48 status_t
49 BPackageVersion::InitCheck() const
50 {
51 	return fMajor.Length() > 0 ? B_OK : B_NO_INIT;
52 }
53 
54 
55 const BString&
56 BPackageVersion::Major() const
57 {
58 	return fMajor;
59 }
60 
61 
62 const BString&
63 BPackageVersion::Minor() const
64 {
65 	return fMinor;
66 }
67 
68 
69 const BString&
70 BPackageVersion::Micro() const
71 {
72 	return fMicro;
73 }
74 
75 
76 const BString&
77 BPackageVersion::PreRelease() const
78 {
79 	return fPreRelease;
80 }
81 
82 
83 uint32
84 BPackageVersion::Revision() const
85 {
86 	return fRevision;
87 }
88 
89 
90 int
91 BPackageVersion::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 
124 BString
125 BPackageVersion::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 
148 void
149 BPackageVersion::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 
165 status_t
166 BPackageVersion::SetTo(const BString& versionString, bool revisionIsOptional)
167 {
168 	Clear();
169 	return BPackageInfo::ParseVersionString(versionString, revisionIsOptional,
170 		*this);
171 }
172 
173 
174 void
175 BPackageVersion::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