Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Implemented NSData backwards search.

+ Added backwards search to FileReader (still experimental).
+ Added backwards search to NSData (approved).
+ Added NSDataExtensions target for testing.
+ Added stepper to user interface to control number of lines.
+ Bugfix: DirectoryReader handles empty path now.
  • Loading branch information...
commit 47b6ee2ff4373c61d7e5692efa0b7b075d05e0ca 1 parent 94dbfa8
Tobias Preuss authored
7 DirectoryReader.m
@@ -24,6 +24,9 @@ - (id)initWithPath:(NSString*)path {
24 24
25 25 self = [super init];
26 26 if (self != nil) {
  27 + if (!path || [path length] <= 0) {
  28 + return nil;
  29 + }
27 30 m_path = path;
28 31 }
29 32 return self;
@@ -36,11 +39,7 @@ - (id)initWithPath:(NSString*)path {
36 39 */
37 40 - (BOOL)readDirectory:(NSArray**)files {
38 41
39   -
40 42 BOOL success = false;
41   - if (!m_path) {
42   - return success;
43   - }
44 43
45 44 NSArray* fileNames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:m_path error:nil];
46 45
193 English.lproj/MainMenu.xib
@@ -12,7 +12,7 @@
12 12 </object>
13 13 <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
14 14 <bool key="EncodedWithXMLCoder">YES</bool>
15   - <integer value="372"/>
  15 + <integer value="371"/>
16 16 </object>
17 17 <object class="NSArray" key="IBDocument.PluginDependencies">
18 18 <bool key="EncodedWithXMLCoder">YES</bool>
@@ -1317,7 +1317,7 @@
1317 1317 <object class="NSWindowTemplate" id="972006081">
1318 1318 <int key="NSWindowStyleMask">15</int>
1319 1319 <int key="NSWindowBacking">2</int>
1320   - <string key="NSWindowRect">{{335, 74}, {499, 676}}</string>
  1320 + <string key="NSWindowRect">{{781, 326}, {499, 676}}</string>
1321 1321 <int key="NSWTFlags">1954021376</int>
1322 1322 <string key="NSWindowTitle">LineReader</string>
1323 1323 <string key="NSWindowClass">NSWindow</string>
@@ -1331,13 +1331,13 @@
1331 1331 <object class="NSTextField" id="231717339">
1332 1332 <reference key="NSNextResponder" ref="439893737"/>
1333 1333 <int key="NSvFlags">268</int>
1334   - <string key="NSFrame">{{130, 634}, {349, 22}}</string>
  1334 + <string key="NSFrame">{{20, 606}, {459, 22}}</string>
1335 1335 <reference key="NSSuperview" ref="439893737"/>
1336 1336 <bool key="NSEnabled">YES</bool>
1337 1337 <object class="NSTextFieldCell" key="NSCell" id="355415411">
1338 1338 <int key="NSCellFlags">-1804468671</int>
1339 1339 <int key="NSCellFlags2">272630784</int>
1340   - <string key="NSContents">/tmp/</string>
  1340 + <string key="NSContents"/>
1341 1341 <object class="NSFont" key="NSSupport" id="953681415">
1342 1342 <string key="NSName">LucidaGrande</string>
1343 1343 <double key="NSSize">13</double>
@@ -1377,7 +1377,7 @@
1377 1377 <string key="NSContents">Directory path:</string>
1378 1378 <reference key="NSSupport" ref="953681415"/>
1379 1379 <reference key="NSControlView" ref="1045706751"/>
1380   - <object class="NSColor" key="NSBackgroundColor">
  1380 + <object class="NSColor" key="NSBackgroundColor" id="685989597">
1381 1381 <int key="NSColorSpace">6</int>
1382 1382 <string key="NSCatalogName">System</string>
1383 1383 <string key="NSColorName">controlColor</string>
@@ -1386,7 +1386,7 @@
1386 1386 <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
1387 1387 </object>
1388 1388 </object>
1389   - <object class="NSColor" key="NSTextColor">
  1389 + <object class="NSColor" key="NSTextColor" id="249716613">
1390 1390 <int key="NSColorSpace">6</int>
1391 1391 <string key="NSCatalogName">System</string>
1392 1392 <string key="NSColorName">controlTextColor</string>
@@ -1394,11 +1394,59 @@
1394 1394 </object>
1395 1395 </object>
1396 1396 </object>
  1397 + <object class="NSStepper" id="1013929455">
  1398 + <reference key="NSNextResponder" ref="439893737"/>
  1399 + <int key="NSvFlags">268</int>
  1400 + <string key="NSFrame">{{463, 548}, {19, 27}}</string>
  1401 + <reference key="NSSuperview" ref="439893737"/>
  1402 + <bool key="NSEnabled">YES</bool>
  1403 + <object class="NSStepperCell" key="NSCell" id="372307018">
  1404 + <int key="NSCellFlags">917024</int>
  1405 + <int key="NSCellFlags2">0</int>
  1406 + <reference key="NSControlView" ref="1013929455"/>
  1407 + <double key="NSMaxValue">100</double>
  1408 + <double key="NSIncrement">1</double>
  1409 + <bool key="NSAutorepeat">YES</bool>
  1410 + </object>
  1411 + </object>
  1412 + <object class="NSTextField" id="293172749">
  1413 + <reference key="NSNextResponder" ref="439893737"/>
  1414 + <int key="NSvFlags">268</int>
  1415 + <string key="NSFrame">{{17, 553}, {444, 17}}</string>
  1416 + <reference key="NSSuperview" ref="439893737"/>
  1417 + <bool key="NSEnabled">YES</bool>
  1418 + <object class="NSTextFieldCell" key="NSCell" id="844018831">
  1419 + <int key="NSCellFlags">68288064</int>
  1420 + <int key="NSCellFlags2">71304192</int>
  1421 + <string key="NSContents">Count</string>
  1422 + <reference key="NSSupport" ref="953681415"/>
  1423 + <reference key="NSControlView" ref="293172749"/>
  1424 + <bool key="NSDrawsBackground">YES</bool>
  1425 + <reference key="NSBackgroundColor" ref="685989597"/>
  1426 + <reference key="NSTextColor" ref="249716613"/>
  1427 + </object>
  1428 + </object>
  1429 + <object class="NSTextField" id="449809172">
  1430 + <reference key="NSNextResponder" ref="439893737"/>
  1431 + <int key="NSvFlags">268</int>
  1432 + <string key="NSFrame">{{17, 581}, {465, 17}}</string>
  1433 + <reference key="NSSuperview" ref="439893737"/>
  1434 + <bool key="NSEnabled">YES</bool>
  1435 + <object class="NSTextFieldCell" key="NSCell" id="630023291">
  1436 + <int key="NSCellFlags">68288064</int>
  1437 + <int key="NSCellFlags2">272630784</int>
  1438 + <string key="NSContents">Numbers of lines per file:</string>
  1439 + <reference key="NSSupport" ref="953681415"/>
  1440 + <reference key="NSControlView" ref="449809172"/>
  1441 + <reference key="NSBackgroundColor" ref="685989597"/>
  1442 + <reference key="NSTextColor" ref="249716613"/>
  1443 + </object>
  1444 + </object>
1397 1445 </object>
1398 1446 <string key="NSFrameSize">{499, 676}</string>
1399 1447 <reference key="NSSuperview"/>
1400 1448 </object>
1401   - <string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
  1449 + <string key="NSScreenRect">{{0, 0}, {1280, 1002}}</string>
1402 1450 <string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
1403 1451 </object>
1404 1452 <object class="NSCustomObject" id="976324537">
@@ -2100,12 +2148,52 @@
2100 2148 <int key="connectionID">546</int>
2101 2149 </object>
2102 2150 <object class="IBConnectionRecord">
2103   - <object class="IBOutletConnection" key="connection">
2104   - <string key="label">m_sourcePath</string>
2105   - <reference key="source" ref="976324537"/>
2106   - <reference key="destination" ref="231717339"/>
  2151 + <object class="IBBindingConnection" key="connection">
  2152 + <string key="label">value: maxNumLines</string>
  2153 + <reference key="source" ref="1013929455"/>
  2154 + <reference key="destination" ref="976324537"/>
  2155 + <object class="NSNibBindingConnector" key="connector">
  2156 + <reference key="NSSource" ref="1013929455"/>
  2157 + <reference key="NSDestination" ref="976324537"/>
  2158 + <string key="NSLabel">value: maxNumLines</string>
  2159 + <string key="NSBinding">value</string>
  2160 + <string key="NSKeyPath">maxNumLines</string>
  2161 + <int key="NSNibBindingConnectorVersion">2</int>
  2162 + </object>
2107 2163 </object>
2108   - <int key="connectionID">547</int>
  2164 + <int key="connectionID">557</int>
  2165 + </object>
  2166 + <object class="IBConnectionRecord">
  2167 + <object class="IBBindingConnection" key="connection">
  2168 + <string key="label">value: maxNumLines</string>
  2169 + <reference key="source" ref="844018831"/>
  2170 + <reference key="destination" ref="976324537"/>
  2171 + <object class="NSNibBindingConnector" key="connector">
  2172 + <reference key="NSSource" ref="844018831"/>
  2173 + <reference key="NSDestination" ref="976324537"/>
  2174 + <string key="NSLabel">value: maxNumLines</string>
  2175 + <string key="NSBinding">value</string>
  2176 + <string key="NSKeyPath">maxNumLines</string>
  2177 + <int key="NSNibBindingConnectorVersion">2</int>
  2178 + </object>
  2179 + </object>
  2180 + <int key="connectionID">558</int>
  2181 + </object>
  2182 + <object class="IBConnectionRecord">
  2183 + <object class="IBBindingConnection" key="connection">
  2184 + <string key="label">value: sourcePath</string>
  2185 + <reference key="source" ref="355415411"/>
  2186 + <reference key="destination" ref="976324537"/>
  2187 + <object class="NSNibBindingConnector" key="connector">
  2188 + <reference key="NSSource" ref="355415411"/>
  2189 + <reference key="NSDestination" ref="976324537"/>
  2190 + <string key="NSLabel">value: sourcePath</string>
  2191 + <string key="NSBinding">value</string>
  2192 + <string key="NSKeyPath">sourcePath</string>
  2193 + <int key="NSNibBindingConnectorVersion">2</int>
  2194 + </object>
  2195 + </object>
  2196 + <int key="connectionID">559</int>
2109 2197 </object>
2110 2198 </object>
2111 2199 <object class="IBMutableOrderedSet" key="objectRecords">
@@ -2664,6 +2752,9 @@
2664 2752 <bool key="EncodedWithXMLCoder">YES</bool>
2665 2753 <reference ref="1045706751"/>
2666 2754 <reference ref="231717339"/>
  2755 + <reference ref="449809172"/>
  2756 + <reference ref="1013929455"/>
  2757 + <reference ref="293172749"/>
2667 2758 </object>
2668 2759 <reference key="parent" ref="972006081"/>
2669 2760 </object>
@@ -3181,6 +3272,48 @@
3181 3272 <reference key="object" ref="183607361"/>
3182 3273 <reference key="parent" ref="1045706751"/>
3183 3274 </object>
  3275 + <object class="IBObjectRecord">
  3276 + <int key="objectID">549</int>
  3277 + <reference key="object" ref="1013929455"/>
  3278 + <object class="NSMutableArray" key="children">
  3279 + <bool key="EncodedWithXMLCoder">YES</bool>
  3280 + <reference ref="372307018"/>
  3281 + </object>
  3282 + <reference key="parent" ref="439893737"/>
  3283 + </object>
  3284 + <object class="IBObjectRecord">
  3285 + <int key="objectID">550</int>
  3286 + <reference key="object" ref="372307018"/>
  3287 + <reference key="parent" ref="1013929455"/>
  3288 + </object>
  3289 + <object class="IBObjectRecord">
  3290 + <int key="objectID">551</int>
  3291 + <reference key="object" ref="293172749"/>
  3292 + <object class="NSMutableArray" key="children">
  3293 + <bool key="EncodedWithXMLCoder">YES</bool>
  3294 + <reference ref="844018831"/>
  3295 + </object>
  3296 + <reference key="parent" ref="439893737"/>
  3297 + </object>
  3298 + <object class="IBObjectRecord">
  3299 + <int key="objectID">552</int>
  3300 + <reference key="object" ref="844018831"/>
  3301 + <reference key="parent" ref="293172749"/>
  3302 + </object>
  3303 + <object class="IBObjectRecord">
  3304 + <int key="objectID">553</int>
  3305 + <reference key="object" ref="449809172"/>
  3306 + <object class="NSMutableArray" key="children">
  3307 + <bool key="EncodedWithXMLCoder">YES</bool>
  3308 + <reference ref="630023291"/>
  3309 + </object>
  3310 + <reference key="parent" ref="439893737"/>
  3311 + </object>
  3312 + <object class="IBObjectRecord">
  3313 + <int key="objectID">554</int>
  3314 + <reference key="object" ref="630023291"/>
  3315 + <reference key="parent" ref="449809172"/>
  3316 + </object>
3184 3317 </object>
3185 3318 </object>
3186 3319 <object class="NSMutableDictionary" key="flattenedProperties">
@@ -3408,6 +3541,12 @@
3408 3541 <string>534.IBPluginDependency</string>
3409 3542 <string>535.IBPluginDependency</string>
3410 3543 <string>536.IBPluginDependency</string>
  3544 + <string>549.IBPluginDependency</string>
  3545 + <string>550.IBPluginDependency</string>
  3546 + <string>551.IBPluginDependency</string>
  3547 + <string>552.IBPluginDependency</string>
  3548 + <string>553.IBPluginDependency</string>
  3549 + <string>554.IBPluginDependency</string>
3411 3550 <string>56.IBPluginDependency</string>
3412 3551 <string>56.ImportedFromIB2</string>
3413 3552 <string>57.IBEditorWindowLastContentRect</string>
@@ -3574,9 +3713,9 @@
3574 3713 <integer value="1"/>
3575 3714 <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
3576 3715 <integer value="1"/>
3577   - <string>{{382, 248}, {499, 676}}</string>
  3716 + <string>{{403, 304}, {499, 676}}</string>
3578 3717 <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
3579   - <string>{{382, 248}, {499, 676}}</string>
  3718 + <string>{{403, 304}, {499, 676}}</string>
3580 3719 <integer value="1"/>
3581 3720 <string>{{33, 99}, {480, 360}}</string>
3582 3721 <string>{3.40282e+38, 3.40282e+38}</string>
@@ -3667,6 +3806,12 @@
3667 3806 <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
3668 3807 <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
3669 3808 <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
  3809 + <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
  3810 + <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
  3811 + <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
  3812 + <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
  3813 + <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
  3814 + <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
3670 3815 <integer value="1"/>
3671 3816 <string>{{286, 129}, {275, 183}}</string>
3672 3817 <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -3718,7 +3863,7 @@
3718 3863 </object>
3719 3864 </object>
3720 3865 <nil key="sourceID"/>
3721   - <int key="maxID">548</int>
  3866 + <int key="maxID">559</int>
3722 3867 </object>
3723 3868 <object class="IBClassDescriber" key="IBDocument.Classes">
3724 3869 <object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -3735,13 +3880,11 @@
3735 3880 <object class="NSArray" key="dict.sortedKeys">
3736 3881 <bool key="EncodedWithXMLCoder">YES</bool>
3737 3882 <string>m_sourcePath</string>
3738   - <string>m_tableView</string>
3739 3883 <string>window</string>
3740 3884 </object>
3741 3885 <object class="NSMutableArray" key="dict.values">
3742 3886 <bool key="EncodedWithXMLCoder">YES</bool>
3743 3887 <string>NSTextField</string>
3744   - <string>NSTableView</string>
3745 3888 <string>NSWindow</string>
3746 3889 </object>
3747 3890 </object>
@@ -4202,6 +4345,22 @@
4202 4345 </object>
4203 4346 </object>
4204 4347 <object class="IBPartialClassDescription">
  4348 + <string key="className">NSStepper</string>
  4349 + <string key="superclassName">NSControl</string>
  4350 + <object class="IBClassDescriptionSource" key="sourceIdentifier">
  4351 + <string key="majorKey">IBFrameworkSource</string>
  4352 + <string key="minorKey">AppKit.framework/Headers/NSStepper.h</string>
  4353 + </object>
  4354 + </object>
  4355 + <object class="IBPartialClassDescription">
  4356 + <string key="className">NSStepperCell</string>
  4357 + <string key="superclassName">NSActionCell</string>
  4358 + <object class="IBClassDescriptionSource" key="sourceIdentifier">
  4359 + <string key="majorKey">IBFrameworkSource</string>
  4360 + <string key="minorKey">AppKit.framework/Headers/NSStepperCell.h</string>
  4361 + </object>
  4362 + </object>
  4363 + <object class="IBPartialClassDescription">
4205 4364 <string key="className">NSTableView</string>
4206 4365 <string key="superclassName">NSControl</string>
4207 4366 <reference key="sourceIdentifier" ref="809545482"/>
5 FileReader.h
@@ -5,8 +5,8 @@
5 5 // Created by Tobias Preuss on 05.10.10.
6 6 // Copyright 2010 Tobias Preuss. All rights reserved.
7 7 //
8   -// Source: Dave DeLong, http://stackoverflow.com/questions/3707427#3711079
9   -
  8 +// Originally written by Dave DeLong,
  9 +// Source: http://stackoverflow.com/questions/3707427#3711079
10 10
11 11 #import <Cocoa/Cocoa.h>
12 12
@@ -26,6 +26,7 @@
26 26
27 27 - (id)initWithFilePath:(NSString*)filePath;
28 28 - (NSString*)readLine;
  29 +- (NSString*)readLineBackwards;
29 30 - (NSString*)readTrimmedLine;
30 31
31 32 #if NS_BLOCKS_AVAILABLE
147 FileReader.m
@@ -5,7 +5,8 @@
5 5 // Created by Tobias Preuss on 05.10.10.
6 6 // Copyright 2010 Tobias Preuss. All rights reserved.
7 7 //
8   -// Source: Dave DeLong, http://stackoverflow.com/questions/3707427#3711079
  8 +// Originally written by Dave DeLong,
  9 +// Source: http://stackoverflow.com/questions/3707427#3711079
9 10
10 11
11 12 #import "FileReader.h"
@@ -13,33 +14,39 @@
13 14
14 15
15 16 // -----------------------------------------------------------------------------
16   -// NSData extension.
  17 +// NSData extensions declaration.
17 18 // -----------------------------------------------------------------------------
18 19
19 20
20 21 @interface NSData (Additions)
21 22
22 23 - (NSRange)rangeOfData:(NSData*)dataToFind;
  24 +- (NSRange)rangeOfDataBackwardsSearch:(NSData*)dataToFind;
  25 +- (NSString*)stringValueWithEncoding:(NSStringEncoding)encoding;
23 26
24 27 @end
25 28
26 29
  30 +// -----------------------------------------------------------------------------
  31 +// NSData extensions implementation.
  32 +// -----------------------------------------------------------------------------
  33 +
  34 +
27 35
28 36 /**
29   - Extension of the NSData class.
30   - @param Additions Additions.
31   - @returns An initialized NSData object or nil if the object could not be created.
  37 + Extension of the NSData class.
  38 + @param Additions Additions.
  39 + @returns An initialized NSData object or nil if the object could not be created.
32 40 */
33 41 @implementation NSData (Additions)
34 42
35 43
36 44 /**
37   - Returns a range of data.
38   - @param dataToFind Data object specifying the delimiter and encoding.
39   - @returns A range.
  45 + Returns a range of data.
  46 + @param dataToFind Data object specifying the delimiter and encoding.
  47 + @returns A range.
40 48 */
41 49 - (NSRange)rangeOfData:(NSData*)dataToFind {
42   -
43 50
44 51 const void* bytes = [self bytes];
45 52 NSUInteger length = [self length];
@@ -49,17 +56,63 @@ - (NSRange)rangeOfData:(NSData*)dataToFind {
49 56
50 57 NSRange foundRange = {NSNotFound, searchLength};
51 58 for (NSUInteger index = 0; index < length; index++) {
  59 + // The current character matches.
  60 + if (((char*)bytes)[index] == ((char*)searchBytes)[searchIndex]) {
  61 + // Store found location if not done earlier.
  62 + if (foundRange.location == NSNotFound) {
  63 + foundRange.location = index;
  64 + }
  65 + // Increment search character index to check for match.
  66 + searchIndex++;
  67 + // All search character match.
  68 + // Break search routine and return found position.
  69 + if (searchIndex >= searchLength) {
  70 + return foundRange;
  71 + }
  72 + }
  73 + // Match does not continue.
  74 + // Return to the first search character.
  75 + // Discard former found location.
  76 + else {
  77 + searchIndex = 0;
  78 + foundRange.location = NSNotFound;
  79 + }
  80 + }
  81 + return foundRange;
  82 +}
  83 +
  84 +
  85 +- (NSRange)rangeOfDataBackwardsSearch:(NSData*)dataToFind {
  86 +
  87 + const void* bytes = [self bytes];
  88 + NSUInteger length = [self length];
  89 + const void* searchBytes = [dataToFind bytes];
  90 + NSUInteger searchLength = [dataToFind length];
  91 + NSUInteger searchIndex = 0;
  92 +
  93 + NSRange foundRange = {NSNotFound, searchLength};
  94 + for (NSUInteger index = length - searchLength; index >= 0;) {
52 95 if (((char*)bytes)[index] == ((char*)searchBytes)[searchIndex]) {
53 96 // The current character matches.
54 97 if (foundRange.location == NSNotFound) {
55 98 foundRange.location = index;
56 99 }
  100 + index++;
57 101 searchIndex++;
58 102 if (searchIndex >= searchLength) {
59 103 return foundRange;
60 104 }
61 105 }
62 106 else {
  107 + // Decrement to search backwards.
  108 + if (foundRange.location == NSNotFound) {
  109 + index--;
  110 + }
  111 + // Jump over the former found location
  112 + // to avoid endless loop.
  113 + else {
  114 + index = index - 2;
  115 + }
63 116 searchIndex = 0;
64 117 foundRange.location = NSNotFound;
65 118 }
@@ -67,13 +120,18 @@ - (NSRange)rangeOfData:(NSData*)dataToFind {
67 120 return foundRange;
68 121 }
69 122
  123 +- (NSString*)stringValueWithEncoding:(NSStringEncoding)encoding {
  124 + return [[NSString alloc] initWithData:self encoding:encoding];
  125 +}
  126 +
70 127 @end
71 128
72 129
73 130
74 131
  132 +
75 133 // -----------------------------------------------------------------------------
76   -// FileReader class.
  134 +// FileReader implementation.
77 135 // -----------------------------------------------------------------------------
78 136
79 137
@@ -96,31 +154,36 @@ @implementation FileReader
96 154 */
97 155 - (id)initWithFilePath:(NSString*)filePath {
98 156
99   -
100 157 self = [super init];
101 158 if (self != nil) {
  159 + if (!filePath || [filePath length] <= 0) {
  160 + return nil;
  161 + }
102 162 m_fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
103 163 if (m_fileHandle == nil) {
104 164 return nil;
105 165 }
  166 + // TODO: How can I use NSLineSeparatorCharacter instead of \n here?
106 167 m_lineDelimiter = [[NSString alloc] initWithString:@"\n"];
107 168 m_filePath = filePath;
108 169 m_currentOffset = 0ULL;
109 170 m_chunkSize = 10;
110 171 [m_fileHandle seekToEndOfFile];
111 172 m_totalFileLength = [m_fileHandle offsetInFile];
  173 + NSLog(@"%qu characters in %@", m_totalFileLength, [filePath lastPathComponent]); /* DEBUG LOG */
112 174 // We do not need to seek back since readLine will do that.
113 175 }
114 176 return self;
115 177 }
116 178
  179 +
  180 +
117 181 /**
118 182 Reads the file forwards.
119 183 @returns Another single line on each call or nil if the file end has been reached.
120 184 */
121 185 - (NSString*)readLine {
122 186
123   -
124 187 if (m_currentOffset >= m_totalFileLength) {
125 188 return nil;
126 189 }
@@ -134,32 +197,83 @@ - (NSString*)readLine {
134 197 if (m_currentOffset >= m_totalFileLength) {
135 198 break;
136 199 }
137   - NSData* chunk = [m_fileHandle readDataOfLength:m_chunkSize];
  200 + NSLog(@"\t m_currentOffset: %qu", m_currentOffset); /* DEBUG LOG */
  201 + NSData* chunk = [m_fileHandle readDataOfLength:m_chunkSize]; // always length = 10
  202 + // Find the location and length of the next line delimiter.
138 203 NSRange newLineRange = [chunk rangeOfData:newLineData];
  204 + NSLog(@"\t\t newLineRange: %d (%d)", newLineRange.location, newLineRange.length); /* DEBUG LOG */
139 205 if (newLineRange.location != NSNotFound) {
140 206 // Include the length so we can include the delimiter in the string.
141   - chunk = [chunk subdataWithRange:NSMakeRange(0, newLineRange.location + [newLineData length])];
  207 + NSRange subDataRange = NSMakeRange(0, newLineRange.location + [newLineData length]);
  208 + NSLog(@"\t\t subDataRange: %d (%d)", subDataRange.location, subDataRange.length); /* DEBUG LOG */
  209 + chunk = [chunk subdataWithRange:subDataRange];
  210 + NSLog(@"\t\t\t\t chunk: %@", [chunk stringValueWithEncoding:NSUTF8StringEncoding]); /* DEBUG LOG */
142 211 shouldReadMore = NO;
143 212 }
144 213 [currentData appendData:chunk];
  214 + NSLog(@"\t\t currentData: %@", [currentData stringValueWithEncoding:NSUTF8StringEncoding]); /* DEBUG LOG */
145 215 m_currentOffset += [chunk length];
146 216 }
147 217
148   - NSString* line = [[NSString alloc] initWithData:currentData encoding:NSUTF8StringEncoding];
  218 + NSString* line = [currentData stringValueWithEncoding:NSUTF8StringEncoding];
149 219 return line;
150 220 }
151 221
  222 +
  223 +
  224 +
  225 +- (NSString*)readLineBackwards {
  226 +
  227 + if (m_currentOffset >= m_totalFileLength) {
  228 + return nil;
  229 + }
  230 +
  231 + NSData* newLineData = [m_lineDelimiter dataUsingEncoding:NSUTF8StringEncoding];
  232 + m_currentOffset = m_totalFileLength - m_chunkSize;
  233 + [m_fileHandle seekToFileOffset:m_currentOffset];
  234 + NSMutableData* currentData = [[NSMutableData alloc] init];
  235 + BOOL shouldReadMore = YES;
  236 +
  237 + while (shouldReadMore) {
  238 +// if (m_currentOffset >= m_totalFileLength) {
  239 +// break;
  240 +// }
  241 + NSLog(@"\t m_currentOffset: %qu", m_currentOffset); /* DEBUG LOG */
  242 + if (m_currentOffset <= 0ULL) {
  243 + break;
  244 + }
  245 + NSData* chunk = [m_fileHandle readDataOfLength:m_chunkSize];
  246 + NSLog(@"chunk: %@", [chunk stringValueWithEncoding:NSUTF8StringEncoding]); /* DEBUG LOG */
  247 + // Find the location and length of the next line delimiter.
  248 + NSRange newLineRange = [chunk rangeOfDataBackwardsSearch:newLineData];
  249 + NSLog(@"\t\t newLineRange: %d (%d)", newLineRange.location, newLineRange.length); /* DEBUG LOG */
  250 + if (newLineRange.location != NSNotFound) {
  251 + // Include the length so we can include the delimiter in the string.
  252 + NSUInteger chunkLength = newLineRange.location - [newLineData length];
  253 + chunk = [chunk subdataWithRange:NSMakeRange(m_currentOffset - chunkLength, chunkLength)];
  254 + shouldReadMore = NO;
  255 + }
  256 + [currentData appendData:chunk];
  257 + m_currentOffset -= [chunk length];
  258 + }
  259 +
  260 + NSString* line = [[NSString alloc] initWithData:currentData encoding:NSUTF8StringEncoding];
  261 + return line;
  262 +}
  263 +
  264 +
  265 +
152 266 /**
153 267 Reads the file forwards while trimming white spaces.
154 268 @returns Another single line on each call or nil if the file end has been reached.
155 269 */
156 270 - (NSString*)readTrimmedLine {
157   -
158 271
159 272 return [[self readLine] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
160 273 }
161 274
162 275
  276 +
163 277 #if NS_BLOCKS_AVAILABLE
164 278 /**
165 279 Reads the file forwards using a block object.
@@ -177,3 +291,4 @@ - (void)enumerateLinesUsingBlock:(void(^)(NSString*, BOOL*))block {
177 291
178 292
179 293 @end
  294 +
143 LineReader.xcodeproj/project.pbxproj
@@ -9,8 +9,11 @@
9 9 /* Begin PBXBuildFile section */
10 10 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58140DA1D0A300B32029 /* MainMenu.xib */; };
11 11 256AC3DA0F4B6AC300CF3369 /* LineReaderAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 256AC3D90F4B6AC300CF3369 /* LineReaderAppDelegate.m */; };
12   - 5548D857125B69B6001C6932 /* FileReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 5548D856125B69B6001C6932 /* FileReader.m */; };
13   - 558DC637125B369600AF819E /* DirectoryReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 558DC636125B369600AF819E /* DirectoryReader.m */; };
  12 + 557E504F125CD4350055E512 /* DirectoryReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 557E504C125CD4350055E512 /* DirectoryReader.m */; };
  13 + 557E5050125CD4350055E512 /* FileReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 557E504E125CD4350055E512 /* FileReader.m */; };
  14 + 557E508E125CD5B80055E512 /* NSDataExtensionsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 557E508C125CD5890055E512 /* NSDataExtensionsTest.m */; };
  15 + 55A52E1D125CDC7A00A9C721 /* FileReader.h in Sources */ = {isa = PBXBuildFile; fileRef = 557E504D125CD4350055E512 /* FileReader.h */; };
  16 + 55A52E1E125CDC7A00A9C721 /* FileReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 557E504E125CD4350055E512 /* FileReader.m */; };
