From 5a94458d9ee3ee8afd978477c755200df432a9b0 Mon Sep 17 00:00:00 2001 From: Alex Merry Date: Wed, 7 Aug 2013 00:43:49 +0100 Subject: Add variant of stringWithContentsOfFile that produces an error It turns out that the [NSString stringWithContentsOfFile:] family of methods do not have a way of reporting why a file could not be read; [NSString stringWithContentsOfFile:usedEncoding:error:] will only set the error object if there was a problem with decoding. So, we cook our own variant that tries to figure out why opening the file failed. User-visible effect: in the GTK+ port, if you try to open a file from the "open recent" menu that no longer exists, you will get a more helpful error message. --- tikzit/src/common/NSString+Util.h | 27 ++++++++++++++++ tikzit/src/common/NSString+Util.m | 66 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 tikzit/src/common/NSString+Util.h create mode 100644 tikzit/src/common/NSString+Util.m (limited to 'tikzit/src/common') diff --git a/tikzit/src/common/NSString+Util.h b/tikzit/src/common/NSString+Util.h new file mode 100644 index 0000000..548edb3 --- /dev/null +++ b/tikzit/src/common/NSString+Util.h @@ -0,0 +1,27 @@ +/* + * Copyright 2013 Alex Merry + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import + +@interface NSString (Util) + + (NSString*) stringWithContentsOfFile:(NSString*)path + error:(NSError**)error; + - (id) initWithContentsOfFile:(NSString*)path + error:(NSError**)error; +@end + +// vi:ft=objc:noet:ts=4:sts=4:sw=4 diff --git a/tikzit/src/common/NSString+Util.m b/tikzit/src/common/NSString+Util.m new file mode 100644 index 0000000..b18f397 --- /dev/null +++ b/tikzit/src/common/NSString+Util.m @@ -0,0 +1,66 @@ +/* + * Copyright 2013 Alex Merry + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import +#import "NSString+Util.h" +#import "NSError+Tikzit.h" + +@implementation NSString (Util) ++ (NSString*) stringWithContentsOfFile:(NSString*)path + error:(NSError**)error +{ + return [[[self alloc] initWithContentsOfFile:path error:error] autorelease]; +} +- (id) initWithContentsOfFile:(NSString*)path + error:(NSError**)error +{ + // Fun fact: on GNUstep, at least, + // [stringWithContentsOfFile:usedEncoding:error:] only + // sets error objects if the decoding fails, not if file + // access fails. + // Fun fact 2: on GNUstep, trying to read a directory using + // [stringWithContentsOfFile:] causes an out-of-memory error; + // hence we do these checks *before* trying to read the file. + NSFileManager *fm = [NSFileManager defaultManager]; + BOOL isDir = NO; + NSString *msg = nil; + if (![fm fileExistsAtPath:path isDirectory:&isDir]) { + msg = [NSString stringWithFormat:@"\"%@\" does not exist", path]; + } else if (isDir) { + msg = [NSString stringWithFormat:@"\"%@\" is a directory", path]; + } else if (![fm isReadableFileAtPath:path]) { + msg = [NSString stringWithFormat:@"\"%@\" is not readable", path]; + } + if (msg != nil) { + if (error) { + *error = [NSError errorWithMessage:msg + code:TZ_ERR_IO]; + } + return nil; + } + self = [self initWithContentsOfFile:path]; + if (self == nil) { + if (error) { + *error = [NSError errorWithMessage:@"unknown error" + code:TZ_ERR_IO]; + } + } + return self; +} +@end + +// vi:ft=objc:noet:ts=4:sts=4:sw=4 -- cgit v1.2.3