diff --git a/ChangeLog b/ChangeLog index 79d9cf62a..6518d0c4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2000-06-30 Richard Frith-Macdonald + + * Headers/gnustep/base/NSDate.h: Added GSTime() function + * Source/NSDate.m: More efficient MINGW date creation + * Source/NSCalendarDate.m: optimised date creation from yymmddhhmmss + * Source/NSData.m: MINGW file read and write operations added (untested) + * Source/NSFileManager.m: MINGW file operations updated. + 2000-06-30 Richard Frith-Macdonald Coding/decoding modifications to make system more in line with diff --git a/Headers/gnustep/base/NSDate.h b/Headers/gnustep/base/NSDate.h index 8f1080194..3fd6db3e1 100644 --- a/Headers/gnustep/base/NSDate.h +++ b/Headers/gnustep/base/NSDate.h @@ -107,6 +107,7 @@ typedef double NSTimeInterval; @end NSTimeInterval GSTimeNow(); /* Get time since reference date*/ +NSTimeInterval GSTime(int day, int mon, int year, int hour, int min, int sec); #endif diff --git a/Source/GSConnection.m b/Source/GSConnection.m index 4831f5e40..50fa03b3e 100644 --- a/Source/GSConnection.m +++ b/Source/GSConnection.m @@ -195,7 +195,7 @@ static unsigned local_object_counter = 0; + (void) setDebug: (int)val; - (void) handlePortMessage: (NSPortMessage*)msg; -- _getReceivedReplyRmcWithSequenceNumber: (int)n; +- _getReplyRmc: (int)n; - (NSPortCoder*) _makeRmc: (int)sequence; - (int) _newMsgNumber; - (void) _sendRmc: (NSPortCoder*)c type: (int)msgid; @@ -992,7 +992,7 @@ static int messages_received_count; op = [self _makeRmc: seq_num]; [self _sendRmc: op type: ROOTPROXY_REQUEST]; - ip = [self _getReceivedReplyRmcWithSequenceNumber: seq_num]; + ip = [self _getReplyRmc: seq_num]; [ip decodeValueOfObjCType: @encode(id) at: &newProxy]; return AUTORELEASE(newProxy); } @@ -1264,7 +1264,7 @@ static int messages_received_count; } /* xxx Why do we get the reply packet in here, and not just before calling dissect_method_return() below? */ - ip = [self _getReceivedReplyRmcWithSequenceNumber: seq_num]; + ip = [self _getReplyRmc: seq_num]; /* Find out if the server is returning an exception instead of the return values. */ [ip decodeValueOfObjCType: @encode(BOOL) at: &is_exception]; @@ -1318,7 +1318,7 @@ static int messages_received_count; [op encodeValueOfObjCType: ":" at: &sel]; [op encodeValueOfObjCType: @encode(unsigned) at: &target]; [self _sendRmc: op type: METHODTYPE_REQUEST]; - ip = [self _getReceivedReplyRmcWithSequenceNumber: seq_num]; + ip = [self _getReplyRmc: seq_num]; [ip decodeValueOfObjCType: @encode(char*) at: &type]; return type; } @@ -1510,156 +1510,6 @@ static int messages_received_count; debug_connection = val; } - - - -/* Methods for handling client and server, requests and replies */ - -/* NSDistantObject's -forward: : method calls this to the the message over the wire. */ -- (retval_t) forwardForProxy: (NSDistantObject*)object - selector: (SEL)sel - argFrame: (arglist_t)argframe -{ - NSPortCoder *op; - - /* The callback for encoding the args of the method call. */ - void encoder (int argnum, void *datum, const char *type, int flags) - { -#define ENCODED_ARGNAME @"argument value" - switch (*type) - { - case _C_ID: - if (flags & _F_BYCOPY) - [op encodeBycopyObject: *(id*)datum]; -#ifdef _F_BYREF - else if (flags & _F_BYREF) - [op encodeByrefObject: *(id*)datum]; -#endif - else - [op encodeObject: *(id*)datum]; - break; - default: - [op encodeValueOfObjCType: type at: datum]; - } - } - - /* Encode the method on an RMC, and send it. */ - { - BOOL out_parameters; - const char *type; - int seq_num; - retval_t retframe; - - NSParameterAssert (_isValid); - - /* get the method types from the selector */ -#if NeXT_runtime - [NSException - raise: NSGenericException - format: @"Sorry, distributed objects does not work with NeXT runtime"]; - /* type = [object selectorTypeForProxy: sel]; */ -#else - type = sel_get_type(sel); -#endif - if (type == 0 || *type == '\0') { - type = [[object methodSignatureForSelector: sel] methodType]; - if (type) { - sel_register_typed_name(sel_get_name(sel), type); - } - } - NSParameterAssert(type); - NSParameterAssert(*type); - - seq_num = [self _newMsgNumber]; - op = [self _makeRmc: seq_num]; - - if (debug_connection > 4) - NSLog(@"building packet seq %d", seq_num); - - /* Send the types that we're using, so that the performer knows - exactly what qualifiers we're using. - If all selectors included qualifiers, and if I could make - sel_types_match() work the way I wanted, we wouldn't need to do - this. */ - [op encodeValueOfObjCType: @encode(char*) at: &type]; - - /* xxx This doesn't work with proxies and the NeXT runtime because - type may be a method_type from a remote machine with a - different architecture, and its argframe layout specifiers - won't be right for this machine! */ - out_parameters = mframe_dissect_call (argframe, type, encoder); - - [self _sendRmc: op type: METHOD_REQUEST]; - - if (debug_connection > 1) - NSLog(@"Sent message to 0x%x", (gsaddr)self); - - /* Get the reply rmc, and decode it. */ - { - NSPortCoder *ip = nil; - BOOL is_exception = NO; - - void decoder(int argnum, void *datum, const char *type, int flags) - { - if (type == 0) { - if (ip) { - /* this must be here to avoid trashing alloca'ed retframe */ - [ip dismiss]; - ip = (id)-1; - } - return; - } - /* If we didn't get the reply packet yet, get it now. */ - if (!ip) - { - if (!_isValid) - { - [NSException raise: NSGenericException - format: @"connection waiting for request was shut down"]; - } - /* xxx Why do we get the reply packet in here, and not - just before calling dissect_method_return() below? */ - ip = [self _getReceivedReplyRmcWithSequenceNumber: seq_num]; - /* Find out if the server is returning an exception instead - of the return values. */ - [ip decodeValueOfObjCType: @encode(BOOL) at: &is_exception]; - if (is_exception) - { - /* Decode the exception object, and raise it. */ - id exc; - [ip decodeValueOfObjCType: @encode(id) at: &exc]; - [ip dismiss]; - ip = (id)-1; - /* xxx Is there anything else to clean up in - dissect_method_return()? */ - [exc raise]; - } - } - [ip decodeValueOfObjCType: type at: datum]; - /* -decodeValueOfObjCType: at: malloc's new memory - for char*'s. We need to make sure it gets freed eventually - so we don't have a memory leak. Request here that it be - autorelease'ed. Also autorelease created objects. */ - if (*type == _C_CHARPTR) - [NSData dataWithBytesNoCopy: *(void**)datum length: 1]; - else if (*type == _C_ID) - [*(id*)datum autorelease]; - } - - retframe = mframe_build_return (argframe, type, out_parameters, - decoder); - /* Make sure we processed all arguments, and dismissed the IP. - IP is always set to -1 after being dismissed; the only places - this is done is in this function DECODER(). IP will be nil - if mframe_build_return() never called DECODER(), i.e. when - we are just returning (void).*/ - NSAssert(ip == (id)-1 || ip == nil, NSInternalInconsistencyException); - _repInCount++; /* received a reply */ - return retframe; - } - } -} - /* NSConnection calls this to service the incoming method request. */ - (void) _service_forwardForProxy: (NSPortCoder*)aRmc { @@ -1958,14 +1808,12 @@ static int messages_received_count; [self runConnectionUntilDate: [NSDate distantFuture]]; } -/* Deal with an RMC, either by queuing it for later service, or - by servicing it right away. This method is called by the - _receivePort's received-packet-invocation. */ - -/* Check the queue, then try to get it from the network by waiting - while we run the NSRunLoop. Raise exception if we don't get anything - before timing out. */ -- _getReceivedReplyRmcWithSequenceNumber: (int)sn +/* + * Check the queue, then try to get it from the network by waiting + * while we run the NSRunLoop. Raise exception if we don't get anything + * before timing out. + */ +- _getReplyRmc: (int)sn { NSPortCoder *rmc; NSDate *timeout_date = nil; @@ -2016,7 +1864,6 @@ static int messages_received_count; - (void) _sendRmc: (NSPortCoder*)c type: (int)msgid { - NSPortMessage *message; NSDate *limit; BOOL raiseException = NO; NSMutableArray *components = [c _components]; @@ -2033,12 +1880,12 @@ static int messages_received_count; } [components addObject: d]; } - message = [[NSPortMessage alloc] initWithSendPort: [self sendPort] - receivePort: [self receivePort] - components: components]; - [message setMsgid: msgid]; limit = [NSDate dateWithTimeIntervalSinceNow: [self requestTimeout]]; - if ([message sendBeforeDate: limit] == NO) + if ([_sendPort sendBeforeDate: limit + msgid: msgid + components: components + from: _receivePort + reserved: [_sendPort reservedSpaceLength]] == NO) { NSString *text; @@ -2275,7 +2122,7 @@ static int messages_received_count; [op encodeValueOfObjCType: @encode(typeof(target)) at: &target]; [self _sendRmc: op type: PROXY_RETAIN]; - ip = [self _getReceivedReplyRmcWithSequenceNumber: seq_num]; + ip = [self _getReplyRmc: seq_num]; [ip decodeValueOfObjCType: @encode(id) at: &result]; if (result != nil) NSLog(@"failed to retain target - %@", result); diff --git a/Source/GSTcpPort.m b/Source/GSTcpPort.m index eb6f8e5f5..34cc20e10 100644 --- a/Source/GSTcpPort.m +++ b/Source/GSTcpPort.m @@ -51,6 +51,9 @@ extern int errno; +#define DO_LOCK(X) {NSDebugMLLog(@"GSTcpHandle",@"lock %@",X); [X lock];} +#define DO_UNLOCK(X) {NSDebugMLLog(@"GSTcpHandle",@"unlock %@",X); [X unlock];} + #define GS_CONNECTION_MSG 0 #define NETBLOCK 8192 @@ -241,7 +244,7 @@ decodePort(NSData *data) pnum = GSSwapBigI16ToHost(pi->num); addr = [NSString stringWithCString: pi->addr]; - NSDebugLLog(@"NSPort", @"Decoded port as '%@:%d'", addr, pnum); + NSDebugFLLog(@"NSPort", @"Decoded port as '%@:%d'", addr, pnum); host = [NSHost hostWithAddress: addr]; return [GSTcpPort portWithNumber: pnum @@ -293,7 +296,7 @@ encodePort(GSTcpPort *port) pi->num = GSSwapHostI16ToBig(pnum); [addr getCString: pi->addr]; - NSDebugLLog(@"NSPort", @"Encoded port as '%@:%d'", addr, pnum); + NSDebugFLLog(@"NSPort", @"Encoded port as '%@:%d'", addr, pnum); return data; } @@ -348,7 +351,7 @@ encodePort(GSTcpPort *port) BOOL gotAddr = NO; NSRunLoop *l; - NSDebugLLog(@"GSTcpHandle", @"Connecting before %@", when); + NSDebugMLLog(@"GSTcpHandle", @"Connecting before %@", when); if (state != GS_H_UNCON) { NSLog(@"attempting connect on connected handle"); @@ -469,7 +472,7 @@ encodePort(GSTcpPort *port) DESTROY(rData); DESTROY(rItems); DESTROY(wMsgs); - RELEASE(myLock); + DESTROY(myLock); [super dealloc]; } @@ -502,15 +505,15 @@ encodePort(GSTcpPort *port) - (void) invalidate { - [myLock lock]; + DO_LOCK(myLock); if (valid == YES) { valid = NO; - NSDebugLLog(@"GSTcpHandle", @"invalidated"); + NSDebugMLLog(@"GSTcpHandle", @"invalidated", 0); [[self recvPort] removeHandle: self]; [[self sendPort] removeHandle: self]; } - [myLock unlock]; + DO_UNLOCK(myLock); } - (BOOL) isValid @@ -531,7 +534,7 @@ encodePort(GSTcpPort *port) extra: (void*)extra forMode: (NSString*)mode { - NSDebugLLog(@"GSTcpHandle", @"Received %s event", + NSDebugMLLog(@"GSTcpHandle", @"received %s event", type == ET_RPORT ? "read" : "write"); /* * If we have been invalidated (desc < 0) then we should ignore this @@ -589,7 +592,7 @@ encodePort(GSTcpPort *port) { if (res == 0) { - NSDebugLLog(@"GSTcpHandle", @"read attempt failed - eof"); + NSDebugMLLog(@"GSTcpHandle", @"read attempt failed - eof", 0); [self invalidate]; return; } @@ -601,7 +604,7 @@ encodePort(GSTcpPort *port) } res = 0; /* Interrupted - continue */ } - NSDebugLLog(@"GSTcpHandle", @"read %d bytes", res); + NSDebugMLLog(@"GSTcpHandle", @"read %d bytes", res); rLength += res; @@ -801,7 +804,7 @@ encodePort(GSTcpPort *port) len = write(desc, [d bytes], [d length]); if (len == [d length]) { - NSDebugLLog(@"GSTcpHandle", @"wrote %d bytes", len); + NSDebugMLLog(@"GSTcpHandle", @"wrote %d bytes", len); state = GS_H_CONNECTED; } else @@ -846,7 +849,7 @@ encodePort(GSTcpPort *port) } else { - NSDebugLLog(@"GSTcpHandle", @"wrote %d bytes", res); + NSDebugMLLog(@"GSTcpHandle", @"wrote %d bytes", res); wLength += res; if (wLength == l) { @@ -886,7 +889,7 @@ encodePort(GSTcpPort *port) BOOL sent = NO; NSAssert([components count] > 0, NSInternalInconsistencyException); - NSDebugLLog(@"GSTcpHandle", @"Sending message before %@", when); + NSDebugMLLog(@"GSTcpHandle", @"Sending message before %@", when); [wMsgs addObject: components]; l = [NSRunLoop currentRunLoop]; @@ -911,7 +914,7 @@ encodePort(GSTcpPort *port) sent = YES; } RELEASE(self); - NSDebugLLog(@"GSTcpHandle", @"Message send %d", sent); + NSDebugMLLog(@"GSTcpHandle", @"Message send %d", sent); return sent; } @@ -1156,7 +1159,7 @@ static NSMapTable *tcpPortMap = 0; * Ok - now add the port for the host */ NSMapInsert(thePorts, (void*)aHost, (void*)port); - NSDebugLLog(@"NSPort", @"Created listening port: %@", port); + NSDebugMLLog(@"NSPort", @"Created listening port: %@", port); } } else @@ -1180,13 +1183,13 @@ static NSMapTable *tcpPortMap = 0; * Record the port by host. */ NSMapInsert(thePorts, (void*)aHost, (void*)port); - NSDebugLLog(@"NSPort", @"Created speaking port: %@", port); + NSDebugMLLog(@"NSPort", @"Created speaking port: %@", port); } IF_NO_GC(AUTORELEASE(port)); } else { - NSDebugLLog(@"NSPort", @"Using pre-existing port: %@", port); + NSDebugMLLog(@"NSPort", @"Using pre-existing port: %@", port); } [tcpPortLock unlock]; @@ -1195,7 +1198,7 @@ static NSMapTable *tcpPortMap = 0; - (void) addHandle: (GSTcpHandle*)handle forSend: (BOOL)send { - [myLock lock]; + DO_LOCK(myLock); if (send == YES) { if (handle->caller == YES) @@ -1208,7 +1211,7 @@ static NSMapTable *tcpPortMap = 0; handle->recvPort = GS_GC_HIDE(self); } NSMapInsert(handles, (void*)(gsaddr)[handle descriptor], (void*)handle); - [myLock unlock]; + DO_UNLOCK(myLock); } - (NSString*) address @@ -1223,7 +1226,7 @@ static NSMapTable *tcpPortMap = 0; - (void) dealloc { - [self invalidate]; + [self gcFinalize]; DESTROY(host); [super dealloc]; } @@ -1253,7 +1256,7 @@ static NSMapTable *tcpPortMap = 0; int sock; GSTcpHandle *handle; - [myLock lock]; + DO_LOCK(myLock); /* * Make sure there is enough room in the provided array. @@ -1274,7 +1277,7 @@ static NSMapTable *tcpPortMap = 0; { fds[(*count)++] = sock; } - [myLock unlock]; + DO_UNLOCK(myLock); } - (GSTcpHandle*) handleForPort: (GSTcpPort*)recvPort beforeDate: (NSDate*)when @@ -1283,7 +1286,7 @@ static NSMapTable *tcpPortMap = 0; int sock; GSTcpHandle *handle = nil; - [myLock lock]; + DO_LOCK(myLock); /* * Enumerate all our socket handles, and look for one with port. */ @@ -1292,7 +1295,7 @@ static NSMapTable *tcpPortMap = 0; { if ([handle recvPort] == recvPort) { - [myLock unlock]; + DO_UNLOCK(myLock); return handle; } } @@ -1320,7 +1323,7 @@ static NSMapTable *tcpPortMap = 0; [recvPort addHandle: handle forSend: NO]; } } - [myLock unlock]; + DO_UNLOCK(myLock); /* * If we succeeded in creating a new handle - connect to remote host. */ @@ -1341,12 +1344,12 @@ static NSMapTable *tcpPortMap = 0; if (d == nil) { - NSDebugLLog(@"NSPort", @"No delegate to handle incoming message"); + NSDebugMLLog(@"NSPort", @"No delegate to handle incoming message", 0); return; } if ([d respondsToSelector: @selector(handlePortMessage:)] == NO) { - NSDebugLLog(@"NSPort", @"delegate doesn't handle messages"); + NSDebugMLLog(@"NSPort", @"delegate doesn't handle messages", 0); return; } [d handlePortMessage: m]; @@ -1371,7 +1374,7 @@ static NSMapTable *tcpPortMap = 0; - (void) invalidate { - [myLock lock]; + DO_LOCK(myLock); if ([self isValid]) { @@ -1404,8 +1407,7 @@ static NSMapTable *tcpPortMap = 0; handles = 0; [super invalidate]; } - [myLock unlock]; - DESTROY(myLock); + DO_UNLOCK(myLock); } - (BOOL) isEqual: (id)anObject @@ -1462,10 +1464,10 @@ static NSMapTable *tcpPortMap = 0; } else { - [myLock lock]; + DO_LOCK(myLock); handle = (GSTcpHandle*)NSMapGet(handles, (void*)(gsaddr)desc); AUTORELEASE(RETAIN(handle)); - [myLock unlock]; + DO_UNLOCK(myLock); if (handle == nil) { NSLog(@"No handle for event on descriptor %d", desc); @@ -1484,7 +1486,7 @@ static NSMapTable *tcpPortMap = 0; */ - (void) removeHandle: (GSTcpHandle*)handle { - [myLock lock]; + DO_LOCK(myLock); if ([handle sendPort] == self) { if (handle->caller == YES) @@ -1502,7 +1504,7 @@ static NSMapTable *tcpPortMap = 0; { [self invalidate]; } - [myLock unlock]; + DO_UNLOCK(myLock); } /* diff --git a/Source/NSCalendarDate.m b/Source/NSCalendarDate.m index 6e406ccd2..b41b19161 100644 --- a/Source/NSCalendarDate.m +++ b/Source/NSCalendarDate.m @@ -47,6 +47,60 @@ #define GREGORIAN_REFERENCE 730486 +static inline int +lastDayOfGregorianMonth(int year, int month) +{ + switch (month) + { + case 2: + if ((((year % 4) == 0) && ((year % 100) != 0)) + || ((year % 400) == 0)) + return 29; + else + return 28; + case 4: + case 6: + case 9: + case 11: return 30; + default: return 31; + } +} + +static inline int +absoluteGregorianDay(int day, int month, int year) +{ + int m, N; + + N = day; // day of month + for (m = month - 1; m > 0; m--) // days in prior months this year + N = N + lastDayOfGregorianMonth(m, year); + return + (N // days this year + + 365 * (year - 1) // days in previous years ignoring leap days + + (year - 1)/4 // Julian leap days before this year... + - (year - 1)/100 // ...minus prior century years... + + (year - 1)/400); // ...plus prior years divisible by 400 +} + +/* + * External - so NSDate can use it. + */ +NSTimeInterval +GSTime(int day, int month, int year, int h, int m, int s) +{ + NSTimeInterval a; + + a = (NSTimeInterval)absoluteGregorianDay(day, month, year); + + // Calculate date as GMT + a -= GREGORIAN_REFERENCE; + a = (NSTimeInterval)a * 86400; + a += h * 3600; + a += m * 60; + a += s; + return a; +} + @interface NSCalendarDate (Private) - (void)getYear: (int *)year month: (int *)month day: (int *)day @@ -628,18 +682,11 @@ second: (unsigned int)second timeZone: (NSTimeZone *)aTimeZone { - int a; int c; NSTimeInterval s; - a = [self absoluteGregorianDay: day month: month year: year]; - // Calculate date as GMT - a -= GREGORIAN_REFERENCE; - s = (double)a * 86400; - s += hour * 3600; - s += minute * 60; - s += second; + s = GSTime(day, month, year, hour, minute, second); // Assign time zone detail _time_zone = RETAIN([aTimeZone @@ -800,7 +847,7 @@ day: &d month: &m year: &y]; days = d; for (i = m - 1; i > 0; i--) // days in prior months this year - days = days + [self lastDayOfGregorianMonth: i year: y]; + days = days + lastDayOfGregorianMonth(i, y); return days; } @@ -1240,34 +1287,12 @@ - (int) lastDayOfGregorianMonth: (int)month year: (int)year { - switch (month) { - case 2: - if ((((year % 4) == 0) && ((year % 100) != 0)) - || ((year % 400) == 0)) - return 29; - else - return 28; - case 4: - case 6: - case 9: - case 11: return 30; - default: return 31; - } + return lastDayOfGregorianMonth(month, year); } - (int) absoluteGregorianDay: (int)day month: (int)month year: (int)year { - int m, N; - - N = day; // day of month - for (m = month - 1; m > 0; m--) // days in prior months this year - N = N + [self lastDayOfGregorianMonth: m year: year]; - return - (N // days this year - + 365 * (year - 1) // days in previous years ignoring leap days - + (year - 1)/4 // Julian leap days before this year... - - (year - 1)/100 // ...minus prior century years... - + (year - 1)/400); // ...plus prior years divisible by 400 + return absoluteGregorianDay(day, month, year); } - (void) gregorianDateFromAbsolute: (int)d @@ -1277,15 +1302,14 @@ { // Search forward year by year from approximate year *year = d/366; - while (d >= [self absoluteGregorianDay: 1 month: 1 year: (*year)+1]) + while (d >= absoluteGregorianDay(1, 1, (*year)+1)) (*year)++; // Search forward month by month from January (*month) = 1; - while (d > [self absoluteGregorianDay: - [self lastDayOfGregorianMonth: *month year: *year] - month: *month year: *year]) + while (d > absoluteGregorianDay(lastDayOfGregorianMonth(*month, *year), + *month, *year)) (*month)++; - *day = d - [self absoluteGregorianDay: 1 month: *month year: *year] + 1; + *day = d - absoluteGregorianDay(1, *month, *year) + 1; } @end @@ -1489,7 +1513,7 @@ tmpmonth += 12; tmpyear--; } - extra += [end lastDayOfGregorianMonth: tmpmonth year: tmpyear]; + extra += lastDayOfGregorianMonth(tmpmonth, tmpyear); } } diff --git a/Source/NSData.m b/Source/NSData.m index f73a7ab8a..f45bf39a7 100644 --- a/Source/NSData.m +++ b/Source/NSData.m @@ -119,9 +119,11 @@ readContentsOfFile(NSString* path, void** buf, unsigned* len, NSZone* zone) unsigned fileLength; void *tmp = 0; int c; - #if defined(__MINGW__) - return NO; + HANDLE fh; + DWORD fileLength + DWORD high; + DWORD got; #endif if ([path getFileSystemRepresentation: thePath @@ -130,6 +132,65 @@ readContentsOfFile(NSString* path, void** buf, unsigned* len, NSZone* zone) NSDebugLog(@"Open (%s) attempt failed - bad path", thePath); return NO; } + +#if defined(__MINGW__) + fh = CreateFile(thePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, 0); + if (fh == INVALID_HANDLE_VALUE) + { + NSDebugLog(@"Open (%s) attempt failed", thePath); + return NO; + } + + fileLength = GetFileSize(fh, &high); + if ((fileLength == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) + { + CloseHandle(fh); + NSLog(@"Failed to determine size of - %s", thePath); + return NO; + } + if (high != 0) + { + CloseHandle(fh); + NSLog(@"File too big to handle - %s", thePath); + return NO; + } + +#if GS_WITH_GC == 1 + tmp = NSZoneMalloc(GSAtomicMallocZone(), fileLength); +#else + tmp = NSZoneMalloc(zone, fileLength); +#endif + if (tmp == 0) + { + CloseHandle(fh); + NSLog(@"Malloc failed for file (%s) of length %d - %s", + thePath, fileLength, strerror(errno)); + return NO; + } + if (!ReadFile(fh, tmp, fileSize, &got, 0)) + { + if (tmp != 0) + { + NSZoneFree(zone, tmp); + CloseHandle(fh); + NSLog(@"File read operation failed for %s", thePath); + return NO; + } + } + if (got != fileSize) + { + NSZoneFree(zone, tmp); + CloseHandle(fh); + NSLog(@"File read operation short for %s", thePath); + return NO; + } + CloseHandle(fh); + *buf = tmp; + *len = fileLength; + return YES; +#endif + theFile = fopen(thePath, "rb"); if (theFile == NULL) /* We failed to open the file. */ @@ -198,9 +259,9 @@ readContentsOfFile(NSString* path, void** buf, unsigned* len, NSZone* zone) * Just in case the failure action needs to be changed. */ failure: - if (tmp) + if (tmp != 0) NSZoneFree(zone, tmp); - if (theFile) + if (theFile != 0) fclose(theFile); return NO; } @@ -535,10 +596,6 @@ failure: FILE *theFile; int c; -#if defined(__MINGW__) - return NO; -#endif - if ([path getFileSystemRepresentation: theRealPath maxLength: sizeof(theRealPath)-1] == NO) { @@ -546,6 +603,38 @@ failure: return NO; } +#if defined(__MINGW__) + HANDLE fh; + DWORD wroteBytes; + + if (useAuxiliaryFile) + { + path = [path stringByAppendingPathExtension: @"tmp"]; + } + if ([path getFileSystemRepresentation: thePath + maxLength: sizeof(thePath)-1] == NO) + { + NSDebugLog(@"Open (%s) attempt failed - bad path", thePath); + return NO; + } + + fh = CreateFile(thePath, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + if (fh == INVALID_HANDLE_VALUE) + { + NSLog(@"Create (%s) attempt failed", thePath); + return NO; + } + + if (!WriteFile(fh, [self bytes], [self length], &wroteBytes, 0)) + { + CloseHandle(fh); + NSLog(@"Write (%s) attempt failed", thePath); + goto failure; + } + CloseHandle(fh); +#else + #ifdef HAVE_MKSTEMP if (useAuxiliaryFile) { @@ -620,6 +709,7 @@ failure: NSLog(@"Fclose (%s) failed - %s", thePath, strerror(errno)); goto failure; } +#endif /* If we used a temporary file, we still need to rename() it be the * real file. Also, we need to try to retain the file attributes of @@ -673,7 +763,7 @@ failure: return YES; /* Just in case the failure action needs to be changed. */ - failure: +failure: /* * Attempt to tidy up by removing temporary file on failure. */ diff --git a/Source/NSDate.m b/Source/NSDate.m index 409888d86..943165bb5 100644 --- a/Source/NSDate.m +++ b/Source/NSDate.m @@ -119,8 +119,9 @@ GSTimeNow() return interval; #else SYSTEMTIME sys_time; - NSCalendarDate *d; NSTimeInterval t; +#if 0 + NSCalendarDate *d; // Get the system time GetLocalTime(&sys_time); @@ -136,6 +137,14 @@ GSTimeNow() timeZone: [NSTimeZone localTimeZone]]; t = otherTime(d); RELEASE(d); +#else + /* + * Get current GMT time, convert to NSTimeInterval since reference date, + */ + GetSystemTime(&sys_time); + t = GSTime(sys_time.eDay, sys_time.wMonth, sys_time.wYear, + sys_time.wHour, sys_time.wMinute, sys_time.wSecond); +#endif return t + sys_time.wMilliseconds / 1000.0; #endif /* __MINGW__ */ } diff --git a/Source/NSFileManager.m b/Source/NSFileManager.m index 76c4c51d8..c53b0c7a0 100644 --- a/Source/NSFileManager.m +++ b/Source/NSFileManager.m @@ -515,7 +515,13 @@ static NSFileManager* defaultManager = nil; contents = [self directoryContentsAtPath: path]; if (contents == nil) { - if (unlink([path fileSystemRepresentation]) < 0) + const char *cpath = [path fileSystemRepresentation]; + +#if defined(__MINGW__) + if (DeleteFile(cpath) == FALSE) +#else + if (unlink(cpath) < 0) +#endif { BOOL result; @@ -587,14 +593,43 @@ static NSFileManager* defaultManager = nil; contents: (NSData*)contents attributes: (NSDictionary*)attributes { - int fd, len, written; + int len; + int written; + const char *cpath = [self fileSystemRepresentationWithPath: path]; - fd = open ([self fileSystemRepresentationWithPath: path], - O_WRONLY|O_TRUNC|O_CREAT, 0644); +#if defined(__MINGW__) + HANDLE fh; + + fh = CreateFile(cpath, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, 0); + if (fh == INVALID_HANDLE_VALUE) + { + return NO; + } + else + { + DWORD len = [contents length]; + DWORD written = 0; + + if (len > 0) + { + WriteFile(fh, [contents bytes], len, &written, NULL); + } + CloseHandle(fh); + if ([self changeFileAttributes: attributes atPath: path] == NO) + { + return NO; + } + } +#else + int fd; + + fd = open (cpath, O_WRONLY|O_TRUNC|O_CREAT, 0644); if (fd < 0) - return NO; - - if (![self changeFileAttributes: attributes atPath: path]) + { + return NO; + } + if ([self changeFileAttributes: attributes atPath: path] == NO) { close (fd); return NO; @@ -618,12 +653,16 @@ static NSFileManager* defaultManager = nil; } len = [contents length]; - if (len) - written = write (fd, [contents bytes], len); + if (len > 0) + { + written = write(fd, [contents bytes], len); + } else - written = 0; + { + written = 0; + } close (fd); - +#endif return written == len; }