14 17 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
15 18 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
16 19 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
@@ -27,15 +30,25 @@
27 30 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
28 31 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
29 32 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
30   - 5548D855125B69B6001C6932 /* FileReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileReader.h; sourceTree = "<group>"; };
31   - 5548D856125B69B6001C6932 /* FileReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileReader.m; sourceTree = "<group>"; };
32   - 558DC635125B369600AF819E /* DirectoryReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryReader.h; sourceTree = "<group>"; };
33   - 558DC636125B369600AF819E /* DirectoryReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DirectoryReader.m; sourceTree = "<group>"; };
  33 + 557E504B125CD4350055E512 /* DirectoryReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryReader.h; sourceTree = "<group>"; };
  34 + 557E504C125CD4350055E512 /* DirectoryReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DirectoryReader.m; sourceTree = "<group>"; };
  35 + 557E504D125CD4350055E512 /* FileReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileReader.h; sourceTree = "<group>"; };
  36 + 557E504E125CD4350055E512 /* FileReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileReader.m; sourceTree = "<group>"; };
  37 + 557E5077125CD51D0055E512 /* NSDataExtensions.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NSDataExtensions.app; sourceTree = BUILT_PRODUCTS_DIR; };
  38 + 557E5079125CD51E0055E512 /* NSDataExtensions-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "NSDataExtensions-Info.plist"; sourceTree = "<group>"; };
  39 + 557E508C125CD5890055E512 /* NSDataExtensionsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSDataExtensionsTest.m; sourceTree = "<group>"; };
34 40 8D1107310486CEB800E47090 /* LineReader-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "LineReader-Info.plist"; sourceTree = "<group>"; };
35 41 8D1107320486CEB800E47090 /* LineReader.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LineReader.app; sourceTree = BUILT_PRODUCTS_DIR; };
36 42 /* End PBXFileReference section */
37 43
38 44 /* Begin PBXFrameworksBuildPhase section */
  45 + 557E5075125CD51D0055E512 /* Frameworks */ = {
  46 + isa = PBXFrameworksBuildPhase;
  47 + buildActionMask = 2147483647;
  48 + files = (
  49 + );
  50 + runOnlyForDeploymentPostprocessing = 0;
  51 + };
