From 36e36ef34d1cd796bf94f81cb00d8ed0c1b42b28 Mon Sep 17 00:00:00 2001 From: CaS Date: Tue, 27 Aug 2002 12:26:17 +0000 Subject: [PATCH] Updates for MacOS-X git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@14346 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 3 + Headers/gnustep/base/NSData.h | 16 ++- Source/NSData.m | 180 +++++++++++++++++++++++++++++----- 3 files changed, 176 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index d0193c37e..046581dc6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,9 @@ * Source/NSData.m: ([-writeToFile:atomically:]) Removed bogus line which deleted files when it shouldn't. + Added new MacOS-X methods supporting NSData objects where the bytes + are not owned by the data object. Removed GNUstep extension which + provided this functionality before. * Source/NSUserDefaults.m: Use distributed lock to ensure that there is no possible window when the defaults file is invalid ... not all systems guarantee that the rename() system call is atomic. diff --git a/Headers/gnustep/base/NSData.h b/Headers/gnustep/base/NSData.h index 7bad15816..b0733b811 100644 --- a/Headers/gnustep/base/NSData.h +++ b/Headers/gnustep/base/NSData.h @@ -41,6 +41,11 @@ length: (unsigned int)length; + (id) dataWithBytesNoCopy: (void*)bytes length: (unsigned int)length; +#ifndef STRICT_OPENSTEP ++ (id) dataWithBytesNoCopy: (void*)aBuffer + length: (unsigned int)bufferSize + freeWhenDone: (BOOL)shouldFree; +#endif + (id) dataWithContentsOfFile: (NSString*)path; + (id) dataWithContentsOfMappedFile: (NSString*)path; #ifndef STRICT_OPENSTEP @@ -51,6 +56,11 @@ length: (unsigned int)bufferSize; - (id) initWithBytesNoCopy: (void*)aBuffer length: (unsigned int)bufferSize; +#ifndef STRICT_OPENSTEP +- (id) initWithBytesNoCopy: (void*)aBuffer + length: (unsigned int)bufferSize + freeWhenDone: (BOOL)shouldFree; +#endif - (id) initWithContentsOfFile: (NSString*)path; - (id) initWithContentsOfMappedFile: (NSString*)path; #ifndef STRICT_OPENSTEP @@ -179,7 +189,6 @@ @interface NSData (GNUstepExtensions) + (id) dataWithShmID: (int)anID length: (unsigned int) length; + (id) dataWithSharedBytes: (const void*)bytes length: (unsigned int) length; -+ (id) dataWithStaticBytes: (const void*)bytes length: (unsigned int) length; /* * -deserializeTypeTag:andCrossRef:atCursor: @@ -215,6 +224,11 @@ - (void) replaceBytesInRange: (NSRange)aRange withBytes: (const void*)bytes; +#ifndef STRICT_OPENSTEP +- (void) replaceBytesInRange: (NSRange)aRange + withBytes: (const void*)bytes + length: (unsigned int)length; +#endif - (void) resetBytesInRange: (NSRange)aRange; - (void) setData: (NSData*)data; diff --git a/Source/NSData.m b/Source/NSData.m index 3e6ccec07..6230da089 100644 --- a/Source/NSData.m +++ b/Source/NSData.m @@ -46,6 +46,7 @@ * * NSData Abstract base class. * NSDataStatic Concrete class static buffers. + * NSDataEmpty Concrete class static buffers. * NSDataMalloc Concrete class. * NSDataMappedFile Memory mapped files. * NSDataShared Extension for shared memory. @@ -333,6 +334,8 @@ failure: void *bytes; } @end +@interface NSDataEmpty: NSDataStatic +@end @interface NSDataMalloc : NSDataStatic { @@ -401,13 +404,19 @@ failure: } } +/** + * Returns an empty data object. + */ + (id) data { - NSData *d; + static NSData *empty = nil; - d = [NSDataStatic allocWithZone: NSDefaultMallocZone()]; - d = [d initWithBytesNoCopy: 0 length: 0]; - return AUTORELEASE(d); + if (empty == nil) + { + empty = [NSDataEmpty allocWithZone: NSDefaultMallocZone()]; + empty = [empty initWithBytesNoCopy: 0 length: 0 freeWhenDone: NO]; + } + return empty; } + (id) dataWithBytes: (const void*)bytes @@ -426,7 +435,25 @@ failure: NSData *d; d = [dataMalloc allocWithZone: NSDefaultMallocZone()]; - d = [d initWithBytesNoCopy: bytes length: length]; + d = [d initWithBytesNoCopy: bytes length: length freeWhenDone: YES]; + return AUTORELEASE(d); +} + ++ (id) dataWithBytesNoCopy: (void*)bytes + length: (unsigned int)length + freeWhenDone: (BOOL)shouldFree +{ + NSData *d; + + if (shouldFree == YES) + { + d = [dataMalloc allocWithZone: NSDefaultMallocZone()]; + } + else + { + d = [dataStatic allocWithZone: NSDefaultMallocZone()]; + } + d = [d initWithBytesNoCopy: bytes length: length freeWhenDone: shouldFree]; return AUTORELEASE(d); } @@ -475,13 +502,13 @@ failure: NSData *d; d = [dataMalloc allocWithZone: NSDefaultMallocZone()]; - d = [d initWithBytesNoCopy: 0 length: 0]; + d = [d initWithBytesNoCopy: 0 length: 0 freeWhenDone: YES]; return d; } - (id) init { - return [self initWithBytesNoCopy: 0 length: 0]; + return [self initWithBytesNoCopy: 0 length: 0 freeWhenDone: YES]; } - (id) initWithBytes: (const void*)aBuffer @@ -494,17 +521,40 @@ failure: ptr = NSZoneMalloc(NSDefaultMallocZone(), bufferSize); memcpy(ptr, aBuffer, bufferSize); } - return [self initWithBytesNoCopy: ptr length: bufferSize]; + return [self initWithBytesNoCopy: ptr + length: bufferSize + freeWhenDone: YES]; } +/** + * Invokes -initWithBytesNoCopy:length:freeWhenDone: with the last argument + * set to YES. Returns the resulting initialised data object (which may not + * be the receiver). + */ - (id) initWithBytesNoCopy: (void*)aBuffer length: (unsigned int)bufferSize +{ + return [self initWithBytesNoCopy: aBuffer + length: bufferSize + freeWhenDone: YES]; +} + +/** + */ +- (id) initWithBytesNoCopy: (void*)aBuffer + length: (unsigned int)bufferSize + freeWhenDone: (BOOL)shouldFree { [self subclassResponsibility: _cmd]; return nil; } -- (id) initWithContentsOfFile: (NSString *)path +/** + * Initialises the receiver with the contents of the specified file.
+ * Returns the resulting object. + * Returns nil if the file does not exist. + */ +- (id) initWithContentsOfFile: (NSString*)path { void *fileBytes; unsigned fileLength; @@ -522,7 +572,9 @@ failure: } else { - self = [self initWithBytesNoCopy: fileBytes length: fileLength]; + self = [self initWithBytesNoCopy: fileBytes + length: fileLength + freeWhenDone: YES]; } return self; } @@ -549,7 +601,7 @@ failure: { if (data == nil) { - return [self initWithBytesNoCopy: 0 length: 0]; + return [self initWithBytesNoCopy: 0 length: 0 freeWhenDone: YES]; } if ([data isKindOfClass: [NSData class]] == NO) { @@ -1336,8 +1388,8 @@ failure: { NSDataStatic *d; - d = [NSDataStatic allocWithZone: NSDefaultMallocZone()]; - d = [d initWithBytesNoCopy: (void*)bytes length: length]; + d = [dataStatic allocWithZone: NSDefaultMallocZone()]; + d = [d initWithBytesNoCopy: (void*)bytes length: length freeWhenDone: NO]; return AUTORELEASE(d); } @@ -1664,6 +1716,52 @@ failure: } } +/** + * Replace the content of the receiver which lies in aRange with + * the specified length of data from the buffer pointed to by bytes.
+ * The size of the receiver is adjusted to allow for the change. + */ +- (void) replaceBytesInRange: (NSRange)aRange + withBytes: (const void*)bytes + length: (unsigned int)length +{ + unsigned size = [self length]; + unsigned end = NSMaxRange(aRange); + int shift = length - aRange.length; + unsigned need = end + shift; + + if (aRange.location > size) + { + [NSException raise: NSRangeException + format: @"location bad in replaceByteInRange:withBytes:"]; + } + if (length > aRange.length) + { + need += (length - aRange.length); + } + if (need > size) + { + [self setLength: need]; + } + if (aRange.length > 0 || aRange.length != length) + { + void *buf = [self mutableBytes]; + + if (end < size && shift != 0) + { + memmove(buf + end + shift, buf + end, size - end); + } + if (length > 0) + { + memmove(buf + aRange.location, bytes, length); + } + } + if (shift < 0) + { + [self setLength: need + shift]; + } +} + - (void) resetBytesInRange: (NSRange)aRange { unsigned size = [self length]; @@ -2043,6 +2141,7 @@ failure: - (id) initWithBytesNoCopy: (void*)aBuffer length: (unsigned int)bufferSize + freeWhenDone: (BOOL)shouldFree { bytes = aBuffer; length = bufferSize; @@ -2422,8 +2521,15 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) } } - @end + + +@implementation NSDataEmpty +- (void) dealloc +{ +} +@end + @implementation NSDataMalloc @@ -2457,7 +2563,12 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) - (id) initWithBytesNoCopy: (void*)aBuffer length: (unsigned int)bufferSize + freeWhenDone: (BOOL)shouldFree { + if (shouldFree == NO) + { + self->isa = dataStatic; + } bytes = aBuffer; length = bufferSize; return self; @@ -2667,7 +2778,10 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) { if (bytes != 0) { - NSZoneFree(zone, bytes); + if (zone != 0) + { + NSZoneFree(zone, bytes); + } bytes = 0; } [super dealloc]; @@ -2689,6 +2803,7 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) - (id) initWithBytesNoCopy: (void*)aBuffer length: (unsigned int)bufferSize + freeWhenDone: (BOOL)shouldFree { if (aBuffer == 0) { @@ -2702,11 +2817,10 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) self = [self initWithCapacity: 0]; if (self) { -#if GS_WITH_GC - zone = GSAtomicMallocZone(); -#else - zone = NSZoneFromPointer(aBuffer); -#endif + if (shouldFree == NO) + { + zone = 0; // Don't free this memory. + } bytes = aBuffer; length = bufferSize; capacity = bufferSize; @@ -2734,7 +2848,8 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) bytes = NSZoneMalloc(zone, size); if (bytes == 0) { - NSLog(@"[NSMutableDataMalloc -initWithCapacity:] out of memory for %u bytes - %s", size, GSLastErrorStr(errno)); + NSLog(@"[NSMutableDataMalloc -initWithCapacity:] out of memory " + @"for %u bytes - %s", size, GSLastErrorStr(errno)); RELEASE(self); return nil; } @@ -3141,10 +3256,31 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) if (bytes) { - tmp = NSZoneRealloc(zone, bytes, size); + if (zone == 0) + { +#if GS_WITH_GC + zone = GSAtomicMallocZone(); +#else + zone = GSObjCZone(self); +#endif + tmp = NSZoneMalloc(zone, size); + memcpy(tmp, bytes, capacity < size ? capacity : size); + } + else + { + tmp = NSZoneRealloc(zone, bytes, size); + } } else { + if (zone == 0) + { +#if GS_WITH_GC + zone = GSAtomicMallocZone(); +#else + zone = GSObjCZone(self); +#endif + } tmp = NSZoneMalloc(zone, size); } if (tmp == 0)