diff --git a/AppledocSettings.plist b/AppledocSettings.plist new file mode 100644 index 00000000..fc514187 --- /dev/null +++ b/AppledocSettings.plist @@ -0,0 +1,44 @@ + + + + + --project-name + DTFoundation + --project-company + Cocoanetics + --project-version + 1.0 + --company-id + com.cocoanetics + --docset-atom-filename + DTFoundation.atom + --docset-feed-url + https://docs.cocoanetics.com/DTFoundation/%DOCSETATOMFILENAME + --docset-package-url + https://docs.cocoanetics.com/DTFoundation/%DOCSETPACKAGEFILENAME + --docset-fallback-url + https://docs.cocoanetics.com/DTFoundation/ + --create-docset + + --publish-docset + + --install-docset + + --logformat + xcode + --keep-intermediate-files + + --no-repeat-first-par + + --ignore + + *.m + Core/Externals + Demo + + --index-desc + Readme.markdown + --warn-invalid-crossref + + + diff --git a/Core/Source/DTASN1Parser.m b/Core/Source/DTASN1Parser.m index e523a267..277d0af3 100644 --- a/Core/Source/DTASN1Parser.m +++ b/Core/Source/DTASN1Parser.m @@ -17,8 +17,10 @@ @implementation DTASN1Parser NSError *_parserError; BOOL _abortParsing; + NSDateFormatter *_UTCFormatter; + // lookup bitmask what delegate methods are implemented - struct + struct { unsigned int delegateSupportsDocumentStart:1; unsigned int delegateSupportsDocumentEnd:1; @@ -47,6 +49,11 @@ - (id)initWithData:(NSData *)data _data = data; _dataLength = [data length]; + // has to end with Z + _UTCFormatter = [[NSDateFormatter alloc] init]; + _UTCFormatter.dateFormat = @"yyMMddHHmmss'Z'"; + _UTCFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; + if (!_dataLength) { return nil; @@ -83,7 +90,7 @@ - (NSUInteger)_parseLengthAtLocation:(NSUInteger)location lengthOfLength:(NSUInt { retValue = (NSUInteger)buffer; } - else if (buffer>0x80) + else if (buffer>0x80) { // next n bytes describe the length length NSUInteger lengthLength = buffer-0x80; @@ -105,7 +112,7 @@ - (NSUInteger)_parseLengthAtLocation:(NSUInteger)location lengthOfLength:(NSUInt free(lengthBytes); } - else + else { // length 0x80 means "indefinite" [self _parseErrorEncountered:@"Indefinite Length form encounted, not implemented"]; @@ -121,12 +128,15 @@ - (NSUInteger)_parseLengthAtLocation:(NSUInteger)location lengthOfLength:(NSUInt - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange { - if (!dataRange.length) - { - return NO; - } - - switch (tag) + if (!dataRange.length && tag != DTASN1TypeNull) + { + NSLog(@"Encountered zero length data for tag %ld", tag); + + // only NULL can have zero length + return NO; + } + + switch (tag) { case DTASN1TypeBoolean: { @@ -172,15 +182,15 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange [_delegate parser:self foundNumber:number]; } - else + else { // send number as data if supported, too long for 32 bit sendAsData = YES; } - - free(buffer); + + free(buffer); } - else + else { // send number as data if supported, delegate does not want numbers sendAsData = YES; @@ -191,7 +201,7 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange char *buffer = malloc(dataRange.length); [_data getBytes:buffer range:dataRange]; NSData *data = [NSData dataWithBytesNoCopy:buffer length:dataRange.length freeWhenDone:YES]; - + [_delegate parser:self foundData:data]; } @@ -202,21 +212,23 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange { if (_delegateFlags.delegateSupportsData) { - char *buffer = malloc(dataRange.length); - [_data getBytes:buffer range:dataRange]; - - // primitive encoding - NSUInteger unusedBits = buffer[0]; - - if (unusedBits>0) - { - [self _parseErrorEncountered:@"Encountered bit string with unused bits > 0, not implemented"]; - free(buffer); - return NO; - } + char *buffer = malloc(dataRange.length); + [_data getBytes:buffer range:dataRange]; + + // primitive encoding + NSUInteger unusedBits = buffer[0]; + + if (unusedBits>0) + { + [self _parseErrorEncountered:@"Encountered bit string with unused bits > 0, not implemented"]; + free(buffer); + return NO; + } - NSData *data = [NSData dataWithBytesNoCopy:buffer+1 length:dataRange.length-1 freeWhenDone:YES]; + NSData *data = [NSData dataWithBytes:buffer+1 length:dataRange.length-1]; [_delegate parser:self foundData:data]; + + free(buffer); } break; @@ -231,7 +243,7 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange NSData *data = [NSData dataWithBytesNoCopy:buffer length:dataRange.length freeWhenDone:YES]; [_delegate parser:self foundData:data]; - } + } break; } @@ -264,7 +276,7 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange NSUInteger value=0; BOOL more = NO; - do + do { unsigned char b = buffer[i]; value = value * 128; @@ -281,7 +293,7 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange { [self _parseErrorEncountered:@"Invalid object identifier with more bit set on last octed"]; free(buffer); - + return NO; } } while (more); @@ -324,12 +336,7 @@ - (BOOL)_parseValueWithTag:(NSUInteger)tag dataRange:(NSRange)dataRange NSString *string = [[NSString alloc] initWithBytesNoCopy:buffer length:dataRange.length encoding:NSASCIIStringEncoding freeWhenDone:YES]; - // has to end with Z - NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; - formatter.dateFormat = @"yyMMddHHmmss'Z'"; - formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; - - NSDate *parsedDate = [formatter dateFromString:string]; + NSDate *parsedDate = [_UTCFormatter dateFromString:string]; if (parsedDate) { @@ -363,7 +370,7 @@ - (BOOL)_parseRange:(NSRange)range NSUInteger location = range.location; - do + do { if (_abortParsing) { @@ -375,9 +382,8 @@ - (BOOL)_parseRange:(NSRange)range [_data getBytes:&tagByte range:NSMakeRange(location, 1)]; location++; - - BOOL isSeq = tagByte & 32; - BOOL isContext = tagByte & 128; + // BOOL isSeq = tagByte & 32; + // BOOL isContext = tagByte & 128; //NSUInteger tagClass = tagByte >> 6; DTASN1Type tagType = tagByte & 31; @@ -404,18 +410,6 @@ - (BOOL)_parseRange:(NSRange)range // make range NSRange subRange = NSMakeRange(location, length); - if (isContext) - { - //NSLog(@"[%d]", tagType); - } - else - { - if (isSeq) - { - //NSLog(@"%d", tagType); - } - } - if (tagConstructed) { // constructed element @@ -435,7 +429,7 @@ - (BOOL)_parseRange:(NSRange)range [_delegate parser:self didEndContainerWithType:tagType]; } } - else + else { // primitive if (![self _parseValueWithTag:tagType dataRange:subRange]) @@ -463,19 +457,22 @@ - (BOOL)_parseRange:(NSRange)range - (BOOL)parse { - if (_delegateFlags.delegateSupportsDocumentStart) + @autoreleasepool { - [_delegate parserDidStartDocument:self]; - } - - BOOL result = [self _parseRange:NSMakeRange(0, _dataLength)]; - - if (result && _delegateFlags.delegateSupportsDocumentEnd) - { - [_delegate parserDidEndDocument:self]; + if (_delegateFlags.delegateSupportsDocumentStart) + { + [_delegate parserDidStartDocument:self]; + } + + BOOL result = [self _parseRange:NSMakeRange(0, _dataLength)]; + + if (result && _delegateFlags.delegateSupportsDocumentEnd) + { + [_delegate parserDidEndDocument:self]; + } + + return result; } - - return result; } - (void)abortParsing @@ -503,7 +500,7 @@ - (void)setDelegate:(__unsafe_unretained id)delegate; { _delegateFlags.delegateSupportsDocumentEnd = YES; } - + if ([_delegate respondsToSelector:@selector(parser:didStartContainerWithType:)]) { _delegateFlags.delegateSupportsContainerStart = YES; @@ -523,7 +520,7 @@ - (void)setDelegate:(__unsafe_unretained id)delegate; { _delegateFlags.delegateSupportsString = YES; } - + if ([_delegate respondsToSelector:@selector(parserFoundNull:)]) { _delegateFlags.delegateSupportsNull = YES; @@ -538,12 +535,12 @@ - (void)setDelegate:(__unsafe_unretained id)delegate; { _delegateFlags.delegateSupportsData = YES; } - + if ([_delegate respondsToSelector:@selector(parser:foundNumber:)]) { _delegateFlags.delegateSupportsNumber = YES; } - + if ([_delegate respondsToSelector:@selector(parser:foundObjectIdentifier:)]) { _delegateFlags.delegateSupportsObjectIdentifier = YES; diff --git a/Core/Source/DTObjectBlockExecutor.h b/Core/Source/DTObjectBlockExecutor.h index 144816a6..19926d80 100644 --- a/Core/Source/DTObjectBlockExecutor.h +++ b/Core/Source/DTObjectBlockExecutor.h @@ -14,6 +14,7 @@ /** Convenience method to create a block executor with a deallocation block + @param block The block to execute when the created receiver is being deallocated */ + (id)blockExecutorWithDeallocBlock:(void(^)())block; diff --git a/Core/Source/NSObject+DTRuntime.h b/Core/Source/NSObject+DTRuntime.h index 9406e9d4..fc27af5a 100644 --- a/Core/Source/NSObject+DTRuntime.h +++ b/Core/Source/NSObject+DTRuntime.h @@ -19,6 +19,7 @@ /** Adds a block to be executed as soon as the receiver's memory is deallocated + @param block The block to execute when the receiver is being deallocated */ - (void)addDeallocBlock:(void(^)())block; diff --git a/Core/Source/iOS/DTActivityTitleView.m b/Core/Source/iOS/DTActivityTitleView.m index c862e57a..573354b4 100644 --- a/Core/Source/iOS/DTActivityTitleView.m +++ b/Core/Source/iOS/DTActivityTitleView.m @@ -54,19 +54,6 @@ - (id)init - (void)layoutSubviews { [super layoutSubviews]; - - CGFloat gap = 5.0; - CGFloat height = self.activityIndicator.frame.size.height; - CGSize neededSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font]; - - if (height < neededSize.height) - { - height = neededSize.height; - } - - CGRect titleRect = CGRectMake(self.activityIndicator.frame.size.width+gap, 0, neededSize.width, height); - self.titleLabel.frame = titleRect; - self.bounds = CGRectMake(0, 0, self.activityIndicator.frame.size.width+neededSize.width+gap, height); } #pragma mark - Properties @@ -93,6 +80,18 @@ - (BOOL)busy - (void)setTitle:(NSString *)title { self.titleLabel.text = title; + CGFloat gap = 5.0; + CGFloat height = self.activityIndicator.frame.size.height; + CGSize neededSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font]; + + if (height < neededSize.height) + { + height = neededSize.height; + } + + CGRect titleRect = CGRectMake(self.activityIndicator.frame.size.width+gap, 0, neededSize.width, height); + self.titleLabel.frame = titleRect; + self.bounds = CGRectMake(0, 0, self.activityIndicator.frame.size.width+neededSize.width+gap, height); [self setNeedsLayout]; } diff --git a/Core/Source/iOS/UIView+DTDebug.h b/Core/Source/iOS/UIView+DTDebug.h index b59878bc..58a0b891 100644 --- a/Core/Source/iOS/UIView+DTDebug.h +++ b/Core/Source/iOS/UIView+DTDebug.h @@ -6,14 +6,16 @@ // Copyright (c) 2013 Cocoanetics. All rights reserved. // -#import - /** Methods useful for debugging problems with UIView instances. */ @interface UIView (DTDebug) +/** + @name Main Thread Checking + */ + /** Toggles on/off main thread checking on several methods of UIView. @@ -31,6 +33,7 @@ Method that gets called if one of the important methods of UIView is not being called on a main queue. Toggle this on/off with . Break on -[UIView methodCalledNotFromMainThread:] to catch it in debugger. + @param methodName Symbolic name of the method being called */ - (void)methodCalledNotFromMainThread:(NSString *)methodName; diff --git a/DTFoundation.xcodeproj/project.pbxproj b/DTFoundation.xcodeproj/project.pbxproj index e21eb6fb..a82c28da 100644 --- a/DTFoundation.xcodeproj/project.pbxproj +++ b/DTFoundation.xcodeproj/project.pbxproj @@ -432,6 +432,7 @@ A77DD41414E825FC00F34B03 /* zip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zip.c; sourceTree = ""; }; A77DD41514E825FC00F34B03 /* zip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zip.h; sourceTree = ""; }; A78220BA168060CA005B602D /* libDTUTI.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libDTUTI.a; sourceTree = BUILT_PRODUCTS_DIR; }; + A7859D3D16DF8D180076F2DB /* AppledocSettings.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AppledocSettings.plist; sourceTree = ""; }; A79231CC157A0B9400C3ACBB /* NSURL+DTUnshorten.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+DTUnshorten.h"; sourceTree = ""; }; A79231CD157A0B9400C3ACBB /* NSURL+DTUnshorten.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+DTUnshorten.m"; sourceTree = ""; }; A79500F3161D680000358BC3 /* NSData+Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Base64.h"; sourceTree = ""; }; @@ -895,6 +896,7 @@ A7F4DF98147FB61500F4059A = { isa = PBXGroup; children = ( + A7859D3D16DF8D180076F2DB /* AppledocSettings.plist */, A7D60FE415D3B15300AEDD1B /* Test */, A70B4CC41486621B00873A4A /* Core */, A70B4CDA1486626900873A4A /* Documentation */, @@ -1348,7 +1350,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/usr/local/bin/appledoc \\\n--project-name \"DTFoundation\" \\\n--project-company \"Cocoanetics\" \\\n--company-id \"com.cocoanetics\" \\\n--docset-atom-filename \"DTFoundation.atom\" \\\n--docset-feed-url \"http://cocoanetics.github.com/DTFoundation/%DOCSETATOMFILENAME\" \\\n--docset-package-url \"http://cocoanetics.github.com/DTFoundation/%DOCSETPACKAGEFILENAME\" \\\n--docset-fallback-url \"http://cocoanetics.github.com/DTFoundation/\" \\\n--output \"~/help/DTFoundation\" \\\n--publish-docset \\\n--logformat xcode \\\n--keep-undocumented-objects \\\n--keep-undocumented-members \\\n--keep-intermediate-files \\\n--no-repeat-first-par \\\n--no-warn-invalid-crossref \\\n--ignore \"*.m\" \\\n--ignore \"LoadableCategory.h\" \\\n--ignore \"DTZipArchiveGZip.h\" \\\n--ignore \"DTZipArchivePKZip.h\" \\\n--index-desc \"${PROJECT_DIR}/readme.markdown\" \\\n\"${PROJECT_DIR}/Core/Source\""; + shellScript = "/usr/local/bin/appledoc --print-settings --output \"${BUILD_DIR}/Documentation/\" \"${PROJECT_DIR}\"\necho \"Documentation Output directory: ${BUILD_DIR}/Documentation/\""; }; /* End PBXShellScriptBuildPhase section */ diff --git a/readme.markdown b/readme.markdown index a0c57051..ab47bdd1 100644 --- a/readme.markdown +++ b/readme.markdown @@ -38,19 +38,23 @@ Other classes simplify working with specialized data - DTZipArchive - uncompressing ZIP and GZ files License -------- - -It is open source and covered by a standard BSD license. That means you have to mention *Cocoanetics* as the original author of this code. You can purchase a Non-Attribution-License from us. +------- + +It is open source and covered by a standard 2-clause BSD license. That means you have to mention *Cocoanetics* as the original author of this code and reproduce the LICENSE text inside your app. + +You can purchase a [Non-Attribution-License](http://www.cocoanetics.com/order/?product=DTFoundation%20Non-Attribution%20License) for 75 Euros for not having to include the LICENSE text. + +We also accept sponsorship for specific enhancements which you might need. Please [contact us via email](mailto:oliver@cocoanetics.com?subject=DTFoundation) for inquiries. Documentation ------------- -Documentation can be [browsed online](http://cocoanetics.github.com/DTFoundation) or installed in your Xcode Organizer via the [Atom Feed URL](http://cocoanetics.github.com/DTFoundation/DTFoundation.atom). +Documentation can be [browsed online](https://docs.cocoanetics.com/DTFoundation) or installed in your Xcode Organizer via the [Atom Feed URL](https://docs.cocoanetics.com/DTFoundation/DTFoundation.atom). Usage ----- -The DTFoundation.framework is using the "Fake Framework" template put together by [Karl Stenerud](https://github.com/kstenerud/iOS-Universal-Framework). All categories employ Karl's LoadabeCategory hack to avoid having to use the -all_load linker flag. If your app does not use ARC yet (but DTFoundation does) then you also need the -fobjc-arc linker flag. +The DTFoundation.framework is using the "Fake Framework" template put together by [Karl Stenerud](https://github.com/kstenerud/iOS-Universal-Framework). If your app does not use ARC yet (but DTFoundation does) then you also need the -fobjc-arc linker flag. 1. Include the DTFoundation.framework in your project. 2. Import the DTFoundation.h in your PCH file or include the individual header files where needed.