39 52 8D11072E0486CEB800E47090 /* Frameworks */ = {
40 53 isa = PBXFrameworksBuildPhase;
41 54 buildActionMask = 2147483647;
@@ -52,10 +65,11 @@
52 65 children = (
53 66 256AC3D80F4B6AC300CF3369 /* LineReaderAppDelegate.h */,
54 67 256AC3D90F4B6AC300CF3369 /* LineReaderAppDelegate.m */,
55   - 558DC635125B369600AF819E /* DirectoryReader.h */,
56   - 558DC636125B369600AF819E /* DirectoryReader.m */,
57   - 5548D855125B69B6001C6932 /* FileReader.h */,
58   - 5548D856125B69B6001C6932 /* FileReader.m */,
  68 + 557E504B125CD4350055E512 /* DirectoryReader.h */,
  69 + 557E504C125CD4350055E512 /* DirectoryReader.m */,
  70 + 557E504D125CD4350055E512 /* FileReader.h */,
  71 + 557E504E125CD4350055E512 /* FileReader.m */,
  72 + 557E508A125CD56B0055E512 /* Testing */,
59 73 );
60 74 name = Classes;
61 75 sourceTree = "<group>";
@@ -82,6 +96,7 @@
82 96 isa = PBXGroup;
83 97 children = (
84 98 8D1107320486CEB800E47090 /* LineReader.app */,
  99 + 557E5077125CD51D0055E512 /* NSDataExtensions.app */,
85 100 );
86 101 name = Products;
87 102 sourceTree = "<group>";
@@ -111,6 +126,7 @@
111 126 isa = PBXGroup;
112 127 children = (
113 128 8D1107310486CEB800E47090 /* LineReader-Info.plist */,
  129 + 557E5079125CD51E0055E512 /* NSDataExtensions-Info.plist */,
114 130 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
115 131 1DDD58140DA1D0A300B32029 /* MainMenu.xib */,
116 132 );
@@ -126,9 +142,35 @@
126 142 name = Frameworks;
127 143 sourceTree = "<group>";
128 144 };
  145 + 557E508A125CD56B0055E512 /* Testing */ = {
  146 + isa = PBXGroup;
  147 + children = (
  148 + 557E508C125CD5890055E512 /* NSDataExtensionsTest.m */,
  149 + );
  150 + name = Testing;
  151 + sourceTree = "<group>";
  152 + };
