Esempio n. 1
0
bool ZTBSpec::Criterion::Matches(const ZTuple& iTuple) const
	{
	ZTuple::const_iterator propIter = iTuple.IteratorOf(this->GetPropName());
	if (propIter == iTuple.end())
		{
		// iTuple does not have a property named fPropName. For
		// 'Lacks' and 'LacksOfType' relationships that means
		// we match iTuple, for all other relationships we don't.
		return this->GetComparator().fRel == eRel_Lacks
			|| this->GetComparator().fRel == eRel_LacksOfType;
		}

	switch (this->GetComparator().fRel)
		{
		case eRel_Has:
			{
			return true;
			}
		case eRel_HasOfType:
			{
			return iTuple.TypeOf(propIter) == this->GetTupleValue().GetType();
			}
		case eRel_Lacks:
			{
			// iTuple has a property named fPropName,
			// so it doesn't lack a property named fPropName.
			return false;
			}
		case eRel_LacksOfType:
			{
			return iTuple.TypeOf(propIter) != this->GetTupleValue().GetType();			
			}
		case eRel_VectorContains:
			{
			if (iTuple.TypeOf(propIter) != eZType_Vector)
				return false;

			const vector<ZTupleValue>& theVector = iTuple.GetVector(propIter);
			for (vector<ZTupleValue>::const_iterator i = theVector.begin();
				i != theVector.end(); ++i)
				{
				if (*i == this->GetTupleValue())
					return true;
#if 0 //##
				if ((*i).TypeOf() == this->GetTupleValue().TypeOf())
					{
					if ((*i).UncheckedEqual(this->GetTupleValue()))
						return true;
					}
#endif
				}
			return false;			
			}
		case eRel_StringContains:
			{
			string pattern;
			if (!this->GetTupleValue().GetString(pattern) || pattern.empty())
				return true;

			string target;
			if (!iTuple.GetString(propIter, target) || target.empty())
				return false;

			if (!fRep->fTextCollator)
				{
				fRep->fTextCollator =
					ZTextCollator(this->GetComparator().fStrength);
				}

			return fRep->fTextCollator.Contains(pattern, target);
			}
		case eRel_Regex:
			{
			#if ZCONFIG_API_Enabled(Regex)
				string target;
				if (!iTuple.GetString(propIter, target) || target.empty())
					return false;

				if (!fRep->fRegex)
					{
					fRep->fRegex =
						ZRegex(this->GetTupleValue().GetString(), this->GetComparator().fStrength);
					}

				if (!fRep->fRegex)
					return false;

				return fRep->fRegex.Matches(target);
			#else
				return false;
			#endif
			}
		default:
			{
			const ZTupleValue& leftValue = iTuple.GetValue(propIter);
			ZType leftType = leftValue.TypeOf();
			ZType rightType = this->GetTupleValue().TypeOf();
			if (this->GetComparator().fRel == eRel_Equal)
				{
				if (leftType != rightType)
					{
					return false;
					}
				else
					{
					if (leftType == eZType_String && this->GetComparator().fStrength != 0)
						{
						// We're doing string compares where the strength is non zero and
						// so we need to use a collator to do the comparison.
						if (!fRep->fTextCollator)
							{
							fRep->fTextCollator =
								ZTextCollator(this->GetComparator().fStrength);
							}

						return fRep->fTextCollator.Equals(
							leftValue.GetString(), this->GetTupleValue().GetString());
						}
					else
						{
						// The type matches, so do the appropriate comparison.
						// return leftValue.pUncheckedEqual(this->GetTupleValue());
						return leftValue == this->GetTupleValue();
						}
					}
				}
			else
				{
				int compare;
				if (leftType != rightType)
					{
					compare = int(leftType) - int(rightType);
					}
				else
					{
					if (leftType == eZType_String && this->GetComparator().fStrength != 0)
						{
						// We're doing string compares where the strength is non zero and
						// so we need to use a collator to do the comparison.
						if (!fRep->fTextCollator)
							{
							fRep->fTextCollator =
								ZTextCollator(this->GetComparator().fStrength);
							}

						compare = fRep->fTextCollator.Compare(
							leftValue.GetString(), this->GetTupleValue().GetString());
						}
					else
						{
						// The type matches, so do the appropriate comparison.
						// compare = leftValue.pUncheckedCompare(this->GetTupleValue());
						compare = leftValue.Compare(this->GetTupleValue());
						}
					}
				switch (this->GetComparator().fRel)
					{
					case eRel_Less: return compare < 0;
					case eRel_LessEqual: return compare <= 0;
					case eRel_GreaterEqual: return compare >= 0;
					case eRel_Greater: return compare > 0;
					}
				}
			}
		}
	// Can't get here.
	ZUnimplemented();
	return false;
	}