diff --git a/DirectoryReader.m b/DirectoryReader.m index 370b773..7542e62 100644 --- a/DirectoryReader.m +++ b/DirectoryReader.m @@ -27,7 +27,10 @@ - (id)initWithPath:(NSString*)path { if (!path || [path length] <= 0) { return nil; } - m_path = path; + // Remove trailing slash if appended. + NSMutableString* mutablePath = [NSMutableString stringWithString:path]; + [mutablePath replaceOccurrencesOfString:@"/" withString:@"" options:NSBackwardsSearch range:NSMakeRange([path length] - 1, 1)]; + m_path = mutablePath; } return self; } diff --git a/English.lproj/MainMenu.xib b/English.lproj/MainMenu.xib index c2dca70..2800267 100644 --- a/English.lproj/MainMenu.xib +++ b/English.lproj/MainMenu.xib @@ -12,7 +12,7 @@ YES - + YES @@ -1317,7 +1317,7 @@ 15 2 - {{781, 842}, {499, 160}} + {{781, 737}, {499, 265}} 1954021376 LineReader NSWindow @@ -1331,7 +1331,7 @@ 268 - {{20, 90}, {459, 22}} + {{20, 195}, {459, 22}} YES @@ -1345,16 +1345,16 @@ YES - + 6 System textBackgroundColor - + 3 MQA - + 6 System textColor @@ -1368,7 +1368,7 @@ 268 - {{17, 120}, {108, 17}} + {{17, 225}, {108, 17}} YES @@ -1397,7 +1397,7 @@ 268 - {{463, 51}, {19, 27}} + {{350, 155}, {19, 27}} YES @@ -1409,51 +1409,191 @@ YES - + 268 - {{17, 56}, {444, 17}} + {{17, 161}, {230, 17}} YES - + 68288064 71304192 - Count + Maximum numbers of lines: - - YES + - + 268 - {{17, 56}, {368, 17}} + {{255, 158}, {90, 22}} YES - + + -1804468671 + 71304192 + + + + YES + + + + + + + 268 + {{249, 47}, {128, 32}} + + YES + + 67239424 + 134217728 + Read lines + + + -2038284033 + 129 + + + 200 + 25 + + + + + 268 + {{253, 127}, {192, 17}} + + YES + 1 + 2 + + YES + + -2080244224 + 0 + Forwards + + + 1211912703 + 0 + + NSRadioButton + + + + 200 + 25 + + + 67239424 + 0 + Backwards + + + -1 + 1211912703 + 0 + + 400 + 75 + + + {94, 17} + {4, 2} + 1151868928 + NSActionCell + + 67239424 + 0 + Radio + + 1211912703 + 0 + + 549453824 + {18, 18} + + YES + + YES + + + + TU0AKgAABRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAADwRERGLJycnySsrK/A1NTXw +IyMjyRwcHIsJCQk8AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFRUVdVBQUOCoqKj/ +29vb//n5+f/6+vr/2tra/6qqqv9UVFTgHx8fdQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUZGRl5 +dXV198PDw//8/Pz////////////////////////////U1NT/fHx89yUlJXkAAAAFAAAAAAAAAAAAAAAA +AAAAAxEREUZqamrmtbW1/+3t7f/+/v7//v7+//7+/v/9/f3//f39//39/f/39/f/xMTE/3d3d+YZGRlG +AAAAAwAAAAAAAAAAAAAACkJCQqGtra3/xsbG/+vr6//y8vL/9fX1//X19f/z8/P/9fX1//Ly8v/u7u7/ +0tLS/6+vr/9KSkqhAAAACgAAAAAAAAAAAAAAF3h4eN2/v7//z8/P/93d3f/q6ur/7+/v/+/v7//w8PD/ +7e3t/+3t7f/i4uL/zs7O/8XFxf98fHzdAAAAFwAAAAAAAAADAAAAJKSkpPjOzs7/2dnZ/+Dg4P/i4uL/ +5eXl/+bm5v/n5+f/5eXl/+Li4v/e3t7/2tra/9DQ0P+srKz4AAAAJAAAAAMAAAADAAAALrCwsPrW1tb/ +3t7e/+Tk5P/p6en/6+vr/+zs7P/p6en/6+vr/+fn5//k5OT/4ODg/9nZ2f+zs7P6AAAALgAAAAMAAAAD +AAAALp2dnezg4OD/5eXl/+rq6v/u7u7/8PDw//Dw8P/x8fH/8PDw/+7u7v/q6ur/5ubm/+Hh4f+ZmZns +AAAALgAAAAMAAAADAAAAJG5ubs/l5eX/6enp/+/v7//y8vL/9vb2//r6+v/5+fn/9/f3//b29v/x8fH/ +6+vr/+Tk5P9ra2vPAAAAJAAAAAMAAAAAAAAAFy4uLpPCwsL67Ozs//Pz8//5+fn//v7+//7+/v/+/v7/ +/v7+//v7+//19fX/8PDw/8LCwvosLCyTAAAAFwAAAAAAAAAAAAAACgAAAENfX1/S5OTk/vn5+f/+/v7/ +///////////////////////////8/Pz/5ubm/l9fX9IAAABDAAAACgAAAAAAAAAAAAAAAwAAABcAAABl +YmJi3NLS0v3////////////////////////////////V1dX9ZGRk3AAAAGUAAAAXAAAAAwAAAAAAAAAA +AAAAAAAAAAUAAAAfAAAAZTMzM8KAgIDwv7+//O3t7f/t7e3/v7+//ICAgPAzMzPCAAAAZQAAAB8AAAAF +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAFwAAAEMAAAB3AAAAnwAAALMAAACzAAAAnwAAAHcAAABD +AAAAFwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAXAAAAJAAAAC4AAAAu +AAAAJAAAABcAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQEAAAMAAAABABIAAAEB +AAMAAAABABIAAAECAAMAAAAEAAAFugEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES +AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABABIAAAEXAAQAAAABAAAFEAEcAAMAAAABAAEAAAFS +AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA + + + + + + 3 + MCAwAA + + + + 400 + 75 + + + + + + + + + 268 + {{17, 128}, {230, 17}} + + YES + 68288064 - 272630784 - Maximum numbers of lines to be read from each file: + 71304192 + Reading mode: - + - + 268 - {{18, 18}, {200, 18}} + {{253, 93}, {155, 18}} YES - + -2080244224 0 - Read file content backwards + Print lines to console - + 1211912703 2 @@ -1469,8 +1609,40 @@ 25 + + + 268 + {{17, 10}, {47, 17}} + + YES + + 68288064 + 272630784 + Status: + + + + + + + + + 268 + {{66, 10}, {421, 17}} + + YES + + 68288064 + 272630784 + Status + + + + + + - {499, 160} + {499, 265} {{0, 0}, {1280, 1002}} @@ -1482,6 +1654,9 @@ NSFontManager + + YES + @@ -2166,14 +2341,6 @@ 532 - - - sourcePathChanged: - - - - 546 - value: maxNumLines @@ -2190,53 +2357,101 @@ 557 + + + readLinesRequested: + + + + 575 + - value: maxNumLines - + selectedIndex: selectedReadMode + - + - value: maxNumLines + selectedIndex: selectedReadMode + selectedIndex + selectedReadMode + 2 + + + 609 + + + + value: printLines + + + + + + value: printLines value - maxNumLines + printLines 2 - 558 + 613 - value: sourcePath - + value: status + - + - value: sourcePath + value: status value - sourcePath + status 2 - 559 + 623 - value: searchBackwards - + value: maxNumLines + - + - value: searchBackwards + value: maxNumLines value - searchBackwards + maxNumLines + + NSContinuouslyUpdatesValue + + 2 - 566 + 624 + + + + value: sourcePath + + + + + + value: sourcePath + value + sourcePath + + NSContinuouslyUpdatesValue + + + 2 + + + 625 @@ -2795,10 +3010,15 @@ YES - - + + - + + + + + + @@ -3331,46 +3551,133 @@ - 551 - + 553 + YES - + - 552 - - + 554 + + - 553 - + 567 + YES - + - 554 - - + 568 + + + + + 571 + + + YES + + + + + + 572 + + + + + 576 + + + YES + + + + + + + + 577 + + + + + 579 + + + + + 590 + + + + + 591 + + + YES + + + + + + 592 + + + + + 601 + + + + + 610 + + + YES + + + + + + 611 + + + + + 614 + + + YES + + + - 564 - + 615 + + + + + 616 + YES - + - 565 - - + 617 + + @@ -3601,20 +3908,33 @@ 536.IBPluginDependency 549.IBPluginDependency 550.IBPluginDependency - 551.IBPluginDependency - 552.IBPluginDependency 553.IBPluginDependency 554.IBPluginDependency 56.IBPluginDependency 56.ImportedFromIB2 - 564.IBPluginDependency - 565.IBPluginDependency + 567.IBPluginDependency + 568.IBPluginDependency 57.IBEditorWindowLastContentRect 57.IBPluginDependency 57.ImportedFromIB2 57.editorWindowContentRectSynchronizationRect + 571.IBPluginDependency + 572.IBPluginDependency + 576.IBPluginDependency + 577.IBPluginDependency + 579.IBPluginDependency 58.IBPluginDependency 58.ImportedFromIB2 + 590.IBPluginDependency + 591.IBPluginDependency + 592.IBPluginDependency + 601.IBPluginDependency + 610.IBPluginDependency + 611.IBPluginDependency + 614.IBPluginDependency + 615.IBPluginDependency + 616.IBPluginDependency + 617.IBPluginDependency 72.IBPluginDependency 72.ImportedFromIB2 73.IBPluginDependency @@ -3773,9 +4093,9 @@ com.apple.InterfaceBuilder.CocoaPlugin - {{403, 820}, {499, 160}} + {{404, 715}, {499, 265}} com.apple.InterfaceBuilder.CocoaPlugin - {{403, 820}, {499, 160}} + {{404, 715}, {499, 265}} {{33, 99}, {480, 360}} {3.40282e+38, 3.40282e+38} @@ -3870,8 +4190,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -3880,8 +4198,23 @@ {{23, 794}, {245, 183}} com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -3925,7 +4258,7 @@ - 566 + 625 @@ -3934,21 +4267,12 @@ LineReaderAppDelegate NSObject - sourcePathChanged: + readLinesRequested: id - YES - - YES - m_sourcePath - window - - - YES - NSTextField - NSWindow - + window + NSWindow IBProjectSource @@ -4057,6 +4381,14 @@ AppKit.framework/Headers/NSControl.h + + NSController + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSController.h + + NSDocument NSObject @@ -4475,6 +4807,14 @@ AppKit.framework/Headers/NSTextView.h + + NSUserDefaultsController + NSController + + IBFrameworkSource + AppKit.framework/Headers/NSUserDefaultsController.h + + NSView diff --git a/FileReader.m b/FileReader.m index 309704d..e2d7cd7 100644 --- a/FileReader.m +++ b/FileReader.m @@ -57,11 +57,12 @@ - (id)initWithFilePath:(NSString*)filePath { /** Reads the file forwards. + Empty lines are not returned. @returns Another single line on each call or nil if the file end has been reached. */ - (NSString*)readLine { - if (m_currentOffset >= m_totalFileLength) { + if (m_totalFileLength == 0 || m_currentOffset >= m_totalFileLength) { return nil; } @@ -96,11 +97,12 @@ - (NSString*)readLine { /** Reads the file backwards. + Empty lines are returned as well. @returns Another single line on each call or nil if the file end has been reached. */ - (NSString*)readLineBackwards { - if (m_currentInset == 0 && m_chunkSize == 0) { + if (m_totalFileLength == 0 || m_currentInset == 0 && m_chunkSize == 0) { return nil; } diff --git a/LineReaderAppDelegate.h b/LineReaderAppDelegate.h index cb02fd4..f5479ce 100644 --- a/LineReaderAppDelegate.h +++ b/LineReaderAppDelegate.h @@ -8,20 +8,37 @@ #import +/** + Enum for the selected read mode. Defined values are FORWARDS = 0 and BACKWARDS = 1. + */ +typedef enum { FORWARDS = 0, BACKWARDS = 1 } READ_MODE; + + + @interface LineReaderAppDelegate : NSObject { - NSWindow* m_window; /**< Application window. */ - IBOutlet NSTextField* m_sourcePath; /**< Source path. */ - NSNumber* m_maxNumLines; /**< Maximum number of lines. */ - NSNumber* m_searchBackwards; /**< Search backwards if value is 1. */ - NSArray* m_directoryListing; /**< Collection of file paths. */ + NSWindow* m_window; /**< Application window. */ + NSString* m_sourcePath; /**< Source path. */ + NSNumber* m_maxNumLines; /**< Maximum number of lines. */ + NSNumber* m_selectedReadMode; /**< Selected read mode. See READ_MODE enum. */ + NSNumber* m_printLines; /**< Option to print lines to the console. */ + NSString* m_status; /**< Program status. */ + NSArray* m_directoryListing; /**< Collection of file paths. */ } @property (assign) IBOutlet NSWindow* window; /**< Property for the application window. */ @property (readwrite, assign) NSString* sourcePath; /**< Property for the source path. */ @property (readwrite, assign) NSNumber* maxNumLines; /**< Property for the maximum number of lines. */ -@property (readwrite, assign) NSNumber* searchBackwards; /**< Property for switch to search backwards. */ +@property (readwrite, assign) NSNumber* selectedReadMode; /**< Property for the selected read mode. */ +@property (readwrite, assign) NSNumber* printLines; /**< Property for the print lines option. */ +@property (readwrite, assign) NSString* status; /**< Property for the program status. */ + +- (IBAction)readLinesRequested:(id)sender; + +// ----------------------------------------------------------------------------- +// Private functions. +// ----------------------------------------------------------------------------- -- (IBAction)sourcePathChanged:(id)sender; +- (void)processSource; @end diff --git a/LineReaderAppDelegate.m b/LineReaderAppDelegate.m index 0f857e8..6f0b811 100644 --- a/LineReaderAppDelegate.m +++ b/LineReaderAppDelegate.m @@ -25,43 +25,36 @@ - (id)init { self = [super init]; if (self != nil) { + m_sourcePath = [NSString stringWithFormat:@"/tmp/"]; m_maxNumLines = [NSNumber numberWithInt:3]; - [self setSourcePath:[NSString stringWithFormat:@"/tmp/"]]; - m_searchBackwards = [NSNumber numberWithInt:1]; + m_selectedReadMode = [NSNumber numberWithInt:BACKWARDS]; + m_printLines = [NSNumber numberWithBool:NO]; + m_status = [NSString stringWithFormat:@"Application started."]; + m_directoryListing = nil; } return self; } +// ----------------------------------------------------------------------------- +// Properties. +// ----------------------------------------------------------------------------- + + @synthesize window = m_window; @synthesize maxNumLines = m_maxNumLines; -@synthesize searchBackwards = m_searchBackwards; -@dynamic sourcePath; +@synthesize sourcePath = m_sourcePath; +@synthesize selectedReadMode = m_selectedReadMode; +@synthesize printLines = m_printLines; +@synthesize status = m_status; -/** - Returns the source path stored in the text field. - @returns The source path as a NSString. - */ -- (NSString*)sourcePath { - return [m_sourcePath stringValue]; -} +// ----------------------------------------------------------------------------- +// Event functions. +// ----------------------------------------------------------------------------- -/** - Sets the text field with the source path. - @param sourcePath The source path. - */ -- (void)setSourcePath:(NSString*)sourcePath { - - m_sourcePath = [[NSTextField alloc] init]; - if (!sourcePath || [sourcePath length] <= 0) { - [m_sourcePath setStringValue:@""]; - return; - } - [m_sourcePath setStringValue:sourcePath]; -} /** Sent by the default notification center after the application @@ -73,51 +66,113 @@ - (void)applicationDidFinishLaunching:(NSNotification*)aNotification { } - /** - Reads a various number of lines from multiple files as found in the source path. - The function is called whenever the source path changes. + The function is called whenever lines should be read. @param sender The object calling this method. */ -- (IBAction)sourcePathChanged:(id)sender { +- (IBAction)readLinesRequested:(id)sender { - DirectoryReader* directoryReader = [[DirectoryReader alloc] initWithPath:[m_sourcePath stringValue]]; + [self processSource]; +} + + + +// ----------------------------------------------------------------------------- +// Private functions. +// ----------------------------------------------------------------------------- + + + +/** + Reads a various number of lines from multiple files as + found in the source path. The lines can be read forwards + or backwards from the file. + */ +- (void)processSource { + + int lineCount; + NSTimeInterval processingStarted = [NSDate timeIntervalSinceReferenceDate]; + + DirectoryReader* directoryReader = [[DirectoryReader alloc] initWithPath:m_sourcePath]; if (!directoryReader) { return; } - + if ([directoryReader readDirectory:&m_directoryListing]) { - + for (NSString* path in m_directoryListing) { NSLog(@"File: %@", path); /* DEBUG LOG */ - int numLine = 0; + lineCount = 0; FileReader* fileReader = [[FileReader alloc] initWithFilePath:path]; if (!fileReader) { return; } NSString* line = nil; - if ([m_searchBackwards boolValue]) { - while (line = [fileReader readLineBackwards]) { - numLine++; - NSLog(@"%3.d: %@", numLine, line); /* DEBUG LOG */ - if (numLine >= [m_maxNumLines intValue]) { + + + if ([m_printLines boolValue]) { + // Print lines to console. + switch ([m_selectedReadMode intValue]) { + case FORWARDS: + while (line = [fileReader readLine]) { + lineCount++; + NSLog(@"%3.d: %@", lineCount, line); + if (lineCount >= [m_maxNumLines intValue]) { + break; + } + } break; - } - } + case BACKWARDS: + while (line = [fileReader readLineBackwards]) { + lineCount++; + NSLog(@"%3.d: %@", lineCount, line); + if (lineCount >= [m_maxNumLines intValue]) { + break; + } + } + break; + default: + NSLog(@"Warning: Read mode not set correctly."); /* DEBUG LOG */ + break; + } } else { - while (line = [fileReader readLine]) { - numLine++; - NSLog(@"%3.d: %@", numLine, line); /* DEBUG LOG */ - if (numLine >= [m_maxNumLines intValue]) { + // Do not print lines to console. + switch ([m_selectedReadMode intValue]) { + case FORWARDS: + while (line = [fileReader readLine]) { + lineCount++; + if (lineCount >= [m_maxNumLines intValue]) { + break; + } + } + break; + case BACKWARDS: + while (line = [fileReader readLineBackwards]) { + lineCount++; + if (lineCount >= [m_maxNumLines intValue]) { + break; + } + } + break; + default: + NSLog(@"Warning: Read mode not set correctly."); /* DEBUG LOG */ break; - } - } + } - } + } + } } + + NSTimeInterval processingEnded = [NSDate timeIntervalSinceReferenceDate]; + + if ([m_selectedReadMode intValue] == FORWARDS) + self.status = [NSString stringWithFormat:@"Processing %d lines forwards took %f seconds.", lineCount, (processingEnded - processingStarted)]; + else + self.status = [NSString stringWithFormat:@"Processing %d lines backwards took %f seconds.", lineCount, (processingEnded - processingStarted)]; + } @end