diff --git a/ChangeLog b/ChangeLog index c45f4450b..f318d03fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-03-18 Richard Frith-Macdonald + + * Source/NSString.m: Add a couple of new MacOS-X methods. + * Headers/Foundation/NSString.h: ditto + * Headers/Foundation/FoundationErrors.h: New list of error codes + * Headers/Foundation/Foundation.h: include error codes + More MacOS-X compatibility tweaks + 2008-03-17 Richard Frith-Macdonald * Headers/Foundation/NSThread.h: diff --git a/Headers/Foundation/Foundation.h b/Headers/Foundation/Foundation.h index 9dc5db820..71b763dd9 100644 --- a/Headers/Foundation/Foundation.h +++ b/Headers/Foundation/Foundation.h @@ -30,6 +30,7 @@ #import #import +#import #import #import #import diff --git a/Headers/Foundation/FoundationErrors.h b/Headers/Foundation/FoundationErrors.h new file mode 100644 index 000000000..bce8ae2af --- /dev/null +++ b/Headers/Foundation/FoundationErrors.h @@ -0,0 +1,81 @@ +/* Interface for FoundationErrors for GNUstep + Copyright (C) 2008 Free Software Foundation, Inc. + + Written by: Richard Frith-Macdonald + Date: 2008 + + This file is part of the GNUstep Base Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. + */ + +#ifndef __FoundationErrors_h_GNUSTEP_BASE_INCLUDE +#define __FoundationErrors_h_GNUSTEP_BASE_INCLUDE + +#import +#import + +#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST) + +/* These are those of the NSError code values for the NSCocoaErrorDomain + * which are defined in the foundation/base library. + */ + +enum { + + NSFileErrorMaximum = 1023, + NSFileErrorMinimum = 0, + NSFileLockingError = 255, + NSFileNoSuchFileError = 4, + NSFileReadCorruptFileError = 259, + NSFileReadInapplicableStringEncodingError = 261, + NSFileReadInvalidFileNameError = 258, + NSFileReadNoPermissionError = 257, + NSFileReadNoSuchFileError = 260, + NSFileReadUnknownError = 256, + NSFileReadUnsupportedSchemeError = 262, + NSFileWriteInapplicableStringEncodingError = 517, + NSFileWriteInvalidFileNameError = 514, + NSFileWriteNoPermissionError = 513, + NSFileWriteOutOfSpaceError = 640, + NSFileWriteUnknownError = 512, + NSFileWriteUnsupportedSchemeError = 518, + NSFormattingError = 2048, + NSFormattingErrorMaximum = 2559, + NSFormattingErrorMinimum = 2048, + NSKeyValueValidationError = 1024, + NSUserCancelledError = 3072, + NSValidationErrorMaximum = 2047, + NSValidationErrorMinimum = 1024, + +#if OS_API_VERSION(MAC_OS_X_VERSION_10_5, GS_API_LATEST) + NSExecutableArchitectureMismatchError = 3585, + NSExecutableErrorMaximum = 3839, + NSExecutableErrorMinimum = 3584, + NSExecutableLinkError = 3588, + NSExecutableLoadError = 3587, + NSExecutableNotLoadableError = 3584, + NSExecutableRuntimeMismatchError = 3586, + NSFileReadTooLargeError = 263, + NSFileReadUnknownStringEncodingError = 264, +#endif + + GSFoundationPlaceHolderError = 9999 +}; + +#endif +#endif + diff --git a/Headers/Foundation/NSString.h b/Headers/Foundation/NSString.h index a893f097a..d3c85e573 100644 --- a/Headers/Foundation/NSString.h +++ b/Headers/Foundation/NSString.h @@ -43,6 +43,7 @@ typedef uint16_t unichar; @class NSData; @class NSDictionary; #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) +@class NSError; @class NSURL; #endif @@ -203,6 +204,14 @@ enum { encoding: (NSStringEncoding)encoding freeWhenDone: (BOOL)flag; #endif +#if OS_API_VERSION(100500,GS_API_LATEST) ++ (id) stringWithContentsOfFile: (NSString*)path + usedEncoding: (NSStringEncoding*)enc + error: (NSError**)error; +- (id) initWithContentsOfFile: (NSString*)path + usedEncoding: (NSStringEncoding*)enc + error: (NSError**)error; +#endif - (id) initWithCharactersNoCopy: (unichar*)chars length: (unsigned int)length freeWhenDone: (BOOL)flag; diff --git a/Source/NSAutoreleasePool.m b/Source/NSAutoreleasePool.m index fc16e466d..b5bbc9f67 100644 --- a/Source/NSAutoreleasePool.m +++ b/Source/NSAutoreleasePool.m @@ -408,8 +408,13 @@ static IMP initImp; { IMP imp; +#if 1 if (GSObjCIsInstance(anObject)) { + /* We call instanceMethodForSelector: on the class + * rather than methodForSelector: because EOFault + * implements the former but not the latter. + */ imp = [c instanceMethodForSelector: releaseSel]; } else @@ -421,6 +426,9 @@ static IMP initImp; [NSException raise: NSInternalInconsistencyException format: @"nul release for object in autorelease pool"]; } +#else + imp = get_imp(anObject, @selector(release)); +#endif classes[hash] = c; imps[hash] = imp; } diff --git a/Source/NSString.m b/Source/NSString.m index 395e71c8d..2a42107c6 100644 --- a/Source/NSString.m +++ b/Source/NSString.m @@ -73,6 +73,7 @@ #include "Foundation/NSLock.h" #include "Foundation/NSNotification.h" #include "Foundation/NSUserDefaults.h" +#include "Foundation/FoundationErrors.h" #include "Foundation/NSDebug.h" // For private method _decodePropertyListForKey: #include "Foundation/NSKeyedArchiver.h" @@ -777,6 +778,21 @@ handle_printf_atsign (FILE *stream, return AUTORELEASE(obj); } +/** + * Load contents of file at path into a new string using the + * -initWithContentsOfFile:usedEncoding:error: method. + */ ++ (id) stringWithContentsOfFile: (NSString *)path + usedEncoding: (NSStringEncoding*)enc + error: (NSError**)error +{ + NSString *obj; + + obj = [self allocWithZone: NSDefaultMallocZone()]; + obj = [obj initWithContentsOfFile: path usedEncoding: enc error: error]; + return AUTORELEASE(obj); +} + /** * Load contents of given URL into a new string. Will interpret contents as * containing direct unicode if it begins with the unicode byte order mark, @@ -1210,6 +1226,78 @@ handle_printf_atsign (FILE *stream, return self; } +/** + *

Initialises the receiver with the contents of the file at path. + *

+ *

Invokes [NSData-initWithContentsOfFile:] to read the file, then + * examines the data to infer its encoding type, and converts the + * data to a string using -initWithData:encoding: + *

+ *

The encoding to use is determined as follows ... if the data begins + * with the 16-bit unicode Byte Order Marker, then it is assumed to be + * unicode data in the appropriate ordering and converted as such.
+ * If it begins with a UTF8 representation of the BOM, the UTF8 encoding + * is used.
+ * Otherwise, the default C String encoding is used. + *

+ *

Releases the receiver and returns nil if the file could not be read + * and converted to a string. + *

+ */ +- (id) initWithContentsOfFile: (NSString*)path + usedEncoding: (NSStringEncoding*)enc + error: (NSError**)error +{ + NSData *d; + unsigned int len; + const unsigned char *data_bytes; + + d = [[NSDataClass alloc] initWithContentsOfFile: path]; + if (d == nil) + { + RELEASE(self); + return nil; + } + *enc = _DefaultStringEncoding; + len = [d length]; + if (len == 0) + { + RELEASE(d); + RELEASE(self); + return @""; + } + data_bytes = [d bytes]; + if ((data_bytes != NULL) && (len >= 2)) + { + const unichar *data_ucs2chars = (const unichar *) data_bytes; + if ((data_ucs2chars[0] == byteOrderMark) + || (data_ucs2chars[0] == byteOrderMarkSwapped)) + { + /* somebody set up us the BOM! */ + *enc = NSUnicodeStringEncoding; + } + else if (len >= 3 + && data_bytes[0] == 0xEF + && data_bytes[1] == 0xBB + && data_bytes[2] == 0xBF) + { + *enc = NSUTF8StringEncoding; + } + } + self = [self initWithData: d encoding: *enc]; + RELEASE(d); + if (self == nil) + { + if (error != 0) + { + *error = [NSError errorWithDomain: NSCocoaErrorDomain + code: NSFileReadCorruptFileError + userInfo: nil]; + } + } + return self; +} + /** *

Initialises the receiver with the contents of the given URL. *