129 153 /* End PBXGroup section */
130 154
131 155 /* Begin PBXNativeTarget section */
  156 + 557E5076125CD51D0055E512 /* NSDataExtensions */ = {
  157 + isa = PBXNativeTarget;
  158 + buildConfigurationList = 557E507C125CD51E0055E512 /* Build configuration list for PBXNativeTarget "NSDataExtensions" */;
  159 + buildPhases = (
  160 + 557E5073125CD51D0055E512 /* Resources */,
  161 + 557E5074125CD51D0055E512 /* Sources */,
  162 + 557E5075125CD51D0055E512 /* Frameworks */,
  163 + );
  164 + buildRules = (
  165 + );
  166 + comments = "Test for NSDataExtensions Backwards search.";
  167 + dependencies = (
  168 + );
  169 + name = NSDataExtensions;
  170 + productName = NSDataExtensions;
  171 + productReference = 557E5077125CD51D0055E512 /* NSDataExtensions.app */;
  172 + productType = "com.apple.product-type.application";
  173 + };
132 174 8D1107260486CEB800E47090 /* LineReader */ = {
133 175 isa = PBXNativeTarget;
134 176 buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "LineReader" */;
@@ -163,11 +205,19 @@
163 205 projectRoot = "";
164 206 targets = (
165 207 8D1107260486CEB800E47090 /* LineReader */,
  208 + 557E5076125CD51D0055E512 /* NSDataExtensions */,
166 209 );
167 210 };
168 211 /* End PBXProject section */
169 212
170 213 /* Begin PBXResourcesBuildPhase section */
  214 + 557E5073125CD51D0055E512 /* Resources */ = {
  215 + isa = PBXResourcesBuildPhase;
  216 + buildActionMask = 2147483647;
  217 + files = (
  218 + );
  219 + runOnlyForDeploymentPostprocessing = 0;
  220 + };
171 221 8D1107290486CEB800E47090 /* Resources */ = {
172 222 isa = PBXResourcesBuildPhase;
173 223 buildActionMask = 2147483647;
@@ -180,14 +230,24 @@
180 230 /* End PBXResourcesBuildPhase section */
181 231
182 232 /* Begin PBXSourcesBuildPhase section */
  233 + 557E5074125CD51D0055E512 /* Sources */ = {
  234 + isa = PBXSourcesBuildPhase;
  235 + buildActionMask = 2147483647;
  236 + files = (
  237 + 55A52E1D125CDC7A00A9C721 /* FileReader.h in Sources */,
  238 + 55A52E1E125CDC7A00A9C721 /* FileReader.m in Sources */,
  239 + 557E508E125CD5B80055E512 /* NSDataExtensionsTest.m in Sources */,
  240 + );
  241 + runOnlyForDeploymentPostprocessing = 0;
  242 + };
183 243 8D11072C0486CEB800E47090 /* Sources */ = {
184 244 isa = PBXSourcesBuildPhase;
185 245 buildActionMask = 2147483647;
186 246 files = (
187 247 8D11072D0486CEB800E47090 /* main.m in Sources */,
188 248 256AC3DA0F4B6AC300CF3369 /* LineReaderAppDelegate.m in Sources */,
189   - 558DC637125B369600AF819E /* DirectoryReader.m in Sources */,
190   - 5548D857125B69B6001C6932 /* FileReader.m in Sources */,
  249 + 557E504F125CD4350055E512 /* DirectoryReader.m in Sources */,
  250 + 557E5050125CD4350055E512 /* FileReader.m in Sources */,
191 251 );
192 252 runOnlyForDeploymentPostprocessing = 0;
193 253 };
@@ -213,6 +273,56 @@
213 273 /* End PBXVariantGroup section */
214 274
215 275 /* Begin XCBuildConfiguration section */
  276 + 557E507A125CD51E0055E512 /* Debug */ = {
  277 + isa = XCBuildConfiguration;
  278 + buildSettings = {
  279 + ALWAYS_SEARCH_USER_PATHS = NO;
  280 + COPY_PHASE_STRIP = NO;
  281 + GCC_DYNAMIC_NO_PIC = NO;
  282 + GCC_ENABLE_FIX_AND_CONTINUE = YES;
  283 + GCC_ENABLE_OBJC_GC = required;
  284 + GCC_MODEL_TUNING = G5;
  285 + GCC_OPTIMIZATION_LEVEL = 0;
  286 + GCC_PRECOMPILE_PREFIX_HEADER = YES;
  287 + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
  288 + INFOPLIST_FILE = "NSDataExtensions-Info.plist";
  289 + INSTALL_PATH = "$(HOME)/Applications";
  290 + OTHER_LDFLAGS = (
  291 + "-framework",
  292 + Foundation,
  293 + "-framework",
  294 + AppKit,
  295 + );
  296 + PREBINDING = NO;
  297 + PRODUCT_NAME = NSDataExtensions;
  298 + };
  299 + name = Debug;
  300 + };
  301 + 557E507B125CD51E0055E512 /* Release */ = {
  302 + isa = XCBuildConfiguration;
  303 + buildSettings = {
  304 + ALWAYS_SEARCH_USER_PATHS = NO;
  305 + COPY_PHASE_STRIP = YES;
  306 + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
  307 + GCC_ENABLE_FIX_AND_CONTINUE = NO;
  308 + GCC_ENABLE_OBJC_GC = required;
  309 + GCC_MODEL_TUNING = G5;
  310 + GCC_PRECOMPILE_PREFIX_HEADER = YES;
  311 + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
  312 + INFOPLIST_FILE = "NSDataExtensions-Info.plist";
  313 + INSTALL_PATH = "$(HOME)/Applications";
  314 + OTHER_LDFLAGS = (
  315 + "-framework",
  316 + Foundation,
  317 + "-framework",
  318 + AppKit,
  319 + );
  320 + PREBINDING = NO;
  321 + PRODUCT_NAME = NSDataExtensions;
  322 + ZERO_LINK = NO;
  323 + };
  324 + name = Release;
  325 + };
216 326 C01FCF4B08A954540054247B /* Debug */ = {
217 327 isa = XCBuildConfiguration;
218 328 buildSettings = {
@@ -273,6 +383,15 @@
273 383 /* End XCBuildConfiguration section */
274 384
275 385 /* Begin XCConfigurationList section */
  386 + 557E507C125CD51E0055E512 /* Build configuration list for PBXNativeTarget "NSDataExtensions" */ = {
  387 + isa = XCConfigurationList;
  388 + buildConfigurations = (
  389 + 557E507A125CD51E0055E512 /* Debug */,
  390 + 557E507B125CD51E0055E512 /* Release */,
  391 + );
  392 + defaultConfigurationIsVisible = 0;
  393 + defaultConfigurationName = Release;
  394 + };
276 395 C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "LineReader" */ = {
277 396 isa = XCConfigurationList;
278 397 buildConfigurations = (
8 LineReaderAppDelegate.h
@@ -9,13 +9,15 @@
9 9 #import <Cocoa/Cocoa.h>
10 10
11 11 @interface LineReaderAppDelegate : NSObject <NSApplicationDelegate> {
12   - NSWindow* window;
  12 + NSWindow* m_window;
13 13 IBOutlet NSTextField* m_sourcePath;
14   - IBOutlet NSTableView* m_tableView;
  14 + NSNumber* m_maxNumLines;
15 15 NSArray* m_directoryListing;
16 16 }
17 17
18   -@property (assign) IBOutlet NSWindow *window;
  18 +@property (assign) IBOutlet NSWindow* window;
  19 +@property (readwrite, assign) NSString* sourcePath;
  20 +@property (readwrite, assign) NSNumber* maxNumLines;
19 21
20 22 - (IBAction)sourcePathChanged:(id)sender;
21 23
62 LineReaderAppDelegate.m
@@ -11,16 +11,43 @@
11 11 #import "FileReader.h"
12 12
13 13
14   -
15 14 /**
16 15 Application delegate.
17 16 */
18 17 @implementation LineReaderAppDelegate
19 18
20 19
21   -@synthesize window;
  20 +/**
  21 + Initializes an application delegate object.
  22 + @returns An initialized LineReaderAppDelegate object or nil if the object could not be created.
  23 + */
  24 +- (id)init {
  25 +
  26 + self = [super init];
  27 + if (self != nil) {
  28 + m_maxNumLines = [NSNumber numberWithInt:3];
  29 + [self setSourcePath:[NSString stringWithFormat:@"/tmp/"]];
  30 + }
  31 + return self;
  32 +}
  33 +
  34 +
  35 +@synthesize window = m_window;
  36 +@synthesize maxNumLines = m_maxNumLines;
  37 +@dynamic sourcePath;
22 38
  39 +- (NSString*)sourcePath {
  40 + return [m_sourcePath stringValue];
  41 +}
23 42
  43 +- (void)setSourcePath:(NSString*)sourcePath {
  44 + m_sourcePath = [[NSTextField alloc] init];
  45 + if (!sourcePath || [sourcePath length] <= 0) {
  46 + [m_sourcePath setStringValue:@""];
  47 + return;
  48 + }
  49 + [m_sourcePath setStringValue:sourcePath];
  50 +}
24 51
25 52 /**
26 53 Sent by the default notification center after the application
@@ -38,22 +65,31 @@ - (void)applicationDidFinishLaunching:(NSNotification*)aNotification {
38 65 @param sender The object calling this method.
39 66 */
40 67 - (IBAction)sourcePathChanged:(id)sender {
  68 +
  69 + DirectoryReader* directoryReader = [[DirectoryReader alloc] initWithPath:[m_sourcePath stringValue]];
  70 + if (!directoryReader) {
  71 + return;
  72 + }
  73 +
  74 + if ([directoryReader readDirectory:&m_directoryListing]) {
41 75
42   - DirectoryReader* dr = [[DirectoryReader alloc] initWithPath:[m_sourcePath stringValue]];
43   - if ([dr readDirectory:&m_directoryListing]) {
44   - NSLog(@"%@",m_directoryListing); /* DEBUG LOG */
45   -
46 76 for (NSString* path in m_directoryListing) {
  77 + NSLog(@"File: %@", path); /* DEBUG LOG */
  78 + int numLine = 0;
  79 + FileReader* fileReader = [[FileReader alloc] initWithFilePath:path];
  80 + if (!fileReader) {
  81 + return;
  82 + }
47 83
48   - int numLines = 0;
49   -
50   - FileReader* fr = [[FileReader alloc] initWithFilePath:path];
51 84 NSString* line = nil;
52   - while (numLines <= 5 && (line = [fr readTrimmedLine])) {
53   - NSLog(@"%@",line); /* DEBUG LOG */
54   - numLines++;
  85 + while (line = [fileReader readLine]) {
  86 + numLine++;
  87 + NSLog(@"------------------ %2.d: %@", numLine, line); /* DEBUG LOG */
  88 + if (numLine >= [m_maxNumLines intValue]) {
  89 + break;
  90 + }
55 91 }
56   - }
  92 + }
57 93 }
58 94 }
59 95
28 NSDataExtensions-Info.plist
... ... @@ -0,0 +1,28 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>English</string>
  7 + <key>CFBundleExecutable</key>
  8 + <string>${EXECUTABLE_NAME}</string>
  9 + <key>CFBundleIdentifier</key>
  10 + <string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
  11 + <key>CFBundleInfoDictionaryVersion</key>
  12 + <string>6.0</string>
  13 + <key>CFBundlePackageType</key>
  14 + <string>APPL</string>
  15 + <key>CFBundleShortVersionString</key>
  16 + <string>1.0</string>
  17 + <key>CFBundleSignature</key>
  18 + <string>????</string>
  19 + <key>CFBundleVersion</key>
  20 + <string>1</string>
  21 + <key>LSMinimumSystemVersion</key>
  22 + <string>${MACOSX_DEPLOYMENT_TARGET}</string>
  23 + <key>NSMainNibFile</key>
  24 + <string>MainMenu</string>
  25 + <key>NSPrincipalClass</key>
  26 + <string>NSApplication</string>
  27 +</dict>
  28 +</plist>
41 NSDataExtensionsTest.m
... ... @@ -0,0 +1,41 @@
  1 +//
  2 +// NSDataExtensionsTest.m
  3 +// LineReader
  4 +//
  5 +// Created by Tobias Preuss on 06.10.10.
  6 +// Copyright 2010 Tobias Preuss. All rights reserved.
  7 +//
  8 +
  9 +#import <Cocoa/Cocoa.h>
  10 +#import "FileReader.h"
  11 +
  12 +
  13 +int main()
  14 +
  15 +{
  16 + NSString* contents = @"one\ntwo\nthree\none\ntwo\nthree";
  17 + NSString* delim = @"o\n";
  18 +
  19 + // -----------------------------------------------------------------------------
  20 + // Test using NSString objects.
  21 + // -----------------------------------------------------------------------------
  22 +
  23 + NSRange r1 = [contents rangeOfString:delim];
  24 + NSLog(@"NSString forwards: \t%3.d (%d)", r1.location, r1.length); /* DEBUG LOG */
  25 + NSRange r2 = [contents rangeOfString:delim options:NSBackwardsSearch];
  26 + NSLog(@"NSString backwards: \t%3.d (%d)", r2.location, r2.length); /* DEBUG LOG */
  27 +
  28 +
  29 + // -----------------------------------------------------------------------------
  30 + // Test using NSData objects.
  31 + // -----------------------------------------------------------------------------
  32 +
  33 + NSData* delimData = [delim dataUsingEncoding:NSUTF8StringEncoding];
  34 + NSData* contentsData = [contents dataUsingEncoding:NSUTF8StringEncoding];
  35 +
  36 + NSRange r3 = [contentsData rangeOfData:delimData];
  37 + NSLog(@"NSData forwards: \t%3.d (%d)", r3.location, r3.length); /* DEBUG LOG */
  38 +
  39 + NSRange r4 = [contentsData rangeOfDataBackwardsSearch:delimData];
  40 + NSLog(@"NSData backwards: \t%3.d (%d)", r4.location, r4.length); /* DEBUG LOG */
  41 +}

0 comments on commit 47b6ee2

Please sign in to comment.
Something went wrong with that request. Please try again.