Oolite
Loading...
Searching...
No Matches
OOPListSchemaVerifier.m File Reference
import "OOPListSchemaVerifier.h"
import "OOLoggingExtended.h"
import "OOCollectionExtractors.h"
import "OOMaths.h"
#include <limits.h>
+ Include dependency graph for OOPListSchemaVerifier.m:

Go to the source code of this file.

Classes

struct  BackLinkChain
 
category  OOPListSchemaVerifier(OOPrivate)
 
category  NSString(OOPListSchemaVerifierHelpers)
 

Macros

#define PLIST_VERIFIER_DEBUG_DUMP_ENABLED   1
 
#define DebugDumpIndent()   do { if (sDebugDump) OOLogIndent(); } while (0)
 
#define DebugDumpOutdent()   do { if (sDebugDump) OOLogOutdent(); } while (0)
 
#define DebugDumpPushIndent()   do { if (sDebugDump) OOLogPushIndent(); } while (0)
 
#define DebugDumpPopIndent()   do { if (sDebugDump) OOLogPopIndent(); } while (0)
 
#define DebugDump(...)   do { if (sDebugDump) OOLog(@"verifyOXP.verbose.plistDebugDump", __VA_ARGS__); } while (0)
 
#define VERIFY_PROTO(T)   static NSError *Verify_##T(OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
#define VERIFY_CASE(T)   case kType##T: error = Verify_##T(self, subProperty, resolvedSpecifier, rootPList, name, keyPath, tentative, outStop); break;
 
#define REQUIRE_TYPE(CLASSNAME, NAMESTRING)
 

Typedefs

typedef struct BackLinkChain BackLinkChain
 

Enumerations

enum  { kMaximumLengthForStringInErrorMessage = 100 }
 
enum  { kStartOfPrivateErrorCodes = kPListErrorLastErrorCode , kPListErrorFailedAndErrorHasBeenReported }
 
enum  SchemaType {
  kTypeUnknown , kTypeString , kTypeArray , kTypeDictionary ,
  kTypeInteger , kTypePositiveInteger , kTypeFloat , kTypePositiveFloat ,
  kTypeOneOf , kTypeEnumeration , kTypeBoolean , kTypeFuzzyBoolean ,
  kTypeVector , kTypeQuaternion , kTypeDelegatedType
}
 

Functions

OOINLINE BackLinkChain BackLink (BackLinkChain *link, id element)
 
OOINLINE BackLinkChain BackLinkIndex (BackLinkChain *link, NSUInteger index)
 
OOINLINE BackLinkChain BackLinkRoot (void)
 
static SchemaType StringToSchemaType (NSString *string, NSError **outError)
 
static NSString * ApplyStringFilter (NSString *string, id filterSpec, BackLinkChain keyPath, NSError **outError)
 
static BOOL ApplyStringTest (NSString *string, id test, SEL testSelector, NSString *testDescription, BackLinkChain keyPath, NSError **outError)
 
static NSArray * KeyPathToArray (BackLinkChain keyPath)
 
static NSString * KeyPathToString (BackLinkChain keyPath)
 
static NSString * StringForErrorReport (NSString *string)
 
static NSString * ArrayForErrorReport (NSArray *array)
 
static NSString * SetForErrorReport (NSSet *set)
 
static NSString * StringOrArrayForErrorReport (id value, NSString *arrayPrefix)
 
static NSError * Error (OOPListSchemaVerifierErrorCode errorCode, BackLinkChain *keyPath, NSString *format,...)
 
static NSError * ErrorWithProperty (OOPListSchemaVerifierErrorCode errorCode, BackLinkChain *keyPath, NSString *propKey, id propValue, NSString *format,...)
 
static NSError * ErrorWithDictionary (OOPListSchemaVerifierErrorCode errorCode, BackLinkChain *keyPath, NSDictionary *dict, NSString *format,...)
 
static NSError * ErrorWithDictionaryAndArguments (OOPListSchemaVerifierErrorCode errorCode, BackLinkChain *keyPath, NSDictionary *dict, NSString *format, va_list arguments)
 
static NSError * ErrorTypeMismatch (Class expectedClass, NSString *expectedClassName, id actualObject, BackLinkChain keyPath)
 
static NSError * ErrorFailureAlreadyReported (void)
 
static BOOL IsFailureAlreadyReportedError (NSError *error)
 
 VERIFY_PROTO (String)
 
 VERIFY_PROTO (Array)
 
 VERIFY_PROTO (Dictionary)
 
 VERIFY_PROTO (Integer)
 
 VERIFY_PROTO (PositiveInteger)
 
 VERIFY_PROTO (Float)
 
 VERIFY_PROTO (PositiveFloat)
 
 VERIFY_PROTO (OneOf)
 
 VERIFY_PROTO (Enumeration)
 
 VERIFY_PROTO (Boolean)
 
 VERIFY_PROTO (FuzzyBoolean)
 
 VERIFY_PROTO (Vector)
 
 VERIFY_PROTO (Quaternion)
 
 VERIFY_PROTO (DelegatedType)
 
static NSError * Verify_String (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
static NSError * Verify_Array (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
static NSError * Verify_Dictionary (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
static NSError * Verify_Integer (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
static NSError * Verify_PositiveInteger (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
static NSError * Verify_Float (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
static NSError * Verify_PositiveFloat (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
static NSError * Verify_OneOf (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
static NSError * Verify_Enumeration (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
static NSError * Verify_Boolean (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
static NSError * Verify_FuzzyBoolean (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
static NSError * Verify_Vector (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
static NSError * Verify_Quaternion (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 
static NSError * Verify_DelegatedType (OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)
 

Variables

static BOOL sDebugDump = NO
 
NSString *const kOOPListSchemaVerifierErrorDomain = @"org.aegidian.oolite.OOPListSchemaVerifier.ErrorDomain"
 
NSString *const kPListKeyPathErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier plist key path"
 
NSString *const kSchemaKeyPathErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier schema key path"
 
NSString *const kExpectedClassErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier expected class"
 
NSString *const kExpectedClassNameErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier expected class name"
 
NSString *const kUnknownKeyErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier unknown key"
 
NSString *const kMissingRequiredKeysErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier missing required keys"
 
NSString *const kMissingSubStringErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier missing substring"
 
NSString *const kUnnownFilterErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier unknown filter"
 
NSString *const kErrorsByOptionErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier errors by option"
 
NSString *const kUnknownTypeErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier unknown type"
 
NSString *const kUndefinedMacroErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier undefined macro"
 

Macro Definition Documentation

◆ DebugDump

#define DebugDump (   ...)    do { if (sDebugDump) OOLog(@"verifyOXP.verbose.plistDebugDump", __VA_ARGS__); } while (0)

Definition at line 64 of file OOPListSchemaVerifier.m.

◆ DebugDumpIndent

#define DebugDumpIndent ( )    do { if (sDebugDump) OOLogIndent(); } while (0)

Definition at line 60 of file OOPListSchemaVerifier.m.

◆ DebugDumpOutdent

#define DebugDumpOutdent ( )    do { if (sDebugDump) OOLogOutdent(); } while (0)

Definition at line 61 of file OOPListSchemaVerifier.m.

◆ DebugDumpPopIndent

#define DebugDumpPopIndent ( )    do { if (sDebugDump) OOLogPopIndent(); } while (0)

Definition at line 63 of file OOPListSchemaVerifier.m.

◆ DebugDumpPushIndent

#define DebugDumpPushIndent ( )    do { if (sDebugDump) OOLogPushIndent(); } while (0)

Definition at line 62 of file OOPListSchemaVerifier.m.

◆ PLIST_VERIFIER_DEBUG_DUMP_ENABLED

#define PLIST_VERIFIER_DEBUG_DUMP_ENABLED   1

Definition at line 38 of file OOPListSchemaVerifier.m.

◆ REQUIRE_TYPE

#define REQUIRE_TYPE (   CLASSNAME,
  NAMESTRING 
)
Value:
do { \
if (![value isKindOfClass:[CLASSNAME class]]) \
{ \
return ErrorTypeMismatch([CLASSNAME class], NAMESTRING, value, keyPath); \
} \
} while (0)
static NSError * ErrorTypeMismatch(Class expectedClass, NSString *expectedClassName, id actualObject, BackLinkChain keyPath)

Definition at line 830 of file OOPListSchemaVerifier.m.

830 { \
831 if (![value isKindOfClass:[CLASSNAME class]]) \
832 { \
833 return ErrorTypeMismatch([CLASSNAME class], NAMESTRING, value, keyPath); \
834 } \
835 } while (0)

◆ VERIFY_CASE

#define VERIFY_CASE (   T)    case kType##T: error = Verify_##T(self, subProperty, resolvedSpecifier, rootPList, name, keyPath, tentative, outStop); break;

◆ VERIFY_PROTO

#define VERIFY_PROTO (   T)    static NSError *Verify_##T(OOPListSchemaVerifier *verifier, id value, NSDictionary *params, id rootPList, NSString *name, BackLinkChain keyPath, BOOL tentative, BOOL *outStop)

Definition at line 196 of file OOPListSchemaVerifier.m.

Typedef Documentation

◆ BackLinkChain

typedef struct BackLinkChain BackLinkChain

Definition at line 111 of file OOPListSchemaVerifier.m.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
kMaximumLengthForStringInErrorMessage 

Definition at line 41 of file OOPListSchemaVerifier.m.

42{
43 // Largest allowable number of characters for string included in error message.
45};
@ kMaximumLengthForStringInErrorMessage

◆ anonymous enum

anonymous enum
Enumerator
kStartOfPrivateErrorCodes 
kPListErrorFailedAndErrorHasBeenReported 

Definition at line 49 of file OOPListSchemaVerifier.m.

◆ SchemaType

enum SchemaType
Enumerator
kTypeUnknown 
kTypeString 
kTypeArray 
kTypeDictionary 
kTypeInteger 
kTypePositiveInteger 
kTypeFloat 
kTypePositiveFloat 
kTypeOneOf 
kTypeEnumeration 
kTypeBoolean 
kTypeFuzzyBoolean 
kTypeVector 
kTypeQuaternion 
kTypeDelegatedType 

Definition at line 91 of file OOPListSchemaVerifier.m.

Function Documentation

◆ ApplyStringFilter()

static NSString * ApplyStringFilter ( NSString *  string,
id  filterSpec,
BackLinkChain  keyPath,
NSError **  outError 
)
static

Definition at line 595 of file OOPListSchemaVerifier.m.

596{
597 NSEnumerator *filterEnum = nil;
598 id filter = nil;
599 NSRange range;
600
601 assert(outError != NULL);
602
603 if (filterSpec == nil) return string;
604
605 if ([filterSpec isKindOfClass:[NSString class]])
606 {
607 filterSpec = [NSArray arrayWithObject:filterSpec];
608 }
609 if ([filterSpec isKindOfClass:[NSArray class]])
610 {
611 for (filterEnum = [filterSpec objectEnumerator]; (filter = [filterEnum nextObject]); )
612 {
613 if ([filter isKindOfClass:[NSString class]])
614 {
615 if ([filter isEqual:@"lowerCase"]) string = [string lowercaseString];
616 else if ([filter isEqual:@"upperCase"]) string = [string uppercaseString];
617 else if ([filter isEqual:@"capitalized"]) string = [string capitalizedString];
618 else if ([filter hasPrefix:@"truncFront:"])
619 {
620 string = [string substringToIndex:[[filter substringFromIndex:11] intValue]];
621 }
622 else if ([filter hasPrefix:@"truncBack:"])
623 {
624 string = [string substringToIndex:[[filter substringFromIndex:10] intValue]];
625 }
626 else if ([filter hasPrefix:@"subStringTo:"])
627 {
628 range = [string rangeOfString:[filter substringFromIndex:12]];
629 if (range.location != NSNotFound)
630 {
631 string = [string substringToIndex:range.location];
632 }
633 }
634 else if ([filter hasPrefix:@"subStringFrom:"])
635 {
636 range = [string rangeOfString:[filter substringFromIndex:14]];
637 if (range.location != NSNotFound)
638 {
639 string = [string substringFromIndex:range.location + range.length];
640 }
641 }
642 else if ([filter hasPrefix:@"subStringToInclusive:"])
643 {
644 range = [string rangeOfString:[filter substringFromIndex:21]];
645 if (range.location != NSNotFound)
646 {
647 string = [string substringToIndex:range.location + range.length];
648 }
649 }
650 else if ([filter hasPrefix:@"subStringFromInclusive:"])
651 {
652 range = [string rangeOfString:[filter substringFromIndex:23]];
653 if (range.location != NSNotFound)
654 {
655 string = [string substringFromIndex:range.location];
656 }
657 }
658 else
659 {
660 *outError = ErrorWithProperty(kPListErrorSchemaUnknownFilter, &keyPath, kUnnownFilterErrorKey, filter, @"Bad schema: unknown string filter specifier \"%@\".", filter);
661 }
662 }
663 else
664 {
665 *outError = Error(kPListErrorSchemaUnknownFilter, &keyPath, @"Bad schema: filter specifier is not a string.");
666 }
667 }
668 }
669 else
670 {
671 *outError = Error(kPListErrorSchemaUnknownFilter, &keyPath, @"Bad schema: \"filter\" must be a string or an array.");
672 }
673
674 return string;
675}
@ kPListErrorSchemaUnknownFilter
static NSError * Error(OOPListSchemaVerifierErrorCode errorCode, BackLinkChain *keyPath, NSString *format,...)
NSString *const kUnnownFilterErrorKey
static NSError * ErrorWithProperty(OOPListSchemaVerifierErrorCode errorCode, BackLinkChain *keyPath, NSString *propKey, id propValue, NSString *format,...)
return nil

References Error(), ErrorWithProperty(), kPListErrorSchemaUnknownFilter, kUnnownFilterErrorKey, and nil.

Referenced by Verify_Enumeration(), and Verify_String().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ApplyStringTest()

static BOOL ApplyStringTest ( NSString *  string,
id  test,
SEL  testSelector,
NSString *  testDescription,
BackLinkChain  keyPath,
NSError **  outError 
)
static

Definition at line 678 of file OOPListSchemaVerifier.m.

679{
680 BOOL (*testIMP)(id, SEL, NSString *);
681 NSEnumerator *testEnum = nil;
682 id subTest = nil;
683
684 assert(outError != NULL);
685
686 if (test == nil) return YES;
687
688 testIMP = (BOOL(*)(id, SEL, NSString *))[string methodForSelector:testSelector];
689 if (testIMP == NULL)
690 {
691 *outError = Error(kPListErrorInternal, &keyPath, @"OOPListSchemaVerifier internal error: NSString does not respond to test selector %@.", NSStringFromSelector(testSelector));
692 return NO;
693 }
694
695 if ([test isKindOfClass:[NSString class]])
696 {
697 test = [NSArray arrayWithObject:test];
698 }
699
700 if ([test isKindOfClass:[NSArray class]])
701 {
702 for (testEnum = [test objectEnumerator]; (subTest = [testEnum nextObject]); )
703 {
704 if ([subTest isKindOfClass:[NSString class]])
705 {
706 if (testIMP(string, testSelector, subTest)) return YES;
707 }
708 else
709 {
710 *outError = Error(kPListErrorSchemaBadComparator, &keyPath, @"Bad schema: required %@ is not a string.", testDescription);
711 return NO;
712 }
713 }
714 }
715 else
716 {
717 *outError = Error(kPListErrorSchemaBadComparator, &keyPath, @"Bad schema: %@ requirement specification is not a string or array.", testDescription);
718 }
719 return NO;
720}
@ kPListErrorInternal
@ kPListErrorSchemaBadComparator

References Error(), kPListErrorInternal, kPListErrorSchemaBadComparator, and nil.

Referenced by Verify_String().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ArrayForErrorReport()

static NSString * ArrayForErrorReport ( NSArray *  array)
static

Definition at line 768 of file OOPListSchemaVerifier.m.

769{
770 NSString *result = nil;
771 NSString *string = nil;
772 NSUInteger i, count;
773 NSAutoreleasePool *pool = nil;
774
775 count = [array count];
776 if (count == 0) return @"( )";
777
778 pool = [[NSAutoreleasePool alloc] init];
779
780 result = [NSString stringWithFormat:@"(%@", [array objectAtIndex:0]];
781
782 for (i = 1; i != count; ++i)
783 {
784 string = [result stringByAppendingFormat:@", %@", [array objectAtIndex:i]];
785 if (kMaximumLengthForStringInErrorMessage < [string length])
786 {
787 result = [result stringByAppendingString:@", ..."];
788 break;
789 }
790 result = string;
791 }
792
793 result = [result stringByAppendingString:@")"];
794
795 [result retain];
796 [pool release];
797 return [result autorelease];
798}
unsigned count

References count, kMaximumLengthForStringInErrorMessage, and nil.

Referenced by SetForErrorReport(), and Verify_Enumeration().

+ Here is the caller graph for this function:

◆ BackLink()

OOINLINE BackLinkChain BackLink ( BackLinkChain link,
id  element 
)

Definition at line 118 of file OOPListSchemaVerifier.m.

119{
120 BackLinkChain result = { link, element };
121 return result;
122}

References BackLinkChain::element, and BackLinkChain::link.

Referenced by Verify_Dictionary().

+ Here is the caller graph for this function:

◆ BackLinkIndex()

OOINLINE BackLinkChain BackLinkIndex ( BackLinkChain link,
NSUInteger  index 
)

Definition at line 124 of file OOPListSchemaVerifier.m.

125{
126 BackLinkChain result = { link, [NSNumber numberWithInteger:index] };
127 return result;
128}

References BackLinkChain::link.

Referenced by Verify_Array().

+ Here is the caller graph for this function:

◆ BackLinkRoot()

OOINLINE BackLinkChain BackLinkRoot ( void  )

Definition at line 130 of file OOPListSchemaVerifier.m.

131{
132 BackLinkChain result = { NULL, NULL };
133 return result;
134}

◆ Error()

static NSError * Error ( OOPListSchemaVerifierErrorCode  errorCode,
BackLinkChain keyPath,
NSString *  format,
  ... 
)
static

Definition at line 1406 of file OOPListSchemaVerifier.m.

1407{
1408 NSError *result = nil;
1409 va_list args;
1410
1411 va_start(args, format);
1412 result = ErrorWithDictionaryAndArguments(errorCode, keyPath, nil, format, args);
1413 va_end(args);
1414
1415 return result;
1416}
static NSError * ErrorWithDictionaryAndArguments(OOPListSchemaVerifierErrorCode errorCode, BackLinkChain *keyPath, NSDictionary *dict, NSString *format, va_list arguments)

References ErrorWithDictionaryAndArguments(), and nil.

+ Here is the call graph for this function:

◆ ErrorFailureAlreadyReported()

static NSError * ErrorFailureAlreadyReported ( void  )
static

Definition at line 1495 of file OOPListSchemaVerifier.m.

1496{
1497 return [NSError errorWithDomain:kOOPListSchemaVerifierErrorDomain code:kPListErrorFailedAndErrorHasBeenReported userInfo:nil];
1498}

Referenced by Verify_Array(), and Verify_Dictionary().

+ Here is the caller graph for this function:

◆ ErrorTypeMismatch()

static NSError * ErrorTypeMismatch ( Class  expectedClass,
NSString *  expectedClassName,
id  actualObject,
BackLinkChain  keyPath 
)
static

Definition at line 1470 of file OOPListSchemaVerifier.m.

1471{
1472 NSDictionary *dict = nil;
1473 NSString *className = nil;
1474
1475 if (expectedClassName == nil) expectedClassName = [expectedClass description];
1476
1477 dict = [NSDictionary dictionaryWithObjectsAndKeys:
1478 expectedClassName, kExpectedClassNameErrorKey,
1479 expectedClass, kExpectedClassErrorKey,
1480 nil];
1481
1482 if (actualObject == nil) className = @"nothing";
1483 else if ([actualObject isKindOfClass:[NSString class]]) className = @"string";
1484 else if ([actualObject isKindOfClass:[NSNumber class]]) className = @"number";
1485 else if ([actualObject isKindOfClass:[NSArray class]]) className = @"array";
1486 else if ([actualObject isKindOfClass:[NSDictionary class]]) className = @"dictionary";
1487 else if ([actualObject isKindOfClass:[NSData class]]) className = @"data";
1488 else if ([actualObject isKindOfClass:[NSDate class]]) className = @"date";
1489 else className = [[actualObject class] description];
1490
1491 return ErrorWithDictionary(kPListErrorTypeMismatch, &keyPath, dict, @"Expected %@, found %@.", expectedClassName, className);
1492}
@ kPListErrorTypeMismatch
static NSError * ErrorWithDictionary(OOPListSchemaVerifierErrorCode errorCode, BackLinkChain *keyPath, NSDictionary *dict, NSString *format,...)

References ErrorWithDictionary(), kPListErrorTypeMismatch, and nil.

Referenced by Verify_Boolean(), Verify_Float(), Verify_FuzzyBoolean(), Verify_Integer(), Verify_PositiveFloat(), Verify_PositiveInteger(), Verify_Quaternion(), and Verify_Vector().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ErrorWithDictionary()

static NSError * ErrorWithDictionary ( OOPListSchemaVerifierErrorCode  errorCode,
BackLinkChain keyPath,
NSDictionary *  dict,
NSString *  format,
  ... 
)
static

Definition at line 1437 of file OOPListSchemaVerifier.m.

1438{
1439 NSError *result = nil;
1440 va_list args;
1441
1442 va_start(args, format);
1443 result = ErrorWithDictionaryAndArguments(errorCode, keyPath, dict, format, args);
1444 va_end(args);
1445
1446 return result;
1447}

References ErrorWithDictionaryAndArguments(), and nil.

Referenced by ErrorTypeMismatch().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ErrorWithDictionaryAndArguments()

static NSError * ErrorWithDictionaryAndArguments ( OOPListSchemaVerifierErrorCode  errorCode,
BackLinkChain keyPath,
NSDictionary *  dict,
NSString *  format,
va_list  arguments 
)
static

Definition at line 1450 of file OOPListSchemaVerifier.m.

1451{
1452 NSString *message = nil;
1453 NSMutableDictionary *userInfo = nil;
1454
1455 message = [[NSString alloc] initWithFormat:format arguments:arguments];
1456
1457 userInfo = [NSMutableDictionary dictionaryWithDictionary:dict];
1458 [userInfo setObject:message forKey:NSLocalizedFailureReasonErrorKey];
1459 if (keyPath != NULL)
1460 {
1461 [userInfo setObject:KeyPathToArray(*keyPath) forKey:kPListKeyPathErrorKey];
1462 }
1463
1464 [message release];
1465
1466 return [NSError errorWithDomain:kOOPListSchemaVerifierErrorDomain code:errorCode userInfo:userInfo];
1467}

References nil.

Referenced by Error(), ErrorWithDictionary(), and ErrorWithProperty().

+ Here is the caller graph for this function:

◆ ErrorWithProperty()

static NSError * ErrorWithProperty ( OOPListSchemaVerifierErrorCode  errorCode,
BackLinkChain keyPath,
NSString *  propKey,
id  propValue,
NSString *  format,
  ... 
)
static

Definition at line 1419 of file OOPListSchemaVerifier.m.

1420{
1421 NSError *result = nil;
1422 va_list args;
1423 NSDictionary *dict = nil;
1424
1425 if (propKey != nil && propValue != nil)
1426 {
1427 dict = [NSDictionary dictionaryWithObject:propValue forKey:propKey];
1428 }
1429 va_start(args, format);
1430 result = ErrorWithDictionaryAndArguments(errorCode, keyPath, dict, format, args);
1431 va_end(args);
1432
1433 return result;
1434}

References ErrorWithDictionaryAndArguments(), and nil.

Referenced by ApplyStringFilter(), StringToSchemaType(), Verify_Dictionary(), Verify_OneOf(), and Verify_String().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ IsFailureAlreadyReportedError()

static BOOL IsFailureAlreadyReportedError ( NSError *  error)
static

Definition at line 1501 of file OOPListSchemaVerifier.m.

1502{
1503 return [[error domain] isEqualToString:kOOPListSchemaVerifierErrorDomain] && [error code] == kPListErrorFailedAndErrorHasBeenReported;
1504}

References kPListErrorFailedAndErrorHasBeenReported.

◆ KeyPathToArray()

static NSArray * KeyPathToArray ( BackLinkChain  keyPath)
static

Definition at line 723 of file OOPListSchemaVerifier.m.

724{
725 NSMutableArray *result = nil;
726 BackLinkChain *curr = NULL;
727
728 result = [NSMutableArray array];
729 for (curr = &keyPath; curr != NULL; curr = curr->link)
730 {
731 if (curr->element != nil) [result insertObject:curr->element atIndex:0];
732 }
733
734 return result;
735}
BackLinkChain * link

References BackLinkChain::element, BackLinkChain::link, and nil.

◆ KeyPathToString()

static NSString * KeyPathToString ( BackLinkChain  keyPath)
static

Definition at line 738 of file OOPListSchemaVerifier.m.

739{
740 return [OOPListSchemaVerifier descriptionForKeyPath:KeyPathToArray(keyPath)];
741}
NSString * descriptionForKeyPath:(NSArray *keyPath)

References OOPListSchemaVerifier::descriptionForKeyPath:.

+ Here is the call graph for this function:

◆ SetForErrorReport()

static NSString * SetForErrorReport ( NSSet *  set)
static

Definition at line 801 of file OOPListSchemaVerifier.m.

802{
803 return ArrayForErrorReport([[set allObjects] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]);
804}
static NSString * ArrayForErrorReport(NSArray *array)

References ArrayForErrorReport().

Referenced by Verify_Dictionary().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ StringForErrorReport()

static NSString * StringForErrorReport ( NSString *  string)
static

Definition at line 744 of file OOPListSchemaVerifier.m.

745{
746 id result = nil;
747
748 if (kMaximumLengthForStringInErrorMessage < [string length])
749 {
750 string = [string substringToIndex:kMaximumLengthForStringInErrorMessage];
751 }
752 result = [NSMutableString stringWithString:string];
753 [result replaceOccurrencesOfString:@"\t" withString:@" " options:0 range:NSMakeRange(0, [string length])];
754 [result replaceOccurrencesOfString:@"\r\n" withString:@" \\ " options:0 range:NSMakeRange(0, [string length])];
755 [result replaceOccurrencesOfString:@"\n" withString:@" \\ " options:0 range:NSMakeRange(0, [string length])];
756 [result replaceOccurrencesOfString:@"\r" withString:@" \\ " options:0 range:NSMakeRange(0, [string length])];
757
758 if (kMaximumLengthForStringInErrorMessage < [result length])
759 {
760 result = [result substringToIndex:kMaximumLengthForStringInErrorMessage - 3];
761 result = [result stringByAppendingString:@"..."];
762 }
763
764 return result;
765}

References kMaximumLengthForStringInErrorMessage, and nil.

Referenced by Verify_Dictionary(), Verify_Enumeration(), and Verify_String().

+ Here is the caller graph for this function:

◆ StringOrArrayForErrorReport()

static NSString * StringOrArrayForErrorReport ( id  value,
NSString *  arrayPrefix 
)
static

Definition at line 807 of file OOPListSchemaVerifier.m.

808{
809 if ([value isKindOfClass:[NSString class]])
810 {
811 return [NSString stringWithFormat:@"\"%@\"", StringForErrorReport(value)];
812 }
813
814 if (arrayPrefix == nil) arrayPrefix = @"";
815 if ([value isKindOfClass:[NSArray class]])
816 {
817 return [arrayPrefix stringByAppendingString:ArrayForErrorReport(value)];
818 }
819 if ([value isKindOfClass:[NSSet class]])
820 {
821 return [arrayPrefix stringByAppendingString:SetForErrorReport(value)];
822 }
823 if (value == nil) return @"(null)";
824 return @"<?>";
825}

References nil.

Referenced by Verify_String().

+ Here is the caller graph for this function:

◆ StringToSchemaType()

static SchemaType StringToSchemaType ( NSString *  string,
NSError **  outError 
)
static

Definition at line 551 of file OOPListSchemaVerifier.m.

552{
553 static NSDictionary *typeMap = nil;
554 SchemaType result;
555
556 if (typeMap == nil)
557 {
558 typeMap =
559 [[NSDictionary dictionaryWithObjectsAndKeys:
560 [NSNumber numberWithUnsignedInt:kTypeString], @"string",
561 [NSNumber numberWithUnsignedInt:kTypeArray], @"array",
562 [NSNumber numberWithUnsignedInt:kTypeDictionary], @"dictionary",
563 [NSNumber numberWithUnsignedInt:kTypeInteger], @"integer",
564 [NSNumber numberWithUnsignedInt:kTypePositiveInteger], @"positiveInteger",
565 [NSNumber numberWithUnsignedInt:kTypeFloat], @"float",
566 [NSNumber numberWithUnsignedInt:kTypePositiveFloat], @"positiveFloat",
567 [NSNumber numberWithUnsignedInt:kTypeOneOf], @"oneOf",
568 [NSNumber numberWithUnsignedInt:kTypeEnumeration], @"enumeration",
569 [NSNumber numberWithUnsignedInt:kTypeBoolean], @"boolean",
570 [NSNumber numberWithUnsignedInt:kTypeFuzzyBoolean], @"fuzzyBoolean",
571 [NSNumber numberWithUnsignedInt:kTypeVector], @"vector",
572 [NSNumber numberWithUnsignedInt:kTypeQuaternion], @"quaternion",
573 [NSNumber numberWithUnsignedInt:kTypeDelegatedType], @"delegatedType",
574 nil
575 ] retain];
576 }
577
578 result = [[typeMap objectForKey:string] unsignedIntValue];
579 if (result == kTypeUnknown && outError != NULL)
580 {
581 if ([string hasPrefix:@"$"])
582 {
583 *outError = ErrorWithProperty(kPListErrorSchemaUnknownType, NULL, kUnknownTypeErrorKey, string, @"Bad schema: unresolved macro reference \"%@\".", string);
584 }
585 else
586 {
587 *outError = ErrorWithProperty(kPListErrorSchemaUnknownType, NULL, kUnknownTypeErrorKey, string, @"Bad schema: unknown type \"%@\".", string);
588 }
589 }
590
591 return result;
592}
@ kPListErrorSchemaUnknownType
NSString *const kUnknownTypeErrorKey

References ErrorWithProperty(), kPListErrorSchemaUnknownType, kTypeUnknown, kUnknownTypeErrorKey, and nil.

+ Here is the call graph for this function:

◆ Verify_Array()

static NSError * Verify_Array ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 903 of file OOPListSchemaVerifier.m.

904{
905 id valueType = nil;
906 BOOL OK = YES, stop = NO;
907 NSUInteger i, count;
908 id subProperty = nil;
909 NSUInteger constraint;
910
911 REQUIRE_TYPE(NSArray, @"array");
912
913 DebugDump(@"%@", @"* array");
914
915 // Apply count bounds.
916 count = [value count];
917 constraint = [params oo_unsignedIntegerForKey:@"minCount" defaultValue:0];
918 if (count < constraint)
919 {
920 return Error(kPListErrorMinimumConstraintNotMet, &keyPath, @"Array has too few members (%u, minimum is %u).", count, constraint);
921 }
922
923 constraint = [params oo_unsignedIntegerForKey:@"maxCount" defaultValue:NSUIntegerMax];
924 if (constraint < count)
925 {
926 return Error(kPListErrorMaximumConstraintNotMet, &keyPath, @"Array has too many members (%u, maximum is %u).", count, constraint);
927 }
928
929 // Test member objects.
930 valueType = [params objectForKey:@"valueType"];
931 if (valueType != nil)
932 {
933 for (i = 0; i != count; ++i)
934 {
935 subProperty = [value objectAtIndex:i];
936
937 if (![verifier verifyPList:rootPList
938 named:name
939 subProperty:subProperty
940 againstSchemaType:valueType
941 atPath:BackLinkIndex(&keyPath, i)
942 tentative:tentative
943 error:NULL
944 stop:&stop])
945 {
946 OK = NO;
947 }
948
949 if ((stop && !tentative) || (tentative && !OK)) break;
950 }
951 }
952
953 *outStop = stop && !tentative;
954
955 if (!OK) return ErrorFailureAlreadyReported();
956 else return nil;
957}
@ kPListErrorMaximumConstraintNotMet
@ kPListErrorMinimumConstraintNotMet
static NSError * ErrorFailureAlreadyReported(void)
#define DebugDump(...)
OOINLINE BackLinkChain BackLinkIndex(BackLinkChain *link, NSUInteger index)
#define REQUIRE_TYPE(CLASSNAME, NAMESTRING)

References BackLinkIndex(), count, DebugDump, Error(), ErrorFailureAlreadyReported(), kPListErrorMaximumConstraintNotMet, kPListErrorMinimumConstraintNotMet, nil, and REQUIRE_TYPE.

+ Here is the call graph for this function:

◆ Verify_Boolean()

static NSError * Verify_Boolean ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 1282 of file OOPListSchemaVerifier.m.

1283{
1284 DebugDump(@"* boolean: %@", value);
1285
1286 // Check basic parseability. If there's inequality here, the default value is being returned.
1287 if (OOBooleanFromObject(value, 0) == OOBooleanFromObject(value, 1)) return nil;
1288 else return ErrorTypeMismatch([NSNumber class], @"boolean", value, keyPath);
1289}
BOOL OOBooleanFromObject(id object, BOOL defaultValue)

References DebugDump, ErrorTypeMismatch(), nil, and OOBooleanFromObject().

+ Here is the call graph for this function:

◆ Verify_DelegatedType()

static NSError * Verify_DelegatedType ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 1323 of file OOPListSchemaVerifier.m.

1324{
1325 id baseType = nil;
1326 NSString *key = nil;
1327 BOOL stop = NO;
1328 NSError *error = nil;
1329
1330 DebugDump(@"* delegated type: %@", [params objectForKey:@"key"]);
1331
1332 baseType = [params objectForKey:@"baseType"];
1333 if (baseType != nil)
1334 {
1335 if (![verifier verifyPList:rootPList
1336 named:name
1337 subProperty:value
1338 againstSchemaType:baseType
1339 atPath:keyPath
1340 tentative:tentative
1341 error:NULL
1342 stop:&stop])
1343 {
1344 *outStop = stop;
1345 return nil;
1346 }
1347 }
1348
1349 key = [params objectForKey:@"key"];
1350 *outStop = ![verifier delegateVerifierWithPropertyList:rootPList
1351 named:name
1352 testProperty:value
1353 atPath:keyPath
1354 againstType:key
1355 error:&error];
1356 return error;
1357}

References DebugDump, OOPListSchemaVerifier::delegateVerifierWithPropertyList:named:testProperty:atPath:againstType:error:, and nil.

+ Here is the call graph for this function:

◆ Verify_Dictionary()

static NSError * Verify_Dictionary ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 960 of file OOPListSchemaVerifier.m.

961{
962 NSDictionary *schema = nil;
963 id valueType = nil,
964 typeSpec = nil;
965 NSEnumerator *keyEnum = nil;
966 NSString *key = nil;
967 id subProperty = nil;
968 BOOL OK = YES, stop = NO, prematureExit = NO;
969 BOOL allowOthers;
970 NSMutableSet *requiredKeys = nil;
971 NSArray *requiredKeyList = nil;
972 NSUInteger count, constraint;
973
974 REQUIRE_TYPE(NSDictionary, @"dictionary");
975
976 DebugDump(@"%@", @"* dictionary");
977
978 // Apply count bounds.
979 count = [value count];
980 constraint = [params oo_unsignedIntegerForKey:@"minCount" defaultValue:0];
981 if (count < constraint)
982 {
983 return Error(kPListErrorMinimumConstraintNotMet, &keyPath, @"Dictionary has too few pairs (%u, minimum is %u).", count, constraint);
984 }
985 constraint = [params oo_unsignedIntegerForKey:@"maxCount" defaultValue:NSUIntegerMax];
986 if (constraint < count)
987 {
988 return Error(kPListErrorMaximumConstraintNotMet, &keyPath, @"Dictionary has too manu pairs (%u, maximum is %u).", count, constraint);
989 }
990
991 // Get schema.
992 schema = [params oo_dictionaryForKey:@"schema"];
993 valueType = [params objectForKey:@"valueType"];
994 allowOthers = [params oo_boolForKey:@"allowOthers" defaultValue:YES];
995 requiredKeyList = [params oo_arrayForKey:@"requiredKeys"];
996
997 // If these conditions are met, all members must pass:
998 if (schema == nil && valueType == nil && requiredKeyList == nil && allowOthers) return nil;
999
1000 if (requiredKeyList != nil)
1001 {
1002 requiredKeys = [NSMutableSet setWithArray:requiredKeyList];
1003 }
1004
1006
1007 // Test member objects.
1008 for (keyEnum = [value keyEnumerator]; (key = [keyEnum nextObject]) && !stop; )
1009 {
1010 subProperty = [(NSDictionary *)value objectForKey:key];
1011 typeSpec = [schema objectForKey:key];
1012 if (typeSpec == nil) typeSpec = valueType;
1013
1014 DebugDump(@"- \"%@\"", key);
1016
1017 if (typeSpec != nil)
1018 {
1019 if (![verifier verifyPList:rootPList
1020 named:name
1021 subProperty:subProperty
1022 againstSchemaType:typeSpec
1023 atPath:BackLink(&keyPath, key)
1024 tentative:tentative
1025 error:NULL
1026 stop:&stop])
1027 {
1028 OK = NO;
1029 }
1030 }
1031 else if (!allowOthers && ![requiredKeys containsObject:key] && [schema objectForKey:key] == nil)
1032 {
1033 // Report error now rather than returning it, since there may be several unknown keys.
1034 if (!tentative)
1035 {
1036 NSError *error = ErrorWithProperty(kPListErrorDictionaryUnknownKey, &keyPath, kUnknownKeyErrorKey, key, @"Unpermitted key \"%@\" in dictionary.", StringForErrorReport(key));
1037 stop = ![verifier delegateVerifierWithPropertyList:rootPList
1038 named:name
1039 failedForProperty:value
1040 withError:error
1041 expectedType:params];
1042 }
1043 OK = NO;
1044 }
1045
1047
1048 [requiredKeys removeObject:key];
1049
1050 if ((stop && !tentative) || (tentative && !OK))
1051 {
1052 prematureExit = YES;
1053 break;
1054 }
1055 }
1056
1058
1059 // Check that all required keys were present.
1060 if (!prematureExit && [requiredKeys count] != 0)
1061 {
1062 return ErrorWithProperty(kPListErrorDictionaryMissingRequiredKeys, &keyPath, kMissingRequiredKeysErrorKey, requiredKeys, @"Required keys %@ missing from dictionary.", SetForErrorReport(requiredKeys));
1063 }
1064
1065 *outStop = stop && !tentative;
1066
1067 if (!OK) return ErrorFailureAlreadyReported();
1068 else return nil;
1069}
@ kPListErrorDictionaryMissingRequiredKeys
@ kPListErrorDictionaryUnknownKey
NSString *const kMissingRequiredKeysErrorKey
static NSString * SetForErrorReport(NSSet *set)
static NSString * StringForErrorReport(NSString *string)
OOINLINE BackLinkChain BackLink(BackLinkChain *link, id element)
#define DebugDumpIndent()
NSString *const kUnknownKeyErrorKey
#define DebugDumpOutdent()

References BackLink(), count, DebugDump, DebugDumpIndent, DebugDumpOutdent, OOPListSchemaVerifier::delegateVerifierWithPropertyList:named:failedForProperty:withError:expectedType:, Error(), ErrorFailureAlreadyReported(), ErrorWithProperty(), kMissingRequiredKeysErrorKey, kPListErrorDictionaryMissingRequiredKeys, kPListErrorDictionaryUnknownKey, kPListErrorMaximumConstraintNotMet, kPListErrorMinimumConstraintNotMet, kUnknownKeyErrorKey, nil, REQUIRE_TYPE, SetForErrorReport(), and StringForErrorReport().

+ Here is the call graph for this function:

◆ Verify_Enumeration()

static NSError * Verify_Enumeration ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 1254 of file OOPListSchemaVerifier.m.

1255{
1256 NSArray *values = nil;
1257 NSString *filteredString = nil;
1258 NSError *error = nil;
1259
1260 DebugDump(@"%@", @"* enumeration");
1261
1262 REQUIRE_TYPE(NSString, @"string");
1263
1264 values = [params oo_arrayForKey:@"values"];
1265 DebugDump(@" - \"%@\" in %@", StringForErrorReport(value), ArrayForErrorReport(values));
1266
1267 if (values == nil)
1268 {
1269 *outStop = YES;
1270 return Error(kPListErrorSchemaNoEnumerationValues, &keyPath, @"Bad schema: no options specified for oneOf type.");
1271 }
1272
1273 filteredString = ApplyStringFilter(value, [params objectForKey:@"filter"], keyPath, &error);
1274 if (filteredString == nil) return error;
1275
1276 if ([values containsObject:filteredString]) return nil;
1277
1278 return Error(kPListErrorEnumerationBadValue, &keyPath, @"Value \"%@\" not recognized, should be one of %@.", StringForErrorReport(value), ArrayForErrorReport(values));
1279}
@ kPListErrorSchemaNoEnumerationValues
@ kPListErrorEnumerationBadValue
static NSString * ApplyStringFilter(NSString *string, id filterSpec, BackLinkChain keyPath, NSError **outError)

References ApplyStringFilter(), ArrayForErrorReport(), DebugDump, Error(), kPListErrorEnumerationBadValue, kPListErrorSchemaNoEnumerationValues, nil, REQUIRE_TYPE, and StringForErrorReport().

+ Here is the call graph for this function:

◆ Verify_Float()

static NSError * Verify_Float ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 1136 of file OOPListSchemaVerifier.m.

1137{
1138 double numericValue;
1139 double constraint;
1140
1141 numericValue = OODoubleFromObject(value, 0);
1142
1143 DebugDump(@"* float: %g", numericValue);
1144
1145 // Check basic parseability. If there's inequality here, the default value is being returned.
1146 if (numericValue != OODoubleFromObject(value, 1))
1147 {
1148 return ErrorTypeMismatch([NSNumber class], @"number", value, keyPath);
1149 }
1150
1151 // Check constraints.
1152 constraint = [params oo_doubleForKey:@"minimum" defaultValue:-INFINITY];
1153 if (numericValue < constraint)
1154 {
1155 return Error(kPListErrorMinimumConstraintNotMet, &keyPath, @"Number is too small (%g, minimum is %g).", numericValue, constraint);
1156 }
1157
1158 constraint = [params oo_doubleForKey:@"maximum" defaultValue:INFINITY];
1159 if (constraint < numericValue)
1160 {
1161 return Error(kPListErrorMaximumConstraintNotMet, &keyPath, @"Number is too large (%g, maximum is %g).", numericValue, constraint);
1162 }
1163
1164 return nil;
1165}
double OODoubleFromObject(id object, double defaultValue)

References DebugDump, Error(), ErrorTypeMismatch(), kPListErrorMaximumConstraintNotMet, kPListErrorMinimumConstraintNotMet, nil, and OODoubleFromObject().

+ Here is the call graph for this function:

◆ Verify_FuzzyBoolean()

static NSError * Verify_FuzzyBoolean ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 1292 of file OOPListSchemaVerifier.m.

1293{
1294 DebugDump(@"* fuzzy boolean: %@", value);
1295
1296 // Check basic parseability. If there's inequality here, the default value is being returned.
1297 if (OODoubleFromObject(value, 0) == OODoubleFromObject(value, 1)) return nil;
1298 else if (OOBooleanFromObject(value, 0) == OOBooleanFromObject(value, 1)) return nil;
1299 else return ErrorTypeMismatch([NSNumber class], @"fuzzy boolean", value, keyPath);
1300}

References DebugDump, ErrorTypeMismatch(), nil, OOBooleanFromObject(), and OODoubleFromObject().

+ Here is the call graph for this function:

◆ Verify_Integer()

static NSError * Verify_Integer ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 1072 of file OOPListSchemaVerifier.m.

1073{
1074 long long numericValue;
1075 long long constraint;
1076
1077 numericValue = OOLongLongFromObject(value, 0);
1078
1079 DebugDump(@"* integer: %lli", numericValue);
1080
1081 // Check basic parseability. If there's inequality here, the default value is being returned.
1082 if (numericValue != OOLongLongFromObject(value, 1))
1083 {
1084 return ErrorTypeMismatch([NSNumber class], @"integer", value, keyPath);
1085 }
1086
1087 // Check constraints.
1088 constraint = [params oo_longLongForKey:@"minimum" defaultValue:LLONG_MIN];
1089 if (numericValue < constraint)
1090 {
1091 return Error(kPListErrorMinimumConstraintNotMet, &keyPath, @"Number is too small (%lli, minimum is %lli).", numericValue, constraint);
1092 }
1093
1094 constraint = [params oo_longLongForKey:@"maximum" defaultValue:LLONG_MAX];
1095 if (constraint < numericValue)
1096 {
1097 return Error(kPListErrorMaximumConstraintNotMet, &keyPath, @"Number is too large (%lli, maximum is %lli).", numericValue, constraint);
1098 }
1099
1100 return nil;
1101}
long long OOLongLongFromObject(id object, long long defaultValue)

References DebugDump, Error(), ErrorTypeMismatch(), kPListErrorMaximumConstraintNotMet, kPListErrorMinimumConstraintNotMet, nil, and OOLongLongFromObject().

+ Here is the call graph for this function:

◆ Verify_OneOf()

static NSError * Verify_OneOf ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 1205 of file OOPListSchemaVerifier.m.

1206{
1207 NSArray *options = nil;
1208 BOOL OK = NO, stop = NO;
1209 id option = nil;
1210 NSError *error;
1211 NSMutableDictionary *errors = nil;
1212
1213 DebugDump(@"%@", @"* oneOf");
1214
1215 options = [params oo_arrayForKey:@"options"];
1216 if (options == nil)
1217 {
1218 *outStop = YES;
1219 return Error(kPListErrorSchemaNoOneOfOptions, &keyPath, @"Bad schema: no options specified for oneOf type.");
1220 }
1221
1222 errors = [[NSMutableDictionary alloc] initWithCapacity:[options count]];
1223
1224 foreach (option, options)
1225 {
1226 if ([verifier verifyPList:rootPList
1227 named:name
1228 subProperty:value
1229 againstSchemaType:option
1230 atPath:keyPath
1231 tentative:YES
1232 error:&error
1233 stop:&stop])
1234 {
1235 DebugDump(@"%@", @"> Match.");
1236 OK = YES;
1237 break;
1238 }
1239 [errors setObject:error forKey:option];
1240 }
1241
1242 if (!OK)
1243 {
1244 DebugDump(@"%@", @"! No match.");
1245 return ErrorWithProperty(kPListErrorOneOfNoMatch, &keyPath, kErrorsByOptionErrorKey, [errors autorelease], @"No matching type rule could be found.");
1246 }
1247
1248 // Ignore stop in tentatives.
1249 [errors release];
1250 return nil;
1251}
@ kPListErrorSchemaNoOneOfOptions
@ kPListErrorOneOfNoMatch
NSString *const kErrorsByOptionErrorKey

References DebugDump, Error(), ErrorWithProperty(), kErrorsByOptionErrorKey, kPListErrorOneOfNoMatch, kPListErrorSchemaNoOneOfOptions, and nil.

+ Here is the call graph for this function:

◆ Verify_PositiveFloat()

static NSError * Verify_PositiveFloat ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 1168 of file OOPListSchemaVerifier.m.

1169{
1170 double numericValue;
1171 double constraint;
1172
1173 numericValue = OODoubleFromObject(value, 0);
1174
1175 DebugDump(@"* positive float: %g", numericValue);
1176
1177 // Check basic parseability. If there's inequality here, the default value is being returned.
1178 if (numericValue != OODoubleFromObject(value, 1))
1179 {
1180 return ErrorTypeMismatch([NSNumber class], @"positive number", value, keyPath);
1181 }
1182
1183 if (numericValue < 0)
1184 {
1185 return Error(kPListErrorNumberIsNegative, &keyPath, @"Expected non-negative number, found %g.", numericValue);
1186 }
1187
1188 // Check constraints.
1189 constraint = [params oo_doubleForKey:@"minimum" defaultValue:0];
1190 if (numericValue < constraint)
1191 {
1192 return Error(kPListErrorMinimumConstraintNotMet, &keyPath, @"Number is too small (%g, minimum is %g).", numericValue, constraint);
1193 }
1194
1195 constraint = [params oo_doubleForKey:@"maximum" defaultValue:INFINITY];
1196 if (constraint < numericValue)
1197 {
1198 return Error(kPListErrorMaximumConstraintNotMet, &keyPath, @"Number is too large (%g, maximum is %g).", numericValue, constraint);
1199 }
1200
1201 return nil;
1202}
@ kPListErrorNumberIsNegative

References DebugDump, Error(), ErrorTypeMismatch(), kPListErrorMaximumConstraintNotMet, kPListErrorMinimumConstraintNotMet, kPListErrorNumberIsNegative, nil, and OODoubleFromObject().

+ Here is the call graph for this function:

◆ Verify_PositiveInteger()

static NSError * Verify_PositiveInteger ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 1104 of file OOPListSchemaVerifier.m.

1105{
1106 unsigned long long numericValue;
1107 unsigned long long constraint;
1108
1109 numericValue = OOUnsignedLongLongFromObject(value, 0);
1110
1111 DebugDump(@"* positive integer: %llu", numericValue);
1112
1113 // Check basic parseability. If there's inequality here, the default value is being returned.
1114 if (numericValue != OOUnsignedLongLongFromObject(value, 1))
1115 {
1116 return ErrorTypeMismatch([NSNumber class], @"positive integer", value, keyPath);
1117 }
1118
1119 // Check constraints.
1120 constraint = [params oo_unsignedLongLongForKey:@"minimum" defaultValue:0];
1121 if (numericValue < constraint)
1122 {
1123 return Error(kPListErrorMinimumConstraintNotMet, &keyPath, @"Number is too small (%llu, minimum is %llu).", numericValue, constraint);
1124 }
1125
1126 constraint = [params oo_unsignedLongLongForKey:@"maximum" defaultValue:ULLONG_MAX];
1127 if (constraint < numericValue)
1128 {
1129 return Error(kPListErrorMaximumConstraintNotMet, &keyPath, @"Number is too large (%llu, maximum is %llu).", numericValue, constraint);
1130 }
1131
1132 return nil;
1133}
unsigned long long OOUnsignedLongLongFromObject(id object, unsigned long long defaultValue)

References DebugDump, Error(), ErrorTypeMismatch(), kPListErrorMaximumConstraintNotMet, kPListErrorMinimumConstraintNotMet, nil, and OOUnsignedLongLongFromObject().

+ Here is the call graph for this function:

◆ VERIFY_PROTO() [1/14]

VERIFY_PROTO ( Array  )

◆ VERIFY_PROTO() [2/14]

VERIFY_PROTO ( Boolean  )

◆ VERIFY_PROTO() [3/14]

VERIFY_PROTO ( DelegatedType  )

◆ VERIFY_PROTO() [4/14]

VERIFY_PROTO ( Dictionary  )

◆ VERIFY_PROTO() [5/14]

VERIFY_PROTO ( Enumeration  )

◆ VERIFY_PROTO() [6/14]

VERIFY_PROTO ( Float  )

◆ VERIFY_PROTO() [7/14]

VERIFY_PROTO ( FuzzyBoolean  )

◆ VERIFY_PROTO() [8/14]

VERIFY_PROTO ( Integer  )

◆ VERIFY_PROTO() [9/14]

VERIFY_PROTO ( OneOf  )

◆ VERIFY_PROTO() [10/14]

VERIFY_PROTO ( PositiveFloat  )

◆ VERIFY_PROTO() [11/14]

VERIFY_PROTO ( PositiveInteger  )

◆ VERIFY_PROTO() [12/14]

VERIFY_PROTO ( Quaternion  )

◆ VERIFY_PROTO() [13/14]

VERIFY_PROTO ( String  )

◆ VERIFY_PROTO() [14/14]

VERIFY_PROTO ( Vector  )

◆ Verify_Quaternion()

static NSError * Verify_Quaternion ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 1313 of file OOPListSchemaVerifier.m.

1314{
1315 DebugDump(@"* quaternion: %@", value);
1316
1317 // Check basic parseability. If there's inequality here, the default value is being returned.
1318 if (quaternion_equal(OOQuaternionFromObject(value, kZeroQuaternion), OOQuaternionFromObject(value, kIdentityQuaternion))) return nil;
1319 else return ErrorTypeMismatch(Nil, @"quaternion", value, keyPath);
1320}
Quaternion OOQuaternionFromObject(id object, Quaternion defaultValue)
const Quaternion kIdentityQuaternion
const Quaternion kZeroQuaternion

References DebugDump, ErrorTypeMismatch(), kIdentityQuaternion, kZeroQuaternion, nil, and OOQuaternionFromObject().

+ Here is the call graph for this function:

◆ Verify_String()

static NSError * Verify_String ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 837 of file OOPListSchemaVerifier.m.

838{
839 NSString *filteredString = nil;
840 id testValue = nil;
841 NSUInteger length;
842 NSUInteger lengthConstraint;
843 NSError *error = nil;
844
845 REQUIRE_TYPE(NSString, @"string");
846
847 DebugDump(@"* string: \"%@\"", StringForErrorReport(value));
848
849 // Apply filters
850 filteredString = ApplyStringFilter(value, [params objectForKey:@"filter"], keyPath, &error);
851 if (filteredString == nil) return error;
852
853 // Apply substring requirements
854 testValue = [params objectForKey:@"requiredPrefix"];
855 if (testValue != nil)
856 {
857 if (!ApplyStringTest(filteredString, testValue, @selector(hasPrefix:), @"prefix", keyPath, &error))
858 {
859 if (error == nil) error = ErrorWithProperty(kPListErrorStringPrefixMissing, &keyPath, kMissingSubStringErrorKey, testValue, @"String \"%@\" does not have required %@ %@.", StringForErrorReport(value), @"prefix", StringOrArrayForErrorReport(testValue, @"in "));
860 return error;
861 }
862 }
863
864 testValue = [params objectForKey:@"requiredSuffix"];
865 if (testValue != nil)
866 {
867 if (!ApplyStringTest(filteredString, testValue, @selector(hasSuffix:), @"suffix", keyPath, &error))
868 {
869 if (error == nil) error = ErrorWithProperty(kPListErrorStringSuffixMissing, &keyPath, kMissingSubStringErrorKey, testValue, @"String \"%@\" does not have required %@ %@.", StringForErrorReport(value), @"suffix", StringOrArrayForErrorReport(testValue, @"in "));
870 return error;
871 }
872 }
873
874 testValue = [params objectForKey:@"requiredSubString"];
875 if (testValue != nil)
876 {
877 if (!ApplyStringTest(filteredString, testValue, @selector(ooPListVerifierHasSubString:), @"substring", keyPath, &error))
878 {
879 if (error == nil) error = ErrorWithProperty(kPListErrorStringSubstringMissing, &keyPath, kMissingSubStringErrorKey, testValue, @"String \"%@\" does not have required %@ %@.", StringForErrorReport(value), @"substring", StringOrArrayForErrorReport(testValue, @"in "));
880 return error;
881 }
882 }
883
884 // Apply length bounds.
885 length = [filteredString length];
886 lengthConstraint = [params oo_unsignedIntegerForKey:@"minLength"];
887 if (length < lengthConstraint)
888 {
889 return Error(kPListErrorMinimumConstraintNotMet, &keyPath, @"String \"%@\" is too short (%u bytes, minimum is %u).", StringForErrorReport(filteredString), length, lengthConstraint);
890 }
891
892 lengthConstraint = [params oo_unsignedIntegerForKey:@"maxLength" defaultValue:NSUIntegerMax];
893 if (lengthConstraint < length)
894 {
895 return Error(kPListErrorMaximumConstraintNotMet, &keyPath, @"String \"%@\" is too long (%u bytes, maximum is %u).", StringForErrorReport(filteredString), length, lengthConstraint);
896 }
897
898 // All tests passed.
899 return nil;
900}
@ kPListErrorStringSubstringMissing
@ kPListErrorStringSuffixMissing
@ kPListErrorStringPrefixMissing
static BOOL ApplyStringTest(NSString *string, id test, SEL testSelector, NSString *testDescription, BackLinkChain keyPath, NSError **outError)
static NSString * StringOrArrayForErrorReport(id value, NSString *arrayPrefix)
NSString *const kMissingSubStringErrorKey

References ApplyStringFilter(), ApplyStringTest(), DebugDump, Error(), ErrorWithProperty(), kMissingSubStringErrorKey, kPListErrorMaximumConstraintNotMet, kPListErrorMinimumConstraintNotMet, kPListErrorStringPrefixMissing, kPListErrorStringSubstringMissing, kPListErrorStringSuffixMissing, nil, REQUIRE_TYPE, StringForErrorReport(), and StringOrArrayForErrorReport().

+ Here is the call graph for this function:

◆ Verify_Vector()

static NSError * Verify_Vector ( OOPListSchemaVerifier verifier,
id  value,
NSDictionary *  params,
id  rootPList,
NSString *  name,
BackLinkChain  keyPath,
BOOL  tentative,
BOOL *  outStop 
)
static

Definition at line 1303 of file OOPListSchemaVerifier.m.

1304{
1305 DebugDump(@"* vector: %@", value);
1306
1307 // Check basic parseability. If there's inequality here, the default value is being returned.
1308 if (vector_equal(OOVectorFromObject(value, kZeroVector), OOVectorFromObject(value, kBasisXVector))) return nil;
1309 else return ErrorTypeMismatch(Nil, @"vector", value, keyPath);
1310}
Vector OOVectorFromObject(id object, Vector defaultValue)
const Vector kZeroVector
Definition OOVector.m:28
const Vector kBasisXVector
Definition OOVector.m:29

References DebugDump, ErrorTypeMismatch(), kBasisXVector, kZeroVector, nil, and OOVectorFromObject().

+ Here is the call graph for this function:

Variable Documentation

◆ kErrorsByOptionErrorKey

NSString* const kErrorsByOptionErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier errors by option"

Definition at line 85 of file OOPListSchemaVerifier.m.

Referenced by Verify_OneOf().

◆ kExpectedClassErrorKey

NSString* const kExpectedClassErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier expected class"

Definition at line 79 of file OOPListSchemaVerifier.m.

◆ kExpectedClassNameErrorKey

NSString* const kExpectedClassNameErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier expected class name"

Definition at line 80 of file OOPListSchemaVerifier.m.

◆ kMissingRequiredKeysErrorKey

NSString* const kMissingRequiredKeysErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier missing required keys"

Definition at line 82 of file OOPListSchemaVerifier.m.

Referenced by Verify_Dictionary().

◆ kMissingSubStringErrorKey

NSString* const kMissingSubStringErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier missing substring"

Definition at line 83 of file OOPListSchemaVerifier.m.

Referenced by Verify_String().

◆ kOOPListSchemaVerifierErrorDomain

NSString* const kOOPListSchemaVerifierErrorDomain = @"org.aegidian.oolite.OOPListSchemaVerifier.ErrorDomain"

Definition at line 74 of file OOPListSchemaVerifier.m.

◆ kPListKeyPathErrorKey

NSString* const kPListKeyPathErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier plist key path"

Definition at line 76 of file OOPListSchemaVerifier.m.

◆ kSchemaKeyPathErrorKey

NSString* const kSchemaKeyPathErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier schema key path"

Definition at line 77 of file OOPListSchemaVerifier.m.

◆ kUndefinedMacroErrorKey

NSString* const kUndefinedMacroErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier undefined macro"

Definition at line 88 of file OOPListSchemaVerifier.m.

◆ kUnknownKeyErrorKey

NSString* const kUnknownKeyErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier unknown key"

Definition at line 81 of file OOPListSchemaVerifier.m.

Referenced by Verify_Dictionary().

◆ kUnknownTypeErrorKey

NSString* const kUnknownTypeErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier unknown type"

Definition at line 87 of file OOPListSchemaVerifier.m.

Referenced by StringToSchemaType().

◆ kUnnownFilterErrorKey

NSString* const kUnnownFilterErrorKey = @"org.aegidian.oolite.OOPListSchemaVerifier unknown filter"

Definition at line 84 of file OOPListSchemaVerifier.m.

Referenced by ApplyStringFilter().

◆ sDebugDump

BOOL sDebugDump = NO
static

Definition at line 58 of file OOPListSchemaVerifier.m.