/* * Copyright 2011, Oliver Tappe * Distributed under the terms of the MIT License. */ #include #include #include #include namespace BPackageKit { const char* BPackageResolvableExpression ::kOperatorNames[B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT] = { "<", "<=", "==", "!=", ">=", ">", }; BPackageResolvableExpression::BPackageResolvableExpression() : fOperator(B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT) { } BPackageResolvableExpression::BPackageResolvableExpression( const BPackageResolvableExpressionData& data) : fName(data.name), fOperator(data.op), fVersion(data.version) { fName.ToLower(); } BPackageResolvableExpression::BPackageResolvableExpression(const BString& name, BPackageResolvableOperator _operator, const BPackageVersion& version) : fName(name), fOperator(_operator), fVersion(version) { fName.ToLower(); } BPackageResolvableExpression::BPackageResolvableExpression( const BString& expressionString) : fName(), fOperator(B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT), fVersion() { SetTo(expressionString); } status_t BPackageResolvableExpression::InitCheck() const { if (fName.Length() == 0) return B_NO_INIT; // either both or none of operator and version must be set if ((fOperator >= 0 && fOperator < B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT) != (fVersion.InitCheck() == B_OK)) return B_NO_INIT; return B_OK; } const BString& BPackageResolvableExpression::Name() const { return fName; } BPackageResolvableOperator BPackageResolvableExpression::Operator() const { return fOperator; } const BPackageVersion& BPackageResolvableExpression::Version() const { return fVersion; } BString BPackageResolvableExpression::ToString() const { BString string = fName; if (fVersion.InitCheck() == B_OK) string << kOperatorNames[fOperator] << fVersion.ToString(); return string; } status_t BPackageResolvableExpression::SetTo(const BString& expressionString) { fName.Truncate(0); fOperator = B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT; fVersion.Clear(); return BPackageInfo::ParseResolvableExpressionString(expressionString, *this); } void BPackageResolvableExpression::SetTo(const BString& name, BPackageResolvableOperator _operator, const BPackageVersion& version) { fName = name; fOperator = _operator; fVersion = version; fName.ToLower(); } void BPackageResolvableExpression::Clear() { fName.Truncate(0); fOperator = B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT; fVersion.Clear(); } bool BPackageResolvableExpression::Matches(const BPackageVersion& version, const BPackageVersion& compatibleVersion) const { // If no particular version is required, we always match. if (fVersion.InitCheck() != B_OK) return true; if (version.InitCheck() != B_OK) return false; int compare = version.Compare(fVersion); bool matches = false; switch (fOperator) { case B_PACKAGE_RESOLVABLE_OP_LESS: matches = compare < 0; break; case B_PACKAGE_RESOLVABLE_OP_LESS_EQUAL: matches = compare <= 0; break; case B_PACKAGE_RESOLVABLE_OP_EQUAL: matches = compare == 0; break; case B_PACKAGE_RESOLVABLE_OP_NOT_EQUAL: matches = compare != 0; break; case B_PACKAGE_RESOLVABLE_OP_GREATER_EQUAL: matches = compare >= 0; break; case B_PACKAGE_RESOLVABLE_OP_GREATER: matches = compare > 0; break; default: break; } if (!matches) return false; // Check compatible version. If not specified, the match must be exact. // Otherwise fVersion must be >= compatibleVersion. if (compatibleVersion.InitCheck() != B_OK) return compare == 0; // Since compatibleVersion <= version, we can save the comparison, if // version <= fVersion. return compare <= 0 || compatibleVersion.Compare(fVersion) <= 0; } bool BPackageResolvableExpression::Matches(const BPackageResolvable& provides) const { if (provides.Name() != fName) return false; return Matches(provides.Version(), provides.CompatibleVersion()); } } // namespace BPackageKit