Line data Source code
1 0 : /* 2 : 3 : OOPListSchemaVerifier.h 4 : 5 : Utility class to verify the structure of a property list based on a schema 6 : (which is itself a property list). 7 : 8 : 9 : Copyright (C) 2007-2013 Jens Ayton 10 : 11 : Permission is hereby granted, free of charge, to any person obtaining a copy 12 : of this software and associated documentation files (the "Software"), to deal 13 : in the Software without restriction, including without limitation the rights 14 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 : copies of the Software, and to permit persons to whom the Software is 16 : furnished to do so, subject to the following conditions: 17 : 18 : The above copyright notice and this permission notice shall be included in all 19 : copies or substantial portions of the Software. 20 : 21 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 : SOFTWARE. 28 : 29 : */ 30 : 31 : #import "OOOXPVerifier.h" 32 : 33 : #if OO_OXP_VERIFIER_ENABLED 34 : 35 : #import <Foundation/Foundation.h> 36 : #import "OOFunctionAttributes.h" 37 : 38 : 39 0 : @interface OOPListSchemaVerifier: NSObject 40 : { 41 : @private 42 0 : NSDictionary *_schema; 43 0 : NSDictionary *_definitions; 44 : 45 0 : id _delegate; 46 0 : uint32_t _badDelegateWarning: 1; 47 : } 48 : 49 0 : + (instancetype)verifierWithSchema:(NSDictionary *)schema; 50 0 : - (id)initWithSchema:(NSDictionary *)schema; 51 : 52 0 : - (void)setDelegate:(id)delegate; 53 0 : - (id)delegate; 54 : 55 0 : - (BOOL)verifyPropertyList:(id)plist named:(NSString *)name; 56 : 57 : /* Convert a key path (such as provided to the delegate method 58 : -verifier:withPropertyList:failedForProperty:atPath:expectedType:) to a 59 : human-readable string. Strings are separated by dots and numbers are give 60 : brackets. For instance, the key path ( "adder-player", "custom_views", 0, 61 : "view_description" ) is transfomed to 62 : "adder-player.custom_views[0].view_description". 63 : */ 64 0 : + (NSString *)descriptionForKeyPath:(NSArray *)keyPath; 65 : 66 : @end 67 : 68 : 69 : @interface NSObject (OOPListSchemaVerifierDelegate) 70 : 71 : // Handle "delegated types". Return YES for valid, NO for invalid. 72 0 : - (BOOL)verifier:(OOPListSchemaVerifier *)verifier 73 : withPropertyList:(id)rootPList 74 : named:(NSString *)name 75 : testProperty:(id)subPList 76 : atPath:(NSArray *)keyPath 77 : againstType:(NSString *)typeKey 78 : error:(NSError **)outError; 79 : 80 : /* Method notifying of verification failure. 81 : Return YES to continue verifying, NO to stop. 82 : */ 83 0 : - (BOOL)verifier:(OOPListSchemaVerifier *)verifier 84 : withPropertyList:(id)rootPList 85 : named:(NSString *)name 86 : failedForProperty:(id)subPList 87 : withError:(NSError *)error 88 : expectedType:(NSDictionary *)localSchema; 89 : 90 : @end 91 : 92 : 93 : // NSError domain and codes used to report schema verifier errors. 94 0 : extern NSString * const kOOPListSchemaVerifierErrorDomain; 95 : 96 0 : extern NSString * const kPListKeyPathErrorKey; // Array specifying key path in plist. 97 0 : extern NSString * const kSchemaKeyPathErrorKey; // Array specifying key path in schema. 98 : 99 0 : extern NSString * const kExpectedClassErrorKey; // Expected class. Nil for vector and quaternion. 100 0 : extern NSString * const kExpectedClassNameErrorKey; // String describing expected class. May be more specific (for instance, "boolean" or "positive integer" for NSNumber). 101 0 : extern NSString * const kUnknownKeyErrorKey; // Unallowed key found in dictionary. 102 0 : extern NSString * const kMissingRequiredKeysErrorKey; // Set of required keys not present in dictionary 103 0 : extern NSString * const kMissingSubStringErrorKey; // String or array of strings not found for kPListErrorStringPrefixMissing/kPListErrorStringSuffixMissing/kPListErrorStringSubstringMissing. 104 0 : extern NSString * const kUnnownFilterErrorKey; // Unrecognized filter specifier for kPListErrorSchemaUnknownFilter. Not specified if filter is not a string. 105 0 : extern NSString * const kErrorsByOptionErrorKey; // Dictionary of errors for oneOf types. 106 : 107 0 : extern NSString * const kUnknownTypeErrorKey; // Set for kPListErrorSchemaUnknownType. 108 0 : extern NSString * const kUndefinedMacroErrorKey; // Set for kPListErrorSchemaUndefiniedMacroReference. 109 : 110 : 111 : // All plist verifier errors have a short error description in their -localizedFailureReason. 112 : 113 0 : typedef enum 114 : { 115 : kPListErrorNone, 116 : kPListErrorInternal, // PList verifier did something dumb. 117 : 118 : // Verification errors -- property list doesn't match schema. 119 : kPListErrorTypeMismatch, // Basic type mismatch -- array instead of number, for instance. 120 : 121 : kPListErrorMinimumConstraintNotMet, // minimum/minCount/minLength constraint violated 122 : kPListErrorMaximumConstraintNotMet, // maximum/maxCount/maxLength constraint violated 123 : kPListErrorNumberIsNegative, // Negative number in positiveFloat. 124 : 125 : kPListErrorStringPrefixMissing, // String does not match requiredPrefix rule. kMissingSubStringErrorKey is set. 126 : kPListErrorStringSuffixMissing, // String does not match requiredSuffix rule. kMissingSubStringErrorKey is set. 127 : kPListErrorStringSubstringMissing, // String does not match requiredSuffix rule. kMissingSubStringErrorKey is set. 128 : 129 : kPListErrorDictionaryUnknownKey, // Unknown key for dictionary with allowOthers = NO. 130 : kPListErrorDictionaryMissingRequiredKeys, // requiredKeys rule is not fulfilled. The missing keys are listed in kMissingRequiredKeysErrorKey. 131 : 132 : kPListErrorEnumerationBadValue, // Enumeration type contains string that isn't in permitted set. 133 : 134 : kPListErrorOneOfNoMatch, // No match for oneOf type. kErrorsByOptionErrorKey is set to a dictionary of type specifiers to errors. Note that the keys in this dictionary can be either strings or dictionaries. 135 : 136 : kPListDelegatedTypeError, // Delegate's verification method failed. If it returned an error, this will be in NSUnderlyingErrorKey. 137 : 138 : // Schema errors -- schema is broken. 139 : kPListErrorStartOfSchemaErrors = 100, 140 : 141 : kPListErrorSchemaBadTypeSpecifier, // Bad type specifier - specifier is not a string or a dictionary, or is a dictionary with no type key. kUndefinedMacroErrorKey is set. 142 : kPListErrorSchemaUndefiniedMacroReference, // Reference to $macro not found in $definitions. 143 : kPListErrorSchemaUnknownType, // Unknown type specified in type specifier. kUnknownTypeErrorKey is set. 144 : kPListErrorSchemaNoOneOfOptions, // OneOf clause has no options array. 145 : kPListErrorSchemaNoEnumerationValues, // Enumeration clause has no values array. 146 : kPListErrorSchemaUnknownFilter, // Bad value for string/enumeration filter specifier. 147 : kPListErrorSchemaBadComparator, // String comparision requirement value (requiredPrefix etc.) is not a string. 148 : 149 : kPListErrorLastErrorCode 150 : } OOPListSchemaVerifierErrorCode; 151 : 152 : 153 0 : OOINLINE BOOL OOPlistErrorIsSchemaError(OOPListSchemaVerifierErrorCode error) 154 : { 155 : return kPListErrorStartOfSchemaErrors < error && error < kPListErrorLastErrorCode; 156 : } 157 : 158 : 159 : @interface NSError (OOPListSchemaVerifierConveniences) 160 : 161 0 : - (NSArray *)plistKeyPath; 162 0 : - (NSString *)plistKeyPathDescription; // Result of calling +[OOPListSchemaVerifier descriptionForKeyPath:] on kPListKeyPathErrorKey. 163 : 164 0 : - (NSSet *)missingRequiredKeys; 165 : 166 0 : - (Class)expectedClass; 167 0 : - (NSString *)expectedClassName; 168 : 169 : @end 170 : 171 : #endif // OO_OXP_VERIFIER_ENABLED