Permalink
Browse files

Producing better error messages (or rather userInfo) on scanning.

  • Loading branch information...
1 parent cfddf3d commit 04a511ba0f349c7f86332496822e28f74ec6475e @schwa schwa committed Aug 20, 2010
@@ -34,4 +34,7 @@
- (BOOL)scanCStyleComment:(NSString **)outComment;
- (BOOL)scanCPlusPlusStyleComment:(NSString **)outComment;
+- (NSUInteger)lineOfScanLocation;
+- (NSDictionary *)userInfoForScanLocation;
+
@end
@@ -77,4 +77,50 @@ - (BOOL)scanCPlusPlusStyleComment:(NSString **)outComment
}
}
+- (NSUInteger)lineOfScanLocation
+{
+NSUInteger theLine = 0;
+for (const u_int8_t *C = start; C < current; ++C)
+ {
+ if (*C == '\n' || *C == '\r')
+ {
+ ++theLine;
+ }
+ }
+return(theLine);
+}
+
+- (NSDictionary *)userInfoForScanLocation
+{
+NSUInteger theLine = 0;
+const u_int8_t *theLineStart = start;
+for (const u_int8_t *C = start; C < current; ++C)
+ {
+ if (*C == '\n' || *C == '\r')
+ {
+ theLineStart = C - 1;
+ ++theLine;
+ }
+ }
+
+NSUInteger theCharacter = current - theLineStart;
+
+NSRange theStartRange = NSIntersectionRange((NSRange){ .location = MAX((NSInteger)self.scanLocation - 20, 0), .length = 20 + (NSInteger)self.scanLocation - 20 }, (NSRange){ .location = 0, .length = self.data.length });
+NSRange theEndRange = NSIntersectionRange((NSRange){ .location = self.scanLocation, .length = 20 }, (NSRange){ .location = 0, .length = self.data.length });
+
+
+NSString *theSnippet = [NSString stringWithFormat:@"%@!HERE>!%@",
+ [[[NSString alloc] initWithData:[self.data subdataWithRange:theStartRange] encoding:NSUTF8StringEncoding] autorelease],
+ [[[NSString alloc] initWithData:[self.data subdataWithRange:theEndRange] encoding:NSUTF8StringEncoding] autorelease]
+ ];
+
+NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithUnsignedInteger:theLine], @"line",
+ [NSNumber numberWithUnsignedInteger:theCharacter], @"character",
+ [NSNumber numberWithUnsignedInteger:self.scanLocation], @"location",
+ theSnippet, @"snippet",
+ NULL];
+return(theUserInfo);
+}
+
@end
View
@@ -180,9 +180,10 @@ - (BOOL)scanJSONDictionary:(NSDictionary **)outDictionary error:(NSError **)outE
{
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan dictionary. Dictionary that does not start with '{' character.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-1 userInfo:theUserInfo];
}
return(NO);
@@ -203,9 +204,10 @@ - (BOOL)scanJSONDictionary:(NSDictionary **)outDictionary error:(NSError **)outE
[self setScanLocation:theScanLocation];
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan dictionary. Failed to scan a key.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-2 userInfo:theUserInfo];
}
[theDictionary release];
@@ -219,9 +221,10 @@ - (BOOL)scanJSONDictionary:(NSDictionary **)outDictionary error:(NSError **)outE
[self setScanLocation:theScanLocation];
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan dictionary. Key was not terminated with a ':' character.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-3 userInfo:theUserInfo];
}
[theDictionary release];
@@ -234,9 +237,11 @@ - (BOOL)scanJSONDictionary:(NSDictionary **)outDictionary error:(NSError **)outE
[self setScanLocation:theScanLocation];
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan dictionary. Failed to scan a value.", NSLocalizedDescriptionKey,
NULL];
+
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-4 userInfo:theUserInfo];
}
[theDictionary release];
@@ -253,9 +258,10 @@ - (BOOL)scanJSONDictionary:(NSDictionary **)outDictionary error:(NSError **)outE
[self setScanLocation:theScanLocation];
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan dictionary. Key value pairs not delimited with a ',' character.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-5 userInfo:theUserInfo];
}
[theDictionary release];
@@ -276,9 +282,10 @@ - (BOOL)scanJSONDictionary:(NSDictionary **)outDictionary error:(NSError **)outE
[self setScanLocation:theScanLocation];
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan dictionary. Dictionary not terminated by a '}' character.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-6 userInfo:theUserInfo];
}
[theDictionary release];
@@ -301,9 +308,10 @@ - (BOOL)scanJSONArray:(NSArray **)outArray error:(NSError **)outError
{
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan array. Array not started by a '{' character.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-7 userInfo:theUserInfo];
}
return(NO);
@@ -320,9 +328,10 @@ - (BOOL)scanJSONArray:(NSArray **)outArray error:(NSError **)outError
[self setScanLocation:theScanLocation];
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan array. Could not scan a value.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-8 userInfo:theUserInfo];
}
[theArray release];
@@ -333,9 +342,10 @@ - (BOOL)scanJSONArray:(NSArray **)outArray error:(NSError **)outError
{
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
- @"Could not scan array. Value is NULL.", NSLocalizedDescriptionKey,
- NULL];
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ @"Could not scan array. Value is NULL.", NSLocalizedDescriptionKey,
+ NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-9 userInfo:theUserInfo];
}
[theArray release];
@@ -353,9 +363,10 @@ - (BOOL)scanJSONArray:(NSArray **)outArray error:(NSError **)outError
[self setScanLocation:theScanLocation];
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan array. Array not terminated by a ']' character.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-9 userInfo:theUserInfo];
}
[theArray release];
@@ -374,9 +385,10 @@ - (BOOL)scanJSONArray:(NSArray **)outArray error:(NSError **)outError
[self setScanLocation:theScanLocation];
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan array. Array not terminated by a ']' character.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-10 userInfo:theUserInfo];
}
[theArray release];
@@ -404,9 +416,10 @@ - (BOOL)scanJSONStringConstant:(NSString **)outStringConstant error:(NSError **)
[self setScanLocation:theScanLocation];
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan string constant. String not started by a '\"' character.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-11 userInfo:theUserInfo];
}
[theString release];
@@ -457,9 +470,10 @@ - (BOOL)scanJSONStringConstant:(NSString **)outStringConstant error:(NSError **)
[self setScanLocation:theScanLocation];
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan string constant. Unicode character could not be decoded.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-12 userInfo:theUserInfo];
}
[theString release];
@@ -476,9 +490,10 @@ - (BOOL)scanJSONStringConstant:(NSString **)outStringConstant error:(NSError **)
[self setScanLocation:theScanLocation];
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan string constant. Unknown escape code.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-13 userInfo:theUserInfo];
}
[theString release];
@@ -493,9 +508,10 @@ - (BOOL)scanJSONStringConstant:(NSString **)outStringConstant error:(NSError **)
{
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan string constant. No terminating double quote character.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-14 userInfo:theUserInfo];
}
[theString release];
@@ -525,9 +541,10 @@ - (BOOL)scanJSONNumberConstant:(NSNumber **)outNumberConstant error:(NSError **)
{
if (outError)
{
- NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ NSMutableDictionary *theUserInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"Could not scan number constant.", NSLocalizedDescriptionKey,
NULL];
+ [theUserInfo addEntriesFromDictionary:self.userInfoForScanLocation];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-14 userInfo:theUserInfo];
}
return(NO);
View
@@ -50,13 +50,14 @@ void test(void)
{
NSString *theSource = NULL;
//
-theSource = @"{\"a\": [ { ] }";
+theSource = @"\n\n\n\n\n{\"a\": [ { ] }";
NSData *theData = [theSource dataUsingEncoding:NSUTF32BigEndianStringEncoding];
NSError *theError = NULL;
id theObject = [[CJSONDeserializer deserializer] deserialize:theData error:&theError];
NSLog(@"Error: %@", theError);
+NSLog(@"Error (User Info): %@", theError.userInfo);
NSLog(@"Result: %@", theObject);
}

0 comments on commit 04a511b

Please sign in to comment.