Trevor Berg: The Blog

Avatar

getLine for NSString

UPDATE2: I’ve added a hack to use psuedo instance variables, it works for now but I’ll refactor to a better solution soon.

UPDATE: After some more research and trouble shooting I’ve found that you can’t add instance variables through categories, it looks as though I’d be better off writing a subclass of NSString for this.

I’m currently writing the decoder for yDec and decided I wanted to read files a line at a time.  Unfortunately, I wasn’t able to find a simple way of doing this in objective-c so I wrote a category for the NSString class that allows you to read from a NSString a line at a time.

Header:

//
//  getLine.h
//  swagr
//
//  Created by Trevor Berg on 8/7/08.
//  Copyright 2008 Trevor Berg. All rights reserved.
//

#import <Cocoa/Cocoa.h>

@interface NSString (getLine)
- (void)setFilePointer:(int)index;
- (int)getFilePointer;
- (NSString*) getLine;
- (void)resetLine;
@end

Implementation:

//
//  getLine.m
//  swagr
//
//  Created by Trevor Berg on 8/7/08.
//  Copyright 2008 Trevor Berg. All rights reserved.
//

#import "getLine.h"

@implementation NSString (getLine)

static NSMutableDictionary *ivarHolder = nil;

- (NSString*) getLine{

	// chop off the first part of the string so that
	// you actually get the next line instead of the first line
	NSString* mySelf = [self substringFromIndex:[self getFilePointer]];

	// find the index of the end of the line
	int first = [mySelf rangeOfString:@"\n"].location;

	// make sure it found a line
	if (first != NSNotFound) {
		NSString* line = [mySelf substringToIndex:(first-1)];

		// move the index to the start of the next line
		[self setFilePointer:(first + 1 + [self getFilePointer])];

		// return the line
		return line;
	}
	else {
		// Didn’t find another line so return nil
		return nil;
	}
}

- (void) resetLine {

	// reset the index to the beginning of the file
	[self setFilePointer:0];
}

- (void)setFilePointer:(int)index {
	if ( ivarHolder == nil )
        ivarHolder = [[NSMutableDictionary alloc] init];

	[ivarHolder setObject:[NSNumber numberWithInt:index] forKey:self];
}

- (int)getFilePointer {
	if(ivarHolder == nil) {
		return 0;
	}
	else {
		NSNumber* index = [ivarHolder objectForKey:self];
		return [index intValue];
	}
}
@end

Obviously, this isn’t the most polished solution so feel free to email me any changes to trevorb(at)gmail.com .