diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 95b3869..4e23cb1 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -39,9 +39,6 @@ 625A150819C78ABA00AD0C32 /* HTMLInputStreamReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 625A150619C78ABA00AD0C32 /* HTMLInputStreamReader.h */; }; 625A150919C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A150719C78ABA00AD0C32 /* HTMLInputStreamReader.m */; }; 625A150A19C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A150719C78ABA00AD0C32 /* HTMLInputStreamReader.m */; }; - 625A150D19C78BE900AD0C32 /* HTMLInputStreamReaderErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 625A150B19C78BE900AD0C32 /* HTMLInputStreamReaderErrors.h */; }; - 625A150E19C78BE900AD0C32 /* HTMLInputStreamReaderErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A150C19C78BE900AD0C32 /* HTMLInputStreamReaderErrors.m */; }; - 625A150F19C78BE900AD0C32 /* HTMLInputStreamReaderErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A150C19C78BE900AD0C32 /* HTMLInputStreamReaderErrors.m */; }; 6279F87419E1808D00F12EE5 /* HTMLElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 6279F87219E1808D00F12EE5 /* HTMLElement.h */; }; 6279F87519E1808D00F12EE5 /* HTMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 6279F87319E1808D00F12EE5 /* HTMLElement.m */; }; 6279F87619E1808D00F12EE5 /* HTMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 6279F87319E1808D00F12EE5 /* HTMLElement.m */; }; @@ -131,8 +128,6 @@ 625A14EC19C7834100AD0C32 /* HTMLKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HTMLKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 625A150619C78ABA00AD0C32 /* HTMLInputStreamReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLInputStreamReader.h; sourceTree = ""; }; 625A150719C78ABA00AD0C32 /* HTMLInputStreamReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLInputStreamReader.m; sourceTree = ""; }; - 625A150B19C78BE900AD0C32 /* HTMLInputStreamReaderErrors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLInputStreamReaderErrors.h; sourceTree = ""; }; - 625A150C19C78BE900AD0C32 /* HTMLInputStreamReaderErrors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLInputStreamReaderErrors.m; sourceTree = ""; }; 6279F87119E17DC700F12EE5 /* HTMLParserInsertionModes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLParserInsertionModes.h; sourceTree = ""; }; 6279F87219E1808D00F12EE5 /* HTMLElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLElement.h; sourceTree = ""; }; 6279F87319E1808D00F12EE5 /* HTMLElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLElement.m; sourceTree = ""; }; @@ -294,8 +289,6 @@ children = ( 625A150619C78ABA00AD0C32 /* HTMLInputStreamReader.h */, 625A150719C78ABA00AD0C32 /* HTMLInputStreamReader.m */, - 625A150B19C78BE900AD0C32 /* HTMLInputStreamReaderErrors.h */, - 625A150C19C78BE900AD0C32 /* HTMLInputStreamReaderErrors.m */, 624493A419CCC54100BCDDF4 /* HTMLTokenizer.h */, 624493A519CCC54100BCDDF4 /* HTMLTokenizer.m */, 624493A919CCE84A00BCDDF4 /* HTMLTokenizerStates.h */, @@ -333,7 +326,6 @@ 62F31FDD19E9DCCF007F0657 /* HTMLTokenizerEntities.h in Headers */, 6279F87419E1808D00F12EE5 /* HTMLElement.h in Headers */, 62AE593F19F9907C0043F069 /* HTMLTagToken.h in Headers */, - 625A150D19C78BE900AD0C32 /* HTMLInputStreamReaderErrors.h in Headers */, 624493A619CCC54100BCDDF4 /* HTMLTokenizer.h in Headers */, 62AE593A19F97E1C0043F069 /* HTMLDOCTYPEToken.h in Headers */, 625A150419C783EB00AD0C32 /* HTMLKit.h in Headers */, @@ -494,7 +486,6 @@ 62AE594619F992F30043F069 /* HTMLCommentToken.m in Sources */, 62AE593C19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */, 62F873ED19E088C90062683C /* HTMLParser.m in Sources */, - 625A150F19C78BE900AD0C32 /* HTMLInputStreamReaderErrors.m in Sources */, 6279F87619E1808D00F12EE5 /* HTMLElement.m in Sources */, 625A150A19C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */, 624493A819CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, @@ -524,7 +515,6 @@ 62AE594519F992F30043F069 /* HTMLCommentToken.m in Sources */, 62AE593B19F97E1C0043F069 /* HTMLDOCTYPEToken.m in Sources */, 62F873EC19E088C90062683C /* HTMLParser.m in Sources */, - 625A150E19C78BE900AD0C32 /* HTMLInputStreamReaderErrors.m in Sources */, 6279F87519E1808D00F12EE5 /* HTMLElement.m in Sources */, 625A150919C78ABA00AD0C32 /* HTMLInputStreamReader.m in Sources */, 624493A719CCC54100BCDDF4 /* HTMLTokenizer.m in Sources */, diff --git a/HTMLKit/HTMLInputStreamReader.h b/HTMLKit/HTMLInputStreamReader.h index 12a7f2e..061c925 100644 --- a/HTMLKit/HTMLInputStreamReader.h +++ b/HTMLKit/HTMLInputStreamReader.h @@ -7,7 +7,8 @@ // #import -#import "HTMLInputStreamReaderErrors.h" + +typedef void (^ HTMLStreamReaderErrorCallback)(NSString *reason); /** * HTML Input Stream Reader processor conforming to the HTML standard diff --git a/HTMLKit/HTMLInputStreamReader.m b/HTMLKit/HTMLInputStreamReader.m index ff2dc16..949898d 100644 --- a/HTMLKit/HTMLInputStreamReader.m +++ b/HTMLKit/HTMLInputStreamReader.m @@ -42,6 +42,15 @@ return self; } +#pragma mark - Errors + +- (void)emitParseError:(NSString *)reason +{ + if (self.errorCallback) { + self.errorCallback(reason); + } +} + #pragma mark - Stream Processing - (UTF32Char)currentInputCharacter @@ -59,32 +68,32 @@ _consume = 1; if (nextInputCharacter == CARRIAGE_RETURN) { UniChar next = CFStringGetCharacterFromInlineBuffer(&_buffer, _location + 1); - if (next == LINE_FEED) _consume = 2; + if (next == LINE_FEED) { + _consume = 2; + } return LINE_FEED; } if (CFStringIsSurrogateLowCharacter(nextInputCharacter)) { - [HTMLInputStreamReaderErrors emitParseError:HTMLStreamReaderErrorIsolatedLowSurrogate - atLocation:_location - andCallback:_errorCallback]; + NSString *reason = [NSString stringWithFormat:@"Non-Unicode character found (an isolated low surrogate: %X)", nextInputCharacter]; + [self emitParseError:reason]; return nextInputCharacter; } if (CFStringIsSurrogateHighCharacter(nextInputCharacter)) { UniChar surrogateLow = CFStringGetCharacterFromInlineBuffer(&_buffer, _location + 1); if (CFStringIsSurrogateLowCharacter(surrogateLow) == NO) { - [HTMLInputStreamReaderErrors emitParseError:HTMLStreamReaderErrorIsolatedHighSurrogate - atLocation:_location - andCallback:_errorCallback]; + NSString *reason = [NSString stringWithFormat:@"Non-Unicode character found (an isolated high surrogate: %X)", nextInputCharacter]; + [self emitParseError:reason]; return nextInputCharacter; } + _consume = 2; nextInputCharacter = CFStringGetLongCharacterForSurrogatePair(nextInputCharacter, surrogateLow); } if (isControlOrUndefinedCharacter(nextInputCharacter)) { - [HTMLInputStreamReaderErrors emitParseError:HTMLStreamReaderErrorControlOrUndefined - atLocation:_location - andCallback:_errorCallback]; + NSString *reason = [NSString stringWithFormat:@"A control/undefined character found: %X", nextInputCharacter]; + [self emitParseError:reason]; } return nextInputCharacter; diff --git a/HTMLKit/HTMLInputStreamReaderErrors.h b/HTMLKit/HTMLInputStreamReaderErrors.h deleted file mode 100644 index 059418b..0000000 --- a/HTMLKit/HTMLInputStreamReaderErrors.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// HTMLInputStreamReaderErrors.h -// HTMLKit -// -// Created by Iska on 15/09/14. -// Copyright (c) 2014 BrainCookie. All rights reserved. -// - -#import - -extern NSString * const HTMLInputStreamReaderErrorDomain; - -typedef NS_ENUM(NSUInteger, HTMLStreamReaderError) -{ - HTMLStreamReaderErrorIsolatedLowSurrogate = 100, - HTMLStreamReaderErrorIsolatedHighSurrogate = 200, - HTMLStreamReaderErrorControlOrUndefined = 300 -}; - -typedef void (^ HTMLStreamReaderErrorCallback)(NSError *error); - -@interface HTMLInputStreamReaderErrors : NSObject - -+ (void)emitParseError:(HTMLStreamReaderError)parseError - atLocation:(NSUInteger)location - andCallback:(HTMLStreamReaderErrorCallback)callback; - -@end diff --git a/HTMLKit/HTMLInputStreamReaderErrors.m b/HTMLKit/HTMLInputStreamReaderErrors.m deleted file mode 100644 index 942c670..0000000 --- a/HTMLKit/HTMLInputStreamReaderErrors.m +++ /dev/null @@ -1,44 +0,0 @@ -// -// HTMLInputStreamReaderErrors.m -// HTMLKit -// -// Created by Iska on 15/09/14. -// Copyright (c) 2014 BrainCookie. All rights reserved. -// - -#import "HTMLInputStreamReaderErrors.h" - -NSString * const HTMLInputStreamReaderErrorDomain = @"HTMLInputStreamReaderErrorDomain"; - -static inline NSString * ReasonStringForError(HTMLStreamReaderError error) -{ - switch (error) { - case HTMLStreamReaderErrorIsolatedLowSurrogate: - return @"Non-Unicode character found (an isolated low surrogate)"; - case HTMLStreamReaderErrorIsolatedHighSurrogate: - return @"Non-Unicode character found (an isolated high surrogate)"; - case HTMLStreamReaderErrorControlOrUndefined: - return @"A control/undefined character found"; - default: - break; - } -} - -@implementation HTMLInputStreamReaderErrors - -+ (void)emitParseError:(HTMLStreamReaderError)parseError atLocation:(NSUInteger)location andCallback:(HTMLStreamReaderErrorCallback)callback -{ - if (callback == nil) return; - - NSDictionary *userInfo = @{ - NSLocalizedDescriptionKey : [NSString stringWithFormat:@"HTML Input Stream error at [%ld]", location], - NSLocalizedFailureReasonErrorKey : ReasonStringForError(parseError) - }; - - NSError *error = [[NSError alloc] initWithDomain:HTMLInputStreamReaderErrorDomain - code:parseError - userInfo:userInfo]; - if (callback) callback(error); -} - -@end diff --git a/HTMLKit/HTMLTokenizer.m b/HTMLKit/HTMLTokenizer.m index 0e06801..afbd6e0 100644 --- a/HTMLKit/HTMLTokenizer.m +++ b/HTMLKit/HTMLTokenizer.m @@ -62,6 +62,10 @@ _tokens = [NSMutableArray new]; _inputStreamReader = [[HTMLInputStreamReader alloc] initWithString:string]; + __weak HTMLTokenizer *weakSelf = self; + _inputStreamReader.errorCallback = ^ (NSString *reason) { + [weakSelf emitParseError:@"%@", reason]; + }; } return self; }