Patches from Frith-MacDonald.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2734 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Adam Fedor 1998-02-05 22:06:20 +00:00
parent 4471b1d57b
commit f5c81dc93c
11 changed files with 749 additions and 109 deletions

View file

@ -1,3 +1,40 @@
Thu Feb 5 10:12:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* src/NSConcreteNumber.m: Defined preprocessor values to handle
'promotion' of numeric types and added private methods to support
this. Modified ([-compare:]) to promote numeric values so that
comparisons work as expected. Implemented ([-isEqualToNumber:]),
Implemented ([-description]) and partially ([-descriptionWithLocale:])
Implemented ([-hash]) so that numbers which compare the same also
has the same (so we can use NSNumbers as dictionary keys).
* src/NSData.m: Added non-openstep method ([-relinquishAllocatedBytes])
to ask a data object to hand over it's malloced buffer.
* src/NSNumber.m: Added initialisation methods specified in Rhapsody
documentation.
* src/NSString.m: ([-dataUsingEncoding:allowLossyConversion:]) made
tiny change for efficiency - moving test outside loop - perhaps the
compiler would have optimised it anyway.
* src/Port.m: Modified initialisaers to test for failure to create
NSData objects and return nil as appropriate.
* src/TcpPort.m: ([+newForReceivingFromPortNumber:]) release newly
created port before raising exceptions.
In both ([-invalidate]) methods we remove the port from the various
maps before doing anything else so that invalid ports can't be found
by accident during the invalidation process.
* src/UnixFileHandle.m: ([-readDataOfLength:]) fixed problem with
data object causing read value to be overwritten with nuls.
* src/include/NSData.h: Added ([-relinquishAllocatedBytes])
* src/NSValue.h: Added initialisation methods for NSNumber and
([-isEqualToNumber:]) method.
Thu Feb 5 10:48:35 1998 Adam Fedor <fedor@ultra.doc.com>
* GNUmakefile (GNUSTEP_MAKEFILE_DIR): New variable. Use it to

View file

@ -94,6 +94,16 @@
+ (id) dataWithShmID: (int)anID length: (unsigned) length;
+ (id) dataWithSharedBytes: (const void*)bytes length: (unsigned) length;
+ (id) dataWithStaticBytes: (const void*)bytes length: (unsigned) length;
/*
* -relinquishAllocatedBytes
* For an NSData object with a malloced buffer, returns that buffer and
* removes it from the NSData object, otherwise returns a nul pointer.
* Use with care, preferably when no-one else has retained the NSData
* object - or they will find it's buffer disappearing unexpectedly.
* Once you have used this method, you own the malloced data and are
* responsible for freeing it.
*/
- (void*) relinquishAllocatedBytes;
@end

View file

@ -1,4 +1,4 @@
/* Interface for NSArray for GNUStep
/* Interface for NSValue for GNUStep
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by: Adam Fedor <fedor@boulder.colorado.edu>
@ -74,6 +74,20 @@
+ (NSNumber*) numberWithUnsignedLongLong: (unsigned long long)value;
+ (NSNumber*) numberWithUnsignedShort: (unsigned short)value;
- (id)initWithBool:(BOOL)value;
- (id)initWithChar:(char)value;
- (id)initWithDouble:(double)value;
- (id)initWithFloat:(float)value;
- (id)initWithInt:(int)value;
- (id)initWithLong:(long)value;
- (id)initWithLongLong:(long long)value;
- (id)initWithShort:(short)value;
- (id)initWithUnsignedChar:(unsigned char)value;
- (id)initWithUnsignedInt:(unsigned int)value;
- (id)initWithUnsignedLong:(unsigned long)value;
- (id)initWithUnsignedLongLong:(unsigned long long)value;
- (id)initWithUnsignedShort:(unsigned short)value;
// Accessing Data
- (BOOL) boolValue;
@ -91,7 +105,11 @@
- (unsigned long) unsignedLongValue;
- (unsigned short) unsignedShortValue;
- (NSString*) description;
- (NSString*) descriptionWithLocale: (NSDictionary*)locale;
- (NSComparisonResult) compare: (NSNumber*)otherNumber;
- (BOOL) isEqualToNumber: (NSNumber*)otherNumber;
@end

View file

@ -36,56 +36,124 @@
# define NumberTemplate NSBoolNumber
# define TYPE_METHOD boolValue
# define TYPE_FORMAT @"%uc"
# define NEXT_ORDER 4
# define NEXT_METHOD shortValue
# define NEXT_CTYPE short
#elif TYPE_ORDER == 1
# define NumberTemplate NSUCharNumber
# define TYPE_METHOD unsignedCharValue
# define TYPE_FORMAT @"%uc"
# define NEXT_ORDER 4
# define NEXT_METHOD shortValue
# define NEXT_CTYPE short
#elif TYPE_ORDER == 2
# define NumberTemplate NSCharNumber
# define TYPE_METHOD charValue
# define TYPE_FORMAT @"%c"
# define NEXT_ORDER 4
# define NEXT_METHOD shortValue
# define NEXT_CTYPE short
#elif TYPE_ORDER == 3
# define NumberTemplate NSUShortNumber
# define TYPE_METHOD unsignedShortValue
# define TYPE_FORMAT @"%hu"
# define NEXT_ORDER 6
# define NEXT_METHOD intValue
# define NEXT_CTYPE int
#elif TYPE_ORDER == 4
# define NumberTemplate NSShortNumber
# define TYPE_METHOD shortValue
# define TYPE_FORMAT @"%hd"
# define NEXT_ORDER 6
# define NEXT_METHOD intValue
# define NEXT_CTYPE int
#elif TYPE_ORDER == 5
# define NumberTemplate NSUIntNumber
# define TYPE_METHOD unsignedIntValue
# define TYPE_FORMAT @"%u"
# define NEXT_ORDER 8
# define NEXT_METHOD longValue
# define NEXT_CTYPE long
#elif TYPE_ORDER == 6
# define NumberTemplate NSIntNumber
# define TYPE_METHOD intValue
# define TYPE_FORMAT @"%d"
# define NEXT_ORDER 8
# define NEXT_METHOD longValue
# define NEXT_CTYPE long
#elif TYPE_ORDER == 7
# define NumberTemplate NSULongNumber
# define TYPE_METHOD unsignedLongValue
# define TYPE_FORMAT @"%lu"
# define NEXT_ORDER 10
# define NEXT_METHOD longLongValue
# define NEXT_CTYPE long long
#elif TYPE_ORDER == 8
# define NumberTemplate NSLongNumber
# define TYPE_METHOD longValue
# define TYPE_FORMAT @"%ld"
# define NEXT_ORDER 10
# define NEXT_METHOD longLongValue
# define NEXT_CTYPE long long
#elif TYPE_ORDER == 9
# define NumberTemplate NSULongLongNumber
# define TYPE_METHOD unsignedLongLongValue
# define TYPE_FORMAT @"%llu"
# define NEXT_ORDER 12
# define NEXT_METHOD doubleValue
# define NEXT_CTYPE double
#elif TYPE_ORDER == 10
# define NumberTemplate NSLongLongNumber
# define TYPE_METHOD longLongValue
# define TYPE_FORMAT @"%lld"
# define NEXT_ORDER 12
# define NEXT_METHOD doubleValue
# define NEXT_CTYPE double
#elif TYPE_ORDER == 11
# define NumberTemplate NSFloatNumber
# define TYPE_METHOD floatValue
# define TYPE_FORMAT @"%f"
# define NEXT_ORDER 12
# define NEXT_METHOD doubleValue
# define NEXT_CTYPE double
#elif TYPE_ORDER == 12
# define NumberTemplate NSDoubleNumber
# define TYPE_METHOD doubleValue
# define TYPE_FORMAT @"%g"
# define NEXT_ORDER 12
# define NEXT_METHOD doubleValue
# define NEXT_CTYPE double
#endif
@interface NSNumber (Private)
- (int)_nextOrder;
- (NSComparisonResult) _promotedCompare: (NSNumber*)other;
- (int)_typeOrder;
@end
@implementation NumberTemplate (Private)
- (int)_nextOrder
{
return NEXT_ORDER;
}
- (NSComparisonResult) _promotedCompare: (NSNumber*)other
{
NEXT_CTYPE v0, v1;
v0 = [self NEXT_METHOD];
v1 = [other NEXT_METHOD];
if (v0 == v1)
return NSOrderedSame;
else
return (v0 < v1) ? NSOrderedAscending : NSOrderedDescending;
}
- (int)_typeOrder
{
return TYPE_ORDER;
}
@end
@implementation NumberTemplate
- initValue:(const void *)value withObjCType:(const char *)type;
@ -136,11 +204,6 @@
return data;
}
- (NSString *)stringValue
{
return [NSString stringWithFormat:TYPE_FORMAT, data];
}
- (unsigned char)unsignedCharValue
{
return data;
@ -166,15 +229,84 @@
return data;
}
- (NSComparisonResult)compare:(NSNumber *)otherNumber
- (NSComparisonResult)compare:(NSNumber *)other
{
typedef _dt = data;
_dt other_data = [otherNumber TYPE_METHOD];
int o = [self _typeOrder];
if (o == [other _typeOrder] || o >= [other _nextOrder]) {
typedef _dt = data;
_dt other_data = [other TYPE_METHOD];
if (data == other_data)
return NSOrderedSame;
else
return (data < other_data) ? NSOrderedAscending : NSOrderedDescending;
if (data == other_data)
return NSOrderedSame;
else
return (data < other_data) ?
NSOrderedAscending : NSOrderedDescending;
}
o = [self _nextOrder];
if (o <= [other _typeOrder]) {
NSComparisonResult r = [other compare: self];
if (r == NSOrderedAscending) {
return NSOrderedDescending;
}
if (r == NSOrderedDescending) {
return NSOrderedAscending;
}
return r;
}
if (o >= [other _nextOrder]) {
return [self _promotedCompare: other];
}
else {
NSComparisonResult r = [other _promotedCompare: self];
if (r == NSOrderedAscending) {
return NSOrderedDescending;
}
if (r == NSOrderedDescending) {
return NSOrderedAscending;
}
return r;
}
}
/* Because of the rule that two numbers which are the same according to
* [-isEqual:] must generate the same hash, we must generate the hash
* from the most general representation of the number.
*/
- (unsigned) hash
{
union {
double d;
unsigned char c[sizeof(double)];
} val;
unsigned hash = 0;
int i;
val.d = [self doubleValue];
for (i = 0; i < sizeof(double); i++) {
hash += val.c[i];
}
return hash;
}
- (BOOL) isEqualToNumber: (NSNumber*)o
{
if ([self compare: o] == NSOrderedSame)
return YES;
return NO;
}
- (BOOL) isEqual: o
{
if ([o isKindOf: [NSNumber class]])
return [self isEqualToNumber: (NSNumber*)o];
else
return [super isEqual: o];
}
- (NSString *)descriptionWithLocale: (NSDictionary*)locale
{
return [NSString stringWithFormat:TYPE_FORMAT, data];
}
// Override these from NSValue
@ -194,18 +326,6 @@
return @encode(_dt);
}
- (unsigned) hash
{
return (unsigned)data;
}
- (BOOL) isEqual: o
{
if ([o isKindOf: [NSValue class]])
return ((unsigned)data == [o unsignedIntValue]) ? YES : NO;
return NO;
}
// NSCoding
- classForCoder
{

View file

@ -800,6 +800,11 @@ readContentsOfFile(NSString* path, void** buf, unsigned* len)
return [[[NSDataStatic alloc] initWithBytesNoCopy:(void*)bytes length:length]
autorelease];
}
- (void*) relinquishAllocatedBytes
{
return 0; /* No data from malloc - return nul pointer */
}
@end
@ -1312,6 +1317,15 @@ readContentsOfFile(NSString* path, void** buf, unsigned* len)
length: length];
}
- (void*) relinquishAllocatedBytes
{
void *buf = bytes;
bytes = 0;
length = 0;
return buf;
}
@end
#if HAVE_MMAP
@ -1732,6 +1746,12 @@ readContentsOfFile(NSString* path, void** buf, unsigned* len)
length = size;
}
- (void*) relinquishAllocatedBytes
{
capacity = 0;
return [super relinquishAllocatedBytes];
}
@end

View file

@ -31,6 +31,8 @@
#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSLock.h>
#include <stdio.h>
/* determine directory reading files */
#if defined(HAVE_DIRENT_H)
@ -91,12 +93,22 @@
# include <sys/statfs.h>
#endif
#if HAVE_SYS_FILE_H
#include <sys/file.h>
#endif
#include <errno.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include <fcntl.h>
#if HAVE_UTIME_H
# include <utime.h>
#endif
/* include usual headers */
#include <Foundation/NSArray.h>
@ -108,6 +120,19 @@
#include <Foundation/NSPathUtilities.h>
#include <Foundation/NSFileManager.h>
@interface NSFileManager (PrivateMethods)
/* Copies the contents of source file to destination file. Assumes source
and destination are regular files or symbolic links. */
- (BOOL)_copyFile:(NSString*)source toFile:(NSString*)destination
handler:handler;
/* Recursively copies the contents of source directory to destination. */
- (BOOL)_copyPath:(NSString*)source toPath:(NSString*)destination
handler:handler;
@end /* NSFileManager (PrivateMethods) */
/*
* NSFileManager implementation
*/
@ -237,44 +262,139 @@ static NSFileManager* defaultManager = nil;
- (BOOL)copyPath:(NSString*)source toPath:(NSString*)destination
handler:handler
{
// TODO
BOOL sourceIsDir, fileExists;
NSDictionary* attributes;
fileExists = [self fileExistsAtPath:source isDirectory:&sourceIsDir];
if (!fileExists)
return NO;
fileExists = [self fileExistsAtPath:destination];
if (fileExists)
return NO;
attributes = [self fileAttributesAtPath:source traverseLink:NO];
if (sourceIsDir) {
/* If destination directory is a descendant of source directory copying
isn't possible. */
if ([[destination stringByAppendingString:@"/"]
hasPrefix:[source stringByAppendingString:@"/"]])
return NO;
[handler fileManager:self willProcessPath:destination];
if (![self createDirectoryAtPath:destination attributes:attributes]) {
if (handler) {
NSDictionary* errorInfo
= [NSDictionary dictionaryWithObjectsAndKeys:
destination, @"Path",
@"cannot create directory", @"Error",
nil];
return [handler fileManager:self
shouldProceedAfterError:errorInfo];
}
else
return NO;
}
}
if (sourceIsDir) {
if (![self _copyPath:source toPath:destination handler:handler])
return NO;
else {
[self changeFileAttributes:attributes atPath:destination];
return YES;
}
}
else {
[handler fileManager:self willProcessPath:source];
if (![self _copyFile:source toFile:destination handler:handler])
return NO;
else {
[self changeFileAttributes:attributes atPath:destination];
return YES;
}
}
return NO;
}
- (BOOL)movePath:(NSString*)source toPath:(NSString*)destination
handler:handler
{
BOOL sourceIsDir;
BOOL sourceIsDir, fileExists;
const char* sourcePath = [self fileSystemRepresentationWithPath:source];
const char* destPath = [self fileSystemRepresentationWithPath:destination];
NSString* destinationParent;
unsigned int sourceDevice, destinationDevice;
if ([self fileExistsAtPath:source isDirectory:&sourceIsDir]
&& !sourceIsDir) {
/* `source' is file so simply move it to destination. */
fileExists = [self fileExistsAtPath:source isDirectory:&sourceIsDir];
if (!fileExists)
return NO;
fileExists = [self fileExistsAtPath:destination];
if (fileExists)
return NO;
/* Check to see if the source and destination's parent are on the same
physical device so we can perform a rename syscall directly. */
sourceDevice = [[[self fileSystemAttributesAtPath:source]
objectForKey:NSFileSystemNumber]
unsignedIntValue];
destinationParent = [destination stringByDeletingLastPathComponent];
if ([destinationParent isEqual:@""])
destinationParent = @".";
destinationDevice
= [[[self fileSystemAttributesAtPath:destinationParent]
objectForKey:NSFileSystemNumber]
unsignedIntValue];
if (sourceDevice != destinationDevice) {
/* If destination directory is a descendant of source directory moving
isn't possible. */
if (sourceIsDir && [[destination stringByAppendingString:@"/"]
hasPrefix:[source stringByAppendingString:@"/"]])
return NO;
if ([self copyPath:source toPath:destination handler:handler]) {
NSDictionary* attributes;
attributes = [self fileAttributesAtPath:source traverseLink:NO];
[self changeFileAttributes:attributes atPath:destination];
return [self removeFileAtPath:source handler:handler];
}
else
return NO;
}
else {
/* source and destination are on the same device so we can simply
invoke rename on source. */
[handler fileManager:self willProcessPath:source];
if (rename(sourcePath, destPath) == -1) {
if (rename (sourcePath, destPath) == -1) {
if (handler) {
NSDictionary* dict
NSDictionary* errorInfo
= [NSDictionary dictionaryWithObjectsAndKeys:
source, @"Path",
[NSString stringWithCString:strerror(errno)], @"Error",
destination, @"ToPath",
@"cannot move file", @"Error",
nil];
if ([handler fileManager:self shouldProceedAfterError:dict])
if ([handler fileManager:self
shouldProceedAfterError:errorInfo])
return YES;
}
return NO;
}
return YES;
}
// TODO: handle directories
return YES;
return NO;
}
- (BOOL)linkPath:(NSString*)source toPath:(NSString*)destination
handler:handler
{
// TODO
[self notImplemented:_cmd];
return NO;
}
@ -361,8 +481,26 @@ static NSFileManager* defaultManager = nil;
- (BOOL)createFileAtPath:(NSString*)path contents:(NSData*)contents
attributes:(NSDictionary*)attributes
{
// TODO
return NO;
int fd, len, written;
fd = open ([self fileSystemRepresentationWithPath:path],
O_WRONLY|O_TRUNC|O_CREAT, 0644);
if (fd < 0)
return NO;
if (![self changeFileAttributes:attributes atPath:path]) {
close (fd);
return NO;
}
len = [contents length];
if (len)
written = write (fd, [contents bytes], len);
else
written = 0;
close (fd);
return written == len;
}
// Getting and comparing file contents
@ -370,12 +508,14 @@ static NSFileManager* defaultManager = nil;
- (NSData*)contentsAtPath:(NSString*)path
{
// TODO
[self notImplemented:_cmd];
return nil;
}
- (BOOL)contentsEqualAtPath:(NSString*)path1 andPath:(NSString*)path2
{
// TODO
[self notImplemented:_cmd];
return NO;
}
@ -495,12 +635,16 @@ static NSFileManager* defaultManager = nil;
values[8] = NSFileTypeCharacterSpecial;
else if (mode == S_IFBLK)
values[8] = NSFileTypeBlockSpecial;
#ifdef S_IFLNK
else if (mode == S_IFLNK)
values[8] = NSFileTypeSymbolicLink;
#endif
else if (mode == S_IFIFO)
values[8] = NSFileTypeFifo;
#ifdef S_IFSOCK
else if (mode == S_IFSOCK)
values[8] = NSFileTypeSocket;
#endif
else
values[8] = NSFileTypeUnknown;
@ -963,4 +1107,185 @@ static NSFileManager* defaultManager = nil;
{return [self objectForKey:NSFileModificationDate];}
- (NSNumber*)filePosixPermissions;
{return [self objectForKey:NSFilePosixPermissions];}
@implementation NSFileManager (PrivateMethods)
- (BOOL)_copyFile:(NSString*)source toFile:(NSString*)destination
handler:handler
{
NSDictionary* attributes;
int i, bufsize = 8096;
int sourceFd, destFd, fileSize, fileMode;
int rbytes, wbytes;
char buffer[bufsize];
/* Assumes source is a file and exists! */
NSAssert1 ([self fileExistsAtPath:source],
@"source file '%@' does not exist!", source);
attributes = [self fileAttributesAtPath:source traverseLink:NO];
NSAssert1 (attributes, @"could not get the attributes for file '%@'",
source);
fileSize = [[attributes objectForKey:NSFileSize] intValue];
fileMode = [[attributes objectForKey:NSFilePosixPermissions] intValue];
/* Open the source file. In case of error call the handler. */
sourceFd = open ([self fileSystemRepresentationWithPath:source], O_RDONLY);
if (sourceFd < 0) {
if (handler) {
NSDictionary* errorInfo
= [NSDictionary dictionaryWithObjectsAndKeys:
source, @"Path",
@"cannot open file for reading", @"Error",
nil];
return [handler fileManager:self
shouldProceedAfterError:errorInfo];
}
else
return NO;
}
/* Open the destination file. In case of error call the handler. */
destFd = open ([self fileSystemRepresentationWithPath:destination],
O_WRONLY|O_CREAT|O_TRUNC, fileMode);
if (destFd < 0) {
if (handler) {
NSDictionary* errorInfo
= [NSDictionary dictionaryWithObjectsAndKeys:
destination, @"ToPath",
@"cannot open file for writing", @"Error",
nil];
close (sourceFd);
return [handler fileManager:self
shouldProceedAfterError:errorInfo];
}
else
return NO;
}
/* Read bufsize bytes from source file and write them into the destination
file. In case of errors call the handler and abort the operation. */
for (i = 0; i < fileSize; i += rbytes) {
rbytes = read (sourceFd, buffer, bufsize);
if (rbytes < 0) {
if (handler) {
NSDictionary* errorInfo
= [NSDictionary dictionaryWithObjectsAndKeys:
source, @"Path",
@"cannot read from file", @"Error",
nil];
close (sourceFd);
close (destFd);
return [handler fileManager:self
shouldProceedAfterError:errorInfo];
}
else
return NO;
}
wbytes = write (destFd, buffer, rbytes);
if (wbytes != rbytes) {
if (handler) {
NSDictionary* errorInfo
= [NSDictionary dictionaryWithObjectsAndKeys:
source, @"Path",
destination, @"ToPath",
@"cannot write to file", @"Error",
nil];
close (sourceFd);
close (destFd);
return [handler fileManager:self
shouldProceedAfterError:errorInfo];
}
else
return NO;
}
}
close (sourceFd);
close (destFd);
return YES;
}
- (BOOL)_copyPath:(NSString*)source
toPath:(NSString*)destination
handler:handler
{
NSDirectoryEnumerator* enumerator;
NSString* dirEntry;
NSString* sourceFile;
NSString* fileType;
NSString* destinationFile;
NSDictionary* attributes;
NSAutoreleasePool* pool;
pool = [NSAutoreleasePool new];
enumerator = [self enumeratorAtPath:source];
while ((dirEntry = [enumerator nextObject])) {
attributes = [enumerator fileAttributes];
fileType = [attributes objectForKey:NSFileType];
sourceFile = [source stringByAppendingPathComponent:dirEntry];
destinationFile
= [destination stringByAppendingPathComponent:dirEntry];
[handler fileManager:self willProcessPath:sourceFile];
if ([fileType isEqual:NSFileTypeDirectory]) {
if (![self createDirectoryAtPath:destinationFile
attributes:attributes]) {
if (handler) {
NSDictionary* errorInfo
= [NSDictionary dictionaryWithObjectsAndKeys:
destinationFile, @"Path",
@"cannot create directory", @"Error",
nil];
if (![handler fileManager:self
shouldProceedAfterError:errorInfo])
return NO;
}
else
return NO;
}
else {
[enumerator skipDescendents];
if (![self _copyPath:sourceFile toPath:destinationFile
handler:handler])
return NO;
}
}
else if ([fileType isEqual:NSFileTypeRegular]) {
if (![self _copyFile:sourceFile toFile:destinationFile
handler:handler])
return NO;
}
else if ([fileType isEqual:NSFileTypeSymbolicLink]) {
if (![self createSymbolicLinkAtPath:destinationFile
pathContent:sourceFile]) {
if (handler) {
NSDictionary* errorInfo
= [NSDictionary dictionaryWithObjectsAndKeys:
sourceFile, @"Path",
destinationFile, @"ToPath",
@"cannot create symbolic link", @"Error",
nil];
if (![handler fileManager:self
shouldProceedAfterError:errorInfo])
return NO;
}
else
return NO;
}
}
else {
NSLog(@"cannot copy file '%@' of type '%@'", sourceFile, fileType);
}
[self changeFileAttributes:attributes atPath:destinationFile];
}
[pool release];
return YES;
}
@end /* NSFileManager (PrivateMethods) */
@end

View file

@ -182,6 +182,95 @@
return [NSNumber numberWithInt: 0];
}
- (id)initWithBool:(BOOL)value
{
[self dealloc];
return self=[[NSBoolNumber alloc] initValue:&value withObjCType:NULL];
}
- (id)initWithChar:(char)value
{
[self dealloc];
return self=[[NSCharNumber alloc] initValue:&value withObjCType:NULL];
}
- (id)initWithDouble:(double)value
{
[self dealloc];
return self=[[NSDoubleNumber alloc] initValue:&value withObjCType:NULL];
}
- (id)initWithFloat:(float)value
{
[self dealloc];
return self=[[NSFloatNumber alloc] initValue:&value withObjCType:NULL];
}
- (id)initWithInt:(int)value
{
[self dealloc];
return self=[[NSIntNumber alloc] initValue:&value withObjCType:NULL];
}
- (id)initWithLong:(long)value
{
[self dealloc];
return self=[[NSLongNumber alloc] initValue:&value withObjCType:NULL];
}
- (id)initWithLongLong:(long long)value
{
[self dealloc];
return self=[[NSLongLongNumber alloc] initValue:&value withObjCType:NULL];
}
- (id)initWithShort:(short)value
{
[self dealloc];
return self=[[NSShortNumber alloc] initValue:&value withObjCType:NULL];
}
- (id)initWithUnsignedChar:(unsigned char)value
{
[self dealloc];
return self=[[NSUCharNumber alloc] initValue:&value withObjCType:NULL];
}
- (id)initWithUnsignedInt:(unsigned int)value
{
[self dealloc];
return self=[[NSUIntNumber alloc] initValue:&value withObjCType:NULL];
}
- (id)initWithUnsignedLong:(unsigned long)value
{
[self dealloc];
return self=[[NSULongNumber alloc] initValue:&value withObjCType:NULL];
}
- (id)initWithUnsignedLongLong:(unsigned long long)value
{
[self dealloc];
return self=[[NSULongLongNumber alloc] initValue:&value withObjCType:NULL];
}
- (id)initWithUnsignedShort:(unsigned short)value
{
[self dealloc];
return self=[[NSUShortNumber alloc] initValue:&value withObjCType:NULL];
}
- (NSString*) description
{
return [self descriptionWithLocale: nil];
}
- (NSString*) descriptionWithLocale: (NSDictionary*)locale
{
[self subclassResponsibility:_cmd];
return nil;
}
/* All the rest of these methods must be implemented by a subclass */
- (BOOL)boolValue
{
@ -233,8 +322,7 @@
- (NSString *)stringValue
{
[self subclassResponsibility:_cmd];
return 0;
return [self descriptionWithLocale: nil];
}
- (unsigned char)unsignedCharValue
@ -273,6 +361,18 @@
return 0;
}
- (unsigned) hash
{
[self subclassResponsibility:_cmd];
return 0;
}
- (BOOL)isEqualToNumber:(NSNumber *)otherNumber
{
[self subclassResponsibility:_cmd];
return NO;
}
// NSCoding (done by subclasses)
- (void)encodeWithCoder:(NSCoder *)coder
{
@ -286,9 +386,4 @@
return self;
}
- description
{
return [self stringValue];
}
@end

View file

@ -2016,13 +2016,14 @@ else
unsigned char *buff;
char t;
OBJC_MALLOC(buff, char, len+1);
for(count=0; count<len; count++)
if(!flag)
if(!flag)
for(count=0; count<len; count++)
if((t = encode_unitochar([self characterAtIndex: count], encoding)))
buff[count] = t;
else
return nil;
else /* lossy */
else /* lossy */
for(count=0; count<len; count++)
if((t = encode_unitochar([self characterAtIndex: count], encoding)))
buff[count] = t;
else
@ -2039,7 +2040,7 @@ else
simple replacement for character */
buff[count] = '*';
};
buff[count]=0;
buff[count]=0;
return [NSData dataWithBytes: (char *)buff length: count];
}
else

View file

@ -165,12 +165,14 @@
receivingInPort: ip
replyOutPort: op
{
[super initWithCapacity: c
prefix: 0];
assert ([op isValid]);
assert (!ip || [ip isValid]);
_reply_out_port = op;
_receiving_in_port = ip;
self = [super initWithCapacity: c prefix: 0];
if (self)
{
assert ([op isValid]);
assert (!ip || [ip isValid]);
_reply_out_port = op;
_receiving_in_port = ip;
}
return self;
}
@ -193,10 +195,12 @@
- initForSendingWithCapacity: (unsigned)c
replyInPort: ip
{
[super initWithCapacity: c
prefix: [[self class] prefixSize]];
assert ([ip isValid]);
_reply_in_port = ip;
self = [super initWithCapacity: c prefix: [[self class] prefixSize]];
if (self)
{
assert ([ip isValid]);
_reply_in_port = ip;
}
return self;
}

View file

@ -720,6 +720,7 @@ static NSMapTable* port_number_2_port;
p->_port_socket = socket (AF_INET, SOCK_STREAM, 0);
if (p->_port_socket < 0)
{
[p release];
[NSException raise: NSInternalInconsistencyException
format: @"[TcpInPort +newForReceivingFromPortNumber:] socket(): %s",
strerror(errno)];
@ -779,6 +780,7 @@ static NSMapTable* port_number_2_port;
}
}
if (ok == NO) {
[p release];
[NSException raise: NSInternalInconsistencyException
format: @"[TcpInPort +newForReceivingFromPortNumber:] bind(): %s",
strerror(errno)];
@ -796,6 +798,7 @@ static NSMapTable* port_number_2_port;
&size)
< 0)
{
[p release];
[NSException raise: NSInternalInconsistencyException
format: @"[TcpInPort +newForReceivingFromPortNumber:] getsockname(): %s",
strerror(errno)];
@ -811,6 +814,7 @@ static NSMapTable* port_number_2_port;
unique host address that can identify us across the network. */
if (gethostname (hostname, len) < 0)
{
[p release];
[NSException raise: NSInternalInconsistencyException
format: @"[TcpInPort +newForReceivingFromPortNumber:] gethostname(): %s",
strerror(errno)];
@ -832,6 +836,7 @@ static NSMapTable* port_number_2_port;
/* xxx Make this "10" a class variable? */
if (listen (p->_port_socket, 10) < 0)
{
[p release];
[NSException raise: NSInternalInconsistencyException
format: @"[TcpInPort +newForReceivingFromPortNumber:] listen(): %s",
strerror(errno)];
@ -860,7 +865,7 @@ static NSMapTable* port_number_2_port;
if (p) {
int port = [p portNumber];
if (nameServer([name cStringNoCopy], 0, GDO_REGISTER, &sin, port, 1) == 0) {
if (nameServer([name cString], 0, GDO_REGISTER, &sin, port, 1) == 0) {
[p release];
return nil;
}
@ -868,7 +873,7 @@ static NSMapTable* port_number_2_port;
return p;
#else
return [self newForReceivingFromPortNumber:
name_2_port_number ([name cStringNoCopy])];
name_2_port_number ([name cString])];
#endif /* GDOMAP */
}
@ -990,7 +995,7 @@ static NSMapTable* port_number_2_port;
fprintf (stderr,
"%s: Accepted connection from\n %s.\n",
object_get_class_name (self),
[[op description] cStringNoCopy]);
[[op description] cString]);
[NotificationDispatcher
postNotificationName: InPortAcceptedClientNotification
object: self
@ -1154,7 +1159,7 @@ assert(type == ET_RPORT);
fprintf (stderr,
"%s: Closed connection from\n %s\n",
object_get_class_name (self),
[[p description] cStringNoCopy]);
[[p description] cString]);
packet = NSMapGet (_client_sock_2_packet, (void*)s);
if (packet)
@ -1198,6 +1203,12 @@ assert(type == ET_RPORT);
id out_ports[count];
int i;
/* These are here, and not in -dealloc, to prevent
+newForReceivingFromPortNumber: from returning invalid sockets. */
NSMapRemove (socket_2_port, (void*)_port_socket);
NSMapRemove (port_number_2_port,
(void*)(int) ntohs(_listening_address.sin_port));
for (i = 0;
NSNextMapEnumeratorPair (&me, (void*)&sock, (void*)&out_port);
i++)
@ -1213,17 +1224,14 @@ assert(type == ET_RPORT);
getting it. This may help Connection invalidation confusion.
However, then the process might run out of FD's if the close()
was delayed too long. */
if (_port_socket > 0)
{
#ifdef __WIN32__
closesocket (_port_socket);
closesocket (_port_socket);
#else
close (_port_socket);
close (_port_socket);
#endif /* __WIN32__ */
/* These are here, and not in -dealloc, to prevent
+newForReceivingFromPortNumber: from returning invalid sockets. */
NSMapRemove (socket_2_port, (void*)_port_socket);
NSMapRemove (port_number_2_port,
(void*)(int) ntohs(_listening_address.sin_port));
}
/* This also posts a NSPortDidBecomeInvalidNotification. */
[super invalidate];
@ -1414,15 +1422,20 @@ static NSMapTable *out_port_bag = NULL;
!= sockaddr->sin_addr.s_addr))
[self error:"Can't change reply port of an out port once set"];
#else
/* If someone is trying to change the port of this socket, the
old one must have died - invalidate it. */
if ((p->_remote_in_port_address.sin_port
!= sockaddr->sin_port)
|| (p->_remote_in_port_address.sin_addr.s_addr
!= sockaddr->sin_addr.s_addr))
{
[p invalidate];
p = nil;
NSString *od = [p description];
NSMapRemove (out_port_bag, (void*)p);
memcpy (&(p->_remote_in_port_address),
sockaddr,
sizeof (p->_remote_in_port_address));
NSMapInsert (out_port_bag, (void*)p, (void*)p);
NSLog(@"Out port changed from %@ to %@\n", od,
[p description]);
}
#endif
}
@ -1434,7 +1447,7 @@ static NSMapTable *out_port_bag = NULL;
sizeof (p->_remote_in_port_address));
if (debug_tcp_port)
printf ("TcpOutPort setting remote address\n%s\n",
[[self description] cStringNoCopy]);
[[self description] cString]);
}
}
if (p)
@ -1456,6 +1469,7 @@ static NSMapTable *out_port_bag = NULL;
p->_port_socket = socket (AF_INET, SOCK_STREAM, 0);
if (p->_port_socket < 0)
{
[p release];
[NSException raise: NSInternalInconsistencyException
format: @"[TcpInPort newForSendingToSockaddr:...] socket(): %s",
strerror(errno)];
@ -1478,9 +1492,7 @@ static NSMapTable *out_port_bag = NULL;
time being, and may get set later by calling
+newForSendingToSockaddr.. with a non-zero socket, and a
non-NULL sockaddr. */
p->_remote_in_port_address.sin_family = 0;
p->_remote_in_port_address.sin_port = 0;
p->_remote_in_port_address.sin_addr.s_addr = 0;
memset (&(p->_remote_in_port_address), '\0', sizeof(*sockaddr));
}
/* xxx Do I need to bind(_port_socket) to this address? I don't think so. */
@ -1494,18 +1506,12 @@ static NSMapTable *out_port_bag = NULL;
if (connect (p->_port_socket,
(struct sockaddr*)&(p->_remote_in_port_address),
sizeof(p->_remote_in_port_address))
< 0)
sizeof(p->_remote_in_port_address)) < 0)
{
#if 0
close(p->_port_socket);
[NSException raise: NSInternalInconsistencyException
[p release];
[NSException raise: NSInternalInconsistencyException
format: @"[TcpInPort newForSendingToSockaddr:...] connect(): %s",
strerror(errno)];
#else
[p release];
return nil;
#endif
}
/*
@ -1565,7 +1571,7 @@ static NSMapTable *out_port_bag = NULL;
*first_dot = '\0';
}
else
host_cstring = [hostname cStringNoCopy];
host_cstring = [hostname cString];
hp = gethostbyname ((char*)host_cstring);
if (!hp)
[self error: "unknown host: \"%s\"", host_cstring];
@ -1589,7 +1595,7 @@ static NSMapTable *out_port_bag = NULL;
int i;
id c = nil;
found = nameServer([name cStringNoCopy], [hostname cStringNoCopy],
found = nameServer([name cString], [hostname cString],
GDO_LOOKUP, sin, 0, 100);
for (i = 0; c == nil && i < found; i++)
{
@ -1600,8 +1606,7 @@ static NSMapTable *out_port_bag = NULL;
return c;
#else
return [self newForSendingToPortNumber:
name_2_port_number ([name cStringNoCopy])
onHost: hostname];;
name_2_port_number ([name cString]) onHost: hostname];;
#endif /* GDOMAP */
}
@ -1700,22 +1705,6 @@ static NSMapTable *out_port_bag = NULL;
_polling_in_port = nil;
/* This also posts a NSPortDidBecomeInvalidNotification. */
[super invalidate];
/* xxx Perhaps should delay this close() to keep another port from
getting it. This may help Connection invalidation confusion. */
#ifdef __WIN32__
if (closesocket (_port_socket) < 0)
#else
if (close (_port_socket) < 0)
#endif /* __WIN32 */
{
[NSException raise: NSInternalInconsistencyException
format: @"[TcpOutPort -invalidate:] close(): %s",
strerror(errno)];
}
/* This is here, and not in -dealloc, because invalidated
but not dealloc'ed ports should not be returned from
the out_port_bag in +newForSendingToSockaddr:... */
@ -1725,6 +1714,25 @@ static NSMapTable *out_port_bag = NULL;
the socket_2_port in +newForSendingToSockaddr:... */
NSMapRemove (socket_2_port, (void*)_port_socket);
/* This also posts a NSPortDidBecomeInvalidNotification. */
[super invalidate];
/* xxx Perhaps should delay this close() to keep another port from
getting it. This may help Connection invalidation confusion. */
if (_port_socket > 0)
{
#ifdef __WIN32__
if (closesocket (_port_socket) < 0)
#else
if (close (_port_socket) < 0)
#endif /* __WIN32 */
{
[NSException raise: NSInternalInconsistencyException
format: @"[TcpOutPort -invalidate:] close(): %s",
strerror(errno)];
}
}
[port _connectedOutPortInvalidated: self];
[port release];
}

View file

@ -631,9 +631,11 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
{
NSMutableData* d;
int pos;
char *buf;
[self checkRead];
d = [NSMutableData dataWithCapacity:len];
buf = objc_malloc(len);
d = [NSMutableData dataWithBytesNoCopy: buf length: len];
if ((pos = read(descriptor, [d mutableBytes], len)) < 0)
{
[NSException raise: NSFileHandleOperationException