Work on the train.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@14654 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2002-10-05 17:47:54 +00:00
parent 209f46ae7e
commit f05b58bc61
17 changed files with 477 additions and 198 deletions

View file

@ -530,6 +530,78 @@ setup()
* peculiar to its memory management (shrinking, growing, and converting).
*/
static inline char*
UTF8String_c(ivars self)
{
unsigned char *r;
if (self->_count == 0)
{
return "";
}
if (intEnc == NSISOLatin1StringEncoding || intEnc == NSASCIIStringEncoding)
{
r = (unsigned char*)_fastMallocBuffer(self->_count+1);
if (self->_count > 0)
{
memcpy(r, self->_contents.c, self->_count);
}
r[self->_count] = '\0';
}
else
{
unichar *u = 0;
unsigned l = 0;
unsigned s = 0;
/*
* We must convert from internal format to unicode and then to
* UTF8 string encoding.
*/
if (GSToUnicode(&u, &l, self->_contents.c, self->_count, intEnc,
NSDefaultMallocZone(), 0) == NO)
{
[NSException raise: NSCharacterConversionException
format: @"Can't convert to Unicode string."];
}
if (GSFromUnicode((unsigned char**)&r, &s, u, l, NSUTF8StringEncoding,
NSDefaultMallocZone(), GSUniTerminate|GSUniTemporary|GSUniStrict) == NO)
{
NSZoneFree(NSDefaultMallocZone(), u);
[NSException raise: NSCharacterConversionException
format: @"Can't convert from Unicode to UTF8."];
}
NSZoneFree(NSDefaultMallocZone(), u);
}
return r;
}
static inline char*
UTF8String_u(ivars self)
{
unsigned c = self->_count;
if (c == 0)
{
return "";
}
else
{
unsigned int l = 0;
unsigned char *r = 0;
if (GSFromUnicode(&r, &l, self->_contents.u, c, NSUTF8StringEncoding,
NSDefaultMallocZone(), GSUniTerminate|GSUniTemporary|GSUniStrict) == NO)
{
[NSException raise: NSCharacterConversionException
format: @"Can't get UTF8 from Unicode string."];
}
return r;
}
}
static inline BOOL
boolValue_c(ivars self)
{
@ -1826,6 +1898,11 @@ transmute(ivars self, NSString *aString)
* 8-bit string class, storing immutable data in a single buffer.
*/
@implementation GSCString
- (const char *) UTF8String
{
return UTF8String_c((ivars)self);
}
- (BOOL) boolValue
{
return boolValue_c((ivars)self);
@ -2124,6 +2201,11 @@ transmute(ivars self, NSString *aString)
@implementation GSUnicodeString
- (const char *) UTF8String
{
return UTF8String_u((ivars)self);
}
- (BOOL) boolValue
{
return boolValue_u((ivars)self);

View file

@ -216,7 +216,7 @@ gregorianDateFromAbsolute(int abs, int *day, int *month, int *year)
* External - so NSDate and others can use it.
*/
NSTimeInterval
GSTime(int day, int month, int year, int h, int m, int s, int mil)
GSTime(int day, int month, int year, int hour, int minute, int second, int mil)
{
NSTimeInterval a;
@ -225,9 +225,9 @@ GSTime(int day, int month, int year, int h, int m, int s, int mil)
// Calculate date as GMT
a -= GREGORIAN_REFERENCE;
a = (NSTimeInterval)a * 86400;
a += h * 3600;
a += m * 60;
a += s;
a += hour * 3600;
a += minute * 60;
a += second;
a += mil/1000.0;
return a;
}
@ -237,7 +237,7 @@ GSTime(int day, int month, int year, int h, int m, int s, int mil)
* elements.<br />
* External - so NSDate and others can use it.
*/
static void
void
GSBreakTime(NSTimeInterval when, int *year, int *month, int *day,
int *hour, int *minute, int *second, int *mil)
{

View file

@ -506,6 +506,7 @@ static BOOL multi_threaded = NO;
}
/**
* Not used in GNUstep
*/
+ (id) currentConversation
{
@ -1164,7 +1165,8 @@ static BOOL multi_threaded = NO;
}
/**
* Returns YES if the connection is invalid, NO otherwise.
* Returns YES if the connection is valid, NO otherwise.
* A connection is valid until it has been sent an -invalidate message.
*/
- (BOOL) isValid
{
@ -1206,7 +1208,8 @@ static BOOL multi_threaded = NO;
/**
* Returns YES if the connection permits multiple threads to use it to
* send requests, NO otherwise.
* send requests, NO otherwise.<br />
* See the -enableMultipleThreads method.
*/
- (BOOL) multipleThreadsEnabled
{
@ -1486,8 +1489,10 @@ static BOOL multi_threaded = NO;
/**
* Sets the time interval that the NSConnection will wait for a
* reply to one of its requests before raising an
* NSPortTimeoutException.
* reply for one of its requests before raising an
* NSPortTimeoutException.<br />
* NB. In GNUstep you may also get such an exception if the connection
* becomes invalidated while waiting for a reply to a request.
*/
- (void) setReplyTimeout: (NSTimeInterval)to
{

View file

@ -317,13 +317,13 @@ static Class NSCountedSet_concrete_class;
* purge the set even when uniquing is turned off.
*/
void
GSUPurge(unsigned level)
GSUPurge(unsigned count)
{
if (uniqueLock != nil)
{
(*lockImp)(uniqueLock, @selector(lock));
}
[uniqueSet purge: level];
[uniqueSet purge: count];
if (uniqueLock != nil)
{
(*unlockImp)(uniqueLock, @selector(unlock));
@ -339,7 +339,7 @@ GSUPurge(unsigned level)
* alter the set even when uniquing is turned off.
*/
id
GSUSet(id obj, unsigned level)
GSUSet(id anObject, unsigned count)
{
id found;
unsigned i;
@ -348,29 +348,29 @@ GSUSet(id obj, unsigned level)
{
(*lockImp)(uniqueLock, @selector(lock));
}
found = [uniqueSet member: obj];
found = [uniqueSet member: anObject];
if (found == nil)
{
found = obj;
for (i = 0; i < level; i++)
found = anObject;
for (i = 0; i < count; i++)
{
[uniqueSet addObject: obj];
[uniqueSet addObject: anObject];
}
}
else
{
i = [uniqueSet countForObject: found];
if (i < level)
if (i < count)
{
while (i < level)
while (i < count)
{
[uniqueSet addObject: found];
i++;
}
}
else if (i > level)
else if (i > count)
{
while (i > level)
while (i > count)
{
[uniqueSet removeObject: found];
i--;
@ -391,7 +391,7 @@ GSUSet(id obj, unsigned level)
* If uniquing is turned off, it simply returns its argument.
*/
id
GSUnique(id obj)
GSUnique(id anObject)
{
if (uniquing == YES)
{
@ -399,13 +399,13 @@ GSUnique(id obj)
{
(*lockImp)(uniqueLock, @selector(lock));
}
obj = (*uniqueImp)(uniqueSet, @selector(unique:), obj);
anObject = (*uniqueImp)(uniqueSet, @selector(unique:), anObject);
if (uniqueLock != nil)
{
(*unlockImp)(uniqueLock, @selector(unlock));
}
}
return obj;
return anObject;
}
/**

View file

@ -461,8 +461,8 @@ failure:
* and with the specified length. Invokes
* -initWithBytesNoCopy:length:freeWhenDone:
*/
+ (id) dataWithBytesNoCopy: (void*)bytes
length: (unsigned int)length
+ (id) dataWithBytesNoCopy: (void*)aBuffer
length: (unsigned int)bufferSize
freeWhenDone: (BOOL)shouldFree
{
NSData *d;
@ -475,7 +475,9 @@ failure:
{
d = [dataStatic allocWithZone: NSDefaultMallocZone()];
}
d = [d initWithBytesNoCopy: bytes length: length freeWhenDone: shouldFree];
d = [d initWithBytesNoCopy: aBuffer
length: bufferSize
freeWhenDone: shouldFree];
return AUTORELEASE(d);
}
@ -592,7 +594,8 @@ failure:
* The value fo shouldFree specifies whether the receiver should
* attempt to free the memory pointer to by aBuffer when the receiver
* is deallocated ... ie. it says whether the receiver <em>owns</em>
* the memory.
* the memory. Supplying the wrong value here will lead to memory
* leaks or crashes.
*/
- (id) initWithBytesNoCopy: (void*)aBuffer
length: (unsigned int)bufferSize

View file

@ -152,7 +152,7 @@ BOOL
GSInstanceVariableInfo(id obj, NSString *iVarName,
const char **type, unsigned *size, unsigned *offset)
{
const char *name = [iVarName cString];
const char *name = [iVarName UTF8String];
return GSFindInstanceVariable(obj, name, type, size, offset);
}
@ -160,13 +160,13 @@ GSInstanceVariableInfo(id obj, NSString *iVarName,
/** ## deprecated ##
*/
BOOL
GSGetInstanceVariable(id obj, NSString *iVarName, void *data)
GSGetInstanceVariable(id obj, NSString *name, void *data)
{
const char *name = [iVarName cString];
const char *cName = [name UTF8String];
int offset;
unsigned int size;
if (GSFindInstanceVariable(obj, name, 0, &size, &offset) == YES)
if (GSFindInstanceVariable(obj, cName, 0, &size, &offset) == YES)
{
GSGetVariable(obj, offset, size, data);
return YES;
@ -177,13 +177,13 @@ GSGetInstanceVariable(id obj, NSString *iVarName, void *data)
/** ## deprecated ##
*/
BOOL
GSSetInstanceVariable(id obj, NSString *iVarName, const void *data)
GSSetInstanceVariable(id obj, NSString *name, const void *data)
{
const char *name = [iVarName cString];
const char *cName = [name UTF8String];
int offset;
unsigned int size;
if (GSFindInstanceVariable(obj, name, 0, &size, &offset) == YES)
if (GSFindInstanceVariable(obj, cName, 0, &size, &offset) == YES)
{
GSSetVariable(obj, offset, size, data);
return YES;

View file

@ -584,8 +584,8 @@ typedef enum {
return [self portForName: name onHost: nil];
}
- (NSPort*) portForName: (NSString*)name
onHost: (NSString*)host
- (BOOL) _lookupName: (NSString*)name onHost: (NSString*)host
intoAddress: (NSString**)addr andPort: (unsigned*)port
{
GSPortCom *com = nil;
NSRunLoop *loop = [NSRunLoop currentRunLoop];
@ -593,11 +593,11 @@ typedef enum {
struct in_addr *svrs = &singleServer;
unsigned numSvrs = 1;
unsigned count;
unsigned portNum = 0;
unsigned len;
NSMutableArray *array;
NSDate *limit;
*port = 0;
if (name == nil)
{
[NSException raise: NSInvalidArgumentException
@ -711,7 +711,7 @@ typedef enum {
{
unsigned i;
portNum = 0;
*port = 0;
count = 0;
do
{
@ -740,13 +740,12 @@ typedef enum {
{
break; /* No servers left to try! */
}
[loop runMode: mode
beforeDate: limit];
[loop runMode: mode beforeDate: limit];
/*
* Check for completed operations.
*/
while (portNum == 0 && i-- > 0)
while (*port == 0 && i-- > 0)
{
com = [array objectAtIndex: i];
if ([com isActive] == NO)
@ -754,9 +753,8 @@ typedef enum {
[com close];
if ([com state] == GSPC_DONE)
{
portNum
= GSSwapBigI32ToHost(*(gsu32*)[[com data] bytes]);
if (portNum != 0)
*port = GSSwapBigI32ToHost(*(gsu32*)[[com data] bytes]);
if (*port != 0)
{
singleServer = [com addr];
}
@ -765,7 +763,7 @@ typedef enum {
}
}
}
while (portNum == 0 && [limit timeIntervalSinceNow] > 0);
while (*port == 0 && [limit timeIntervalSinceNow] > 0);
/*
* Make sure that any outstanding lookups are cancelled.
@ -788,14 +786,32 @@ typedef enum {
NS_ENDHANDLER
[serverLock unlock];
if (portNum)
if (*port)
{
*addr = [NSString stringWithCString: inet_ntoa(singleServer)];
return YES;
}
else
{
return NO;
}
}
- (NSPort*) portForName: (NSString*)name
onHost: (NSString*)host
{
NSString *addr;
unsigned portNum = 0;
if ([self _lookupName: name
onHost: host
intoAddress: &addr
andPort: &portNum] == YES)
{
if (portClass == [GSTcpPort class])
{
NSString *addr;
NSHost *host;
addr = [NSString stringWithCString: inet_ntoa(singleServer)];
host = [NSHost hostWithAddress: addr];
return (NSPort*)[GSTcpPort portWithNumber: portNum
onHost: host
@ -854,7 +870,6 @@ typedef enum {
NS_DURING
{
NSMutableSet *known = NSMapGet(_portMap, port);
GSPortCom *tmp;
/*
* If there is no set of names for this port - create one.
@ -875,8 +890,7 @@ typedef enum {
if ([known count] == 0)
{
com = [GSPortCom new];
[com startPortUnregistration: [port portNumber]
withName: nil];
[com startPortUnregistration: [port portNumber] withName: nil];
while ([limit timeIntervalSinceNow] > 0 && [com isActive] == YES)
{
[loop runMode: mode
@ -888,18 +902,14 @@ typedef enum {
[NSException raise: NSPortTimeoutException
format: @"timed out unregistering port"];
}
tmp = com;
com = nil;
RELEASE(tmp);
DESTROY(com);
}
com = [GSPortCom new];
[com startPortRegistration: [port portNumber]
withName: name];
[com startPortRegistration: [port portNumber] withName: name];
while ([limit timeIntervalSinceNow] > 0 && [com isActive] == YES)
{
[loop runMode: mode
beforeDate: limit];
[loop runMode: mode beforeDate: limit];
}
[com close];
if ([com state] != GSPC_DONE)
@ -914,19 +924,53 @@ typedef enum {
result = GSSwapBigI32ToHost(*(gsu32*)[[com data] bytes]);
if (result == 0)
{
[NSException raise: NSGenericException
format: @"Unable to register name '%@' for the port -\n%@\n"
unsigned int portNum;
NSString *addr;
BOOL found;
NS_DURING
{
found = [self _lookupName: name
onHost: @""
intoAddress: &addr
andPort: &portNum];
}
NS_HANDLER
{
found = NO;
}
NS_ENDHANDLER
if (found == YES)
{
[NSException raise: NSGenericException
format: @"Unable to register name '%@' for the port -\n%@\n"
@"It appears that a process is already registered with this name at port\n"
@"'%d' IP address %@\n"
@"Perhaps this program ran before and was shut down without unregistering,\n"
@"so another process may be running using the same network port. If this is\n"
@"the case, you can use -\n"
@"gdomap -U '%@'\n"
@"to remove the registration so that you can attempt this operation again.",
name, port, portNum, addr, name];
}
else
{
[NSException raise: NSGenericException
format: @"Unable to register name '%@' for the port -\n%@\n"
@"Typically, this might mean that a process is already running with the name\n"
@"'%@' ...\n"
@"Try the command -\n"
@" gdomap -L '%@'\n"
@" gdomap -M localhost -L '%@'\n"
@"to find its network details.\n"
@"Alternatively, it may have been shut down without unregistering, and\n"
@"another process may be running using the same network port. If this is\n"
@"the case, you can use -\n"
@"gdomap -U '%@'\n"
@"to remove the registration so that you can attempt this operation again.",
name, port, name, name, name];
name, port, name, name, name];
}
}
else
{
@ -938,16 +982,14 @@ typedef enum {
NSMapInsert(_nameMap, name, port);
}
}
tmp = com;
com = nil;
RELEASE(tmp);
DESTROY(com);
}
NS_HANDLER
{
/*
* If we had a problem - close and unlock before continueing.
*/
RELEASE(com);
DESTROY(com);
[serverLock unlock];
[localException raise];
}

View file

@ -4339,7 +4339,7 @@ handle_printf_atsign (FILE *stream,
* Removes the specified prefix from the string. Raises an exception
* if the prefix is not present.
*/
- (void) deletePrefix: (NSString*)prefix;
- (void) deletePrefix: (NSString*)prefix
{
NSCAssert2([self hasPrefix: prefix],
@"'%@' does not have the prefix '%@'", self, prefix);