From a6ea2267e813195007aa26140460cd9538fcaf64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pirringer?= Date: Fri, 22 Feb 2013 16:19:16 +0100 Subject: [PATCH 1/6] fixed endless loop in layout subviews if the title is too long --- Core/Source/iOS/DTActivityTitleView.m | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) 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]; } From c5cebdadb3ad4015233e6bf60187d3763dbff519 Mon Sep 17 00:00:00 2001 From: Oliver Drobnik Date: Fri, 22 Feb 2013 20:33:35 +0100 Subject: [PATCH 2/6] ASN1 Parser Fixes - fixed a crash due to using BytesNoCopy on a different address than the malloc, in bit string decoding - fixed a bug where encountering ASN1NULL would end parsing - moved date formatter creation for parsing into init - added an additional autorelease pool in the parse method, so that if there are some other memory problems this is localized to DTASN1Parser --- Core/Source/DTASN1Parser.m | 133 ++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 68 deletions(-) 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; From c2ebc25e5caf0fea9a764afd384b321ae2e5350a Mon Sep 17 00:00:00 2001 From: Oliver Drobnik Date: Thu, 28 Feb 2013 14:10:37 +0100 Subject: [PATCH 3/6] Updated docs, moved appledoc settings to plist --- AppledocSettings.plist | 44 ++++++++++++++++++++++++++ Core/Source/DTObjectBlockExecutor.h | 1 + Core/Source/NSObject+DTRuntime.h | 1 + Core/Source/iOS/UIView+DTDebug.h | 7 ++-- DTFoundation.xcodeproj/project.pbxproj | 4 ++- 5 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 AppledocSettings.plist 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/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/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 */ From 7ef0b05fe66cd3faf769e3afe0328622fb2498e3 Mon Sep 17 00:00:00 2001 From: Oliver Drobnik Date: Thu, 28 Feb 2013 14:12:13 +0100 Subject: [PATCH 4/6] changed URL to own docs server --- readme.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.markdown b/readme.markdown index a0c57051..7e3a1093 100644 --- a/readme.markdown +++ b/readme.markdown @@ -45,7 +45,7 @@ It is open source and covered by a standard BSD license. That means you have to 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 ----- From aec09a10dc7feab8ea431de3597ed6dd6bef07b3 Mon Sep 17 00:00:00 2001 From: Oliver Drobnik Date: Thu, 28 Feb 2013 14:12:57 +0100 Subject: [PATCH 5/6] removed loadableCategory hack reference --- readme.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.markdown b/readme.markdown index 7e3a1093..9daa7a11 100644 --- a/readme.markdown +++ b/readme.markdown @@ -50,7 +50,7 @@ Documentation can be [browsed online](https://docs.cocoanetics.com/DTFoundation) 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. From 87de8b7775ea18de3554729cfb6307a7efa585f3 Mon Sep 17 00:00:00 2001 From: Oliver Drobnik Date: Thu, 28 Feb 2013 16:18:03 +0100 Subject: [PATCH 6/6] Update license info in readme --- readme.markdown | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/readme.markdown b/readme.markdown index 9daa7a11..ab47bdd1 100644 --- a/readme.markdown +++ b/readme.markdown @@ -38,9 +38,13 @@ 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 -------------