xref: /haiku/src/kits/package/PackageResolvableExpression.cpp (revision f73f5d4c42a01ece688cbb57b5d332cc0f68b2c6)
1 /*
2  * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <package/PackageResolvableExpression.h>
8 
9 #include <package/hpkg/PackageInfoAttributeValue.h>
10 #include <package/PackageResolvable.h>
11 
12 
13 namespace BPackageKit {
14 
15 
16 const char*
17 BPackageResolvableExpression
18 ::kOperatorNames[B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT] = {
19 	"<",
20 	"<=",
21 	"==",
22 	"!=",
23 	">=",
24 	">",
25 };
26 
27 
28 BPackageResolvableExpression::BPackageResolvableExpression()
29 	:
30 	fOperator(B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT)
31 {
32 }
33 
34 
35 BPackageResolvableExpression::BPackageResolvableExpression(
36 	const BPackageResolvableExpressionData& data)
37 	:
38 	fName(data.name),
39 	fOperator(data.op),
40 	fVersion(data.version)
41 {
42 	fName.ToLower();
43 }
44 
45 
46 BPackageResolvableExpression::BPackageResolvableExpression(const BString& name,
47 	BPackageResolvableOperator _operator, const BPackageVersion& version)
48 	:
49 	fName(name),
50 	fOperator(_operator),
51 	fVersion(version)
52 {
53 	fName.ToLower();
54 }
55 
56 
57 status_t
58 BPackageResolvableExpression::InitCheck() const
59 {
60 	if (fName.Length() == 0)
61 		return B_NO_INIT;
62 
63 	// either both or none of operator and version must be set
64 	if ((fOperator >= 0 && fOperator < B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT)
65 		!= (fVersion.InitCheck() == B_OK))
66 		return B_NO_INIT;
67 
68 	return B_OK;
69 }
70 
71 
72 const BString&
73 BPackageResolvableExpression::Name() const
74 {
75 	return fName;
76 }
77 
78 
79 BPackageResolvableOperator
80 BPackageResolvableExpression::Operator() const
81 {
82 	return fOperator;
83 }
84 
85 
86 const BPackageVersion&
87 BPackageResolvableExpression::Version() const
88 {
89 	return fVersion;
90 }
91 
92 
93 BString
94 BPackageResolvableExpression::ToString() const
95 {
96 	BString string = fName;
97 
98 	if (fVersion.InitCheck() == B_OK)
99 		string << kOperatorNames[fOperator] << fVersion.ToString();
100 
101 	return string;
102 }
103 
104 
105 void
106 BPackageResolvableExpression::SetTo(const BString& name,
107 	BPackageResolvableOperator _operator, const BPackageVersion& version)
108 {
109 	fName = name;
110 	fOperator = _operator;
111 	fVersion = version;
112 
113 	fName.ToLower();
114 }
115 
116 
117 void
118 BPackageResolvableExpression::Clear()
119 {
120 	fName.Truncate(0);
121 	fOperator = B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT;
122 	fVersion.Clear();
123 }
124 
125 
126 bool
127 BPackageResolvableExpression::Matches(const BPackageVersion& version,
128 	const BPackageVersion& compatibleVersion) const
129 {
130 	// If no particular version is required, we always match.
131 	if (fVersion.InitCheck() != B_OK)
132 		return true;
133 
134 	if (version.InitCheck() != B_OK)
135 		return false;
136 
137 	int compare = version.Compare(fVersion);
138 	bool matches = false;
139 	switch (fOperator) {
140 		case B_PACKAGE_RESOLVABLE_OP_LESS:
141 			matches = compare < 0;
142 			break;
143 		case B_PACKAGE_RESOLVABLE_OP_LESS_EQUAL:
144 			matches = compare <= 0;
145 			break;
146 		case B_PACKAGE_RESOLVABLE_OP_EQUAL:
147 			matches = compare == 0;
148 			break;
149 		case B_PACKAGE_RESOLVABLE_OP_NOT_EQUAL:
150 			matches = compare != 0;
151 			break;
152 		case B_PACKAGE_RESOLVABLE_OP_GREATER_EQUAL:
153 			matches = compare >= 0;
154 			break;
155 		case B_PACKAGE_RESOLVABLE_OP_GREATER:
156 			matches = compare > 0;
157 			break;
158 		default:
159 			break;
160 	}
161 	if (!matches)
162 		return false;
163 
164 	// Check compatible version. If not specified, the match must be exact.
165 	// Otherwise fVersion must be >= compatibleVersion.
166 	if (compatibleVersion.InitCheck() != B_OK)
167 		return compare == 0;
168 
169 	// Since compatibleVersion <= version, we can save the comparison, if
170 	// version <= fVersion.
171 	return compare <= 0 || compatibleVersion.Compare(fVersion) <= 0;
172 }
173 
174 
175 bool
176 BPackageResolvableExpression::Matches(const BPackageResolvable& provides) const
177 {
178 	if (provides.Name() != fName)
179 		return false;
180 
181 	return Matches(provides.Version(), provides.CompatibleVersion());
182 }
183 
184 
185 }	// namespace BPackageKit
186