return (id)self;
}
+/* key/value archiving */
+
+- (id)initWithKeyValueUnarchiver:(EOKeyValueUnarchiver *)_unarchiver {
+ int opt;
+ NSPredicateOperatorType ptype;
+ NSComparisonPredicateModifier mod;
+ NSExpression *left, *right;
+ NSString *selName, *s;
+
+ /* left / right - TODO: need to check 'official' keys fo rthat */
+
+ left = [_unarchiver decodeObjectForKey:@"left"];
+ if (left != nil && ![left isKindOfClass:[NSExpression class]])
+ left = [NSExpression expressionForConstantValue:left];
+
+ right = [_unarchiver decodeObjectForKey:@"right"];
+ if (right != nil && ![right isKindOfClass:[NSExpression class]])
+ right = [NSExpression expressionForConstantValue:right];
+
+ /* custom selector */
+
+ selName = [_unarchiver decodeObjectForKey:@"selector"];
+ if ([selName length] > 0) {
+ return [self initWithLeftExpression:left rightExpression:right
+ customSelector:NSSelectorFromString(selName)];
+ }
+
+ /* modifier */
+
+ if ((s = [_unarchiver decodeObjectForKey:@"modifier"]) != nil) {
+ if ([s isEqualToString:@"direct"]) mod = NSDirectPredicateModifier;
+ else if ([s isEqualToString:@"all"]) mod = NSAllPredicateModifier;
+ else if ([s isEqualToString:@"any"]) mod = NSAnyPredicateModifier;
+ else {
+ NSLog(@"WARNING(%s): could not decode modifier (trying int): %@!",
+ __PRETTY_FUNCTION__, s);
+ mod = [s intValue];
+ }
+ }
+ else
+ mod = NSDirectPredicateModifier;
+
+ /* type */
+
+ if ((s = [_unarchiver decodeObjectForKey:@"type"]) != nil) {
+ if ([s isEqualToString:@"<"])
+ ptype = NSLessThanPredicateOperatorType;
+ else if ([s isEqualToString:@"=<"])
+ ptype = NSLessThanOrEqualToPredicateOperatorType;
+ else if ([s isEqualToString:@">"])
+ ptype = NSGreaterThanPredicateOperatorType;
+ else if ([s isEqualToString:@">="])
+ ptype = NSGreaterThanOrEqualToPredicateOperatorType;
+ else if ([s isEqualToString:@"=="])
+ ptype = NSEqualToPredicateOperatorType;
+ else if ([s isEqualToString:@"!="])
+ ptype = NSNotEqualToPredicateOperatorType;
+ else if ([s isEqualToString:@"like"])
+ ptype = NSLikePredicateOperatorType;
+ else if ([s isEqualToString:@"contains"])
+ ptype = NSInPredicateOperatorType;
+ else if ([s isEqualToString:@"beginswith"])
+ ptype = NSBeginsWithPredicateOperatorType;
+ else if ([s isEqualToString:@"endswith"])
+ ptype = NSEndsWithPredicateOperatorType;
+ else if ([s isEqualToString:@"matches"])
+ ptype = NSMatchesPredicateOperatorType;
+ else {
+ NSLog(@"WARNING(%s): could not decode type (trying int): %@!",
+ __PRETTY_FUNCTION__, s);
+ ptype = [s intValue];
+ }
+ }
+ else
+ ptype = NSEqualToPredicateOperatorType;
+
+ /* options */
+
+ // TODO: use bit-compare and a set?
+ if ((s = [_unarchiver decodeObjectForKey:@"options"]) != nil) {
+ if ([s isEqualToString:@"caseInsensitive"])
+ opt = NSCaseInsensitivePredicateOption;
+ else if ([s isEqualToString:@"diacritic"])
+ opt = NSDiacriticInsensitivePredicateOption;
+ else {
+ NSLog(@"WARNING(%s): could not decode options (trying int): %@!",
+ __PRETTY_FUNCTION__, s);
+ opt = [s intValue];
+ }
+ }
+ else
+ opt = 0;
+
+ /* create and return */
+
+ return [self initWithLeftExpression:left rightExpression:right
+ modifier:mod type:ptype options:opt];
+}
+
+- (void)encodeWithKeyValueArchiver:(EOKeyValueArchiver *)_archiver {
+ NSString *s;
+
+ [_archiver encodeObject:[self leftExpression] forKey:@"left"];
+ [_archiver encodeObject:[self rightExpression] forKey:@"right"];
+
+ /* type */
+
+ switch ([self predicateOperatorType]) {
+ case NSCustomSelectorPredicateOperatorType:
+ [_archiver encodeObject:NSStringFromSelector([self customSelector])
+ forKey:@"selector"];
+ return; /* no more info */
+
+ case NSLessThanPredicateOperatorType: s = @"<"; break;
+ case NSLessThanOrEqualToPredicateOperatorType: s = @"=<"; break;
+ case NSGreaterThanPredicateOperatorType: s = @">"; break;
+ case NSGreaterThanOrEqualToPredicateOperatorType: s = @">="; break;
+ case NSEqualToPredicateOperatorType: s = @"=="; break;
+ case NSNotEqualToPredicateOperatorType: s = @"!="; break;
+ case NSLikePredicateOperatorType: s = @"like"; break;
+ case NSInPredicateOperatorType: s = @"contains"; break;
+ case NSBeginsWithPredicateOperatorType: s = @"beginswith"; break;
+ case NSEndsWithPredicateOperatorType: s = @"endswith"; break;
+ case NSMatchesPredicateOperatorType: s = @"matches"; break;
+
+ default:
+ s = [NSString stringWithFormat:@"%i", [self predicateOperatorType]];
+ break;
+ }
+ if (s != nil) [_archiver encodeObject:s forKey:@"type"];
+
+ /* modifier */
+
+ switch ([self comparisonPredicateModifier]) {
+ case NSDirectPredicateModifier: s = nil; break;
+ case NSAllPredicateModifier: s = @"all"; break;
+ case NSAnyPredicateModifier: s = @"any"; break;
+ default:
+ s = [NSString stringWithFormat:@"%i",
+ [self comparisonPredicateModifier]];
+ break;
+ }
+ if (s != nil) [_archiver encodeObject:s forKey:@"modifier"];
+
+ /* options */
+
+ // TODO: use bit-compare and a set?
+
+ if ([self options] == NSCaseInsensitivePredicateOption)
+ [_archiver encodeObject:@"caseInsensitive" forKey:@"options"];
+ else if ([self options] == NSDiacriticInsensitivePredicateOption)
+ [_archiver encodeObject:@"diacritic" forKey:@"options"];
+}
+
@end /* NSComparisonPredicate(EOCoreData) */