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