45 unsigned int _options;
57 + (CPPredicate)predicateWithLeftExpression:(CPExpression)left rightExpression:(CPExpression)right customSelector:(
SEL)selector
59 return [[
self alloc] initWithLeftExpression:left rightExpression:right customSelector:selector];
71 + (CPPredicate)predicateWithLeftExpression:(CPExpression)left rightExpression:(CPExpression)right modifier:(
CPComparisonPredicateModifier)modifier type:(
int)type options:(
unsigned)options
73 return [[
self alloc] initWithLeftExpression:left rightExpression:right modifier:modifier type:type options:options];
83 - (id)initWithLeftExpression:(CPExpression)left rightExpression:(CPExpression)right customSelector:(
SEL)selector
94 _customSelector = selector;
117 _modifier = modifier;
126 _customSelector = NULL;
146 - (SEL)customSelector
148 return _customSelector;
155 - (CPExpression)leftExpression
182 - (CPExpression)rightExpression
200 default: modifier =
"";
216 default: options =
"";
252 return [
CPString stringWithFormat:@"%s%s %s%s %s",modifier,[_left description],operator,options,[_right description]];
255 - (CPPredicate)predicateWithSubstitutionVariables:(
CPDictionary)variables
257 var left = [_left _expressionWithSubstitutionVariables:variables],
258 right = [_right _expressionWithSubstitutionVariables:variables];
268 if (
self === anObject)
271 if (anObject === nil || anObject.isa !==
self.isa || _modifier !== [anObject comparisonPredicateModifier] || _type !== [anObject predicateOperatorType] || _options !== [anObject options] || _customSelector !== [anObject customSelector] || ![_left
isEqual:[anObject leftExpression]] || ![_right
isEqual:[anObject rightExpression]])
277 - (BOOL)_evaluateValue:lhs rightValue:rhs
279 var leftIsNil = (lhs == nil || [lhs isEqual:[
CPNull null]]),
283 return (leftIsNil == rightIsNil &&
288 var string_compare_options = 0;
303 lhs = lhs.stripDiacritics();
304 rhs = rhs.stripDiacritics();
306 return (
new RegExp(rhs,commut)).test(lhs);
310 lhs = lhs.stripDiacritics();
311 rhs = rhs.stripDiacritics();
314 reg =
new RegExp(rhs.escapeForRegExp(),commut);
315 return reg.test(lhs);
319 string_compare_options |= CPCaseInsensitiveSearch;
320 if (_options & CPDiacriticInsensitivePredicateOption)
322 return ([lhs compare:rhs options:string_compare_options range:range] ==
CPOrderedSame);
325 if (_options & CPCaseInsensitivePredicateOption)
326 string_compare_options |= CPCaseInsensitiveSearch;
327 if (_options & CPDiacriticInsensitivePredicateOption)
329 return ([lhs compare:rhs options:string_compare_options range:range] ==
CPOrderedSame);
338 if (![lhs respondsToSelector:
@selector(objectEnumerator)])
339 [
CPException raise:CPInvalidArgumentException
reason:@"The left/right hand side for a CONTAINS/IN operator must be a collection or a string"];
341 return [lhs containsObject:rhs];
344 if (_options & CPCaseInsensitivePredicateOption)
345 string_compare_options |= CPCaseInsensitiveSearch;
346 if (_options & CPDiacriticInsensitivePredicateOption)
349 return ([lhs rangeOfString:rhs options:string_compare_options].location !=
CPNotFound);
352 [
CPException raise:CPInvalidArgumentException
reason:@"The right hand side for a BETWEEN operator must contain 2 objects"];
360 - (BOOL)evaluateWithObject:(
id)object
365 - (BOOL)evaluateWithObject:(
id)object substitutionVariables:(
CPDictionary)variables
367 var leftValue = [_left expressionValueWithObject:object context:variables],
368 rightValue = [_right expressionValueWithObject:object context:variables];
371 return [
self _evaluateValue:leftValue rightValue:rightValue];
374 if (![leftValue respondsToSelector:
@selector(objectEnumerator)])
375 [
CPException raise:CPInvalidArgumentException
reason:@"The left hand side for an ALL or ANY operator must be either a CPArray or a CPSet"];
377 var e = [leftValue objectEnumerator],
381 while ((value = [e nextObject]) !== nil)
383 var eval = [
self _evaluateValue:value rightValue:rightValue];
402 _left = [coder decodeObjectForKey:@"CPComparisonPredicateLeftExpression"];
403 _right = [coder decodeObjectForKey:@"CPComparisonPredicateRightExpression"];
404 _modifier = [coder decodeIntForKey:@"CPComparisonPredicateModifier"];
405 _type = [coder decodeIntForKey:@"CPComparisonPredicateType"];
406 _options = [coder decodeIntForKey:@"CPComparisonPredicateOptions"];
407 _customSelector = [coder decodeObjectForKey:@"CPComparisonPredicateCustomSelector"];
415 [coder encodeObject:_left forKey:@"CPComparisonPredicateLeftExpression"];
416 [coder encodeObject:_right forKey:@"CPComparisonPredicateRightExpression"];
417 [coder encodeInt:_modifier forKey:@"CPComparisonPredicateModifier"];
418 [coder encodeInt:_type forKey:@"CPComparisonPredicateType"];
419 [coder encodeInt:_options forKey:@"CPComparisonPredicateOptions"];
420 [coder encodeObject:_customSelector forKey:@"CPComparisonPredicateCustomSelector"];
425 var
source = ['*','?','(',')','{','}','.','+','|','/',','^'],
426 dest = ['.*','.?','\\(','\\)','\\{','\\}','\\.','\\+','\\|','\\/','\\$','\\^'];
428 String.prototype.escapeForRegExp =
function()
430 var foundChar =
false,
433 for (; i <
source.length; ++i)
435 if (this.indexOf(
source[i]) !== -1)
447 for (i = 0; i < this.length; ++i)
449 var sourceIndex =
source.indexOf(this.charAt(i));
450 if (sourceIndex !== -1)
451 result +=
dest[sourceIndex];
453 result += this.charAt(i);