4 Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
7 Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
8 Mircea Oancea <mircea@jupiter.elcom.pub.ro>
9 Florin Mihaila <phil@pathcom.com>
10 Bogdan Baliuc <stark@protv.ro>
12 This file is part of libFoundation.
14 Permission to use, copy, modify, and distribute this software and its
15 documentation for any purpose and without fee is hereby granted, provided
16 that the above copyright notice appear in all copies and that both that
17 copyright notice and this permission notice appear in supporting
20 We disclaim all warranties with regard to this software, including all
21 implied warranties of merchantability and fitness, in no event shall
22 we be liable for any special, indirect or consequential damages or any
23 damages whatsoever resulting from loss of use, data or profits, whether in
24 an action of contract, negligence or other tortious action, arising out of
25 or in connection with the use or performance of this software.
28 #include <Foundation/common.h>
29 #include <Foundation/NSString.h>
30 #include <Foundation/NSData.h>
31 #include <Foundation/NSPosixFileDescriptor.h>
32 #include <Foundation/NSFileManager.h>
33 #include <Foundation/NSException.h>
34 #include <Foundation/NSThread.h>
35 #include <Foundation/NSAutoreleasePool.h>
36 #include <Foundation/NSPathUtilities.h>
38 #include "PrivateThreadData.h"
39 #include "NSCalendarDateScanf.h"
41 #include <Foundation/exceptions/GeneralExceptions.h>
42 #include <extensions/PrintfFormatScanner.h>
43 #include <extensions/PrintfScannerHandler.h>
53 # warning defined O_BINARY
62 #if defined(__MINGW32__)
64 NSString *NSWindowsWideStringToString(LPWSTR _wstr)
66 unsigned char cstr[256];
69 result = WideCharToMultiByte(CP_ACP,
71 _wstr, /* the wide string */
72 -1, /* determine length of _wstr */
73 cstr, /* destination */
74 sizeof(cstr), /* buffer size */
75 NULL, /* insert char if char could not be conv */
76 NULL /* pointer to flag: couldNotBeConverted */);
77 return [NSString stringWithCString:cstr];
80 LPWSTR NSStringToWindowsWideString(NSString *_str)
86 int cstrlen = [_str cStringLength];
88 cstr = malloc(cstrlen + 1);
89 [_str getCString:cstr]; cstr[cstrlen] = '\0';
91 // first determine required buffer size
92 wstrlen = MultiByteToWideChar(CP_ACP, /* ANSI Code Conversion */
93 0, /* conversion flags */
94 cstr, /* ANSI string */
95 cstrlen + 1, /* ANSI string length + zero byte */
96 wstr, /* destination */
97 0); /* Shall determine required size */
100 wstr = NSZoneMalloc(NULL, sizeof(WCHAR) * (wstrlen + 1));
102 result = MultiByteToWideChar(CP_ACP, /* ANSI Code Conversion */
103 0, /* conversion flags */
104 cstr, /* ANSI string */
105 cstrlen + 1, /* ANSI string length + zero byte */
106 wstr, /* destination */
107 wstrlen); /* destination buffer size */
109 #if !LIB_FOUNDATION_BOEHM_GC
110 [NSAutoreleasedPointer autoreleasePointer:wstr];
119 void *NSReadContentsOfFile(NSString *_path, unsigned _extraCapacity,
122 unsigned char *bytes = NULL;
123 #if defined(__MINGW32__)
125 DWORD sizeLow, sizeHigh;
130 fh = CreateFile([_path fileSystemRepresentation],
131 GENERIC_READ, /* assume read access */
132 FILE_SHARE_READ, /* multiple read lock */
133 NULL, /* security attributes */
134 OPEN_EXISTING, /* fail if file does not exist */
135 FILE_ATTRIBUTE_NORMAL, /* access normal file */
136 NULL); /* template file (not used) */
137 if (fh == INVALID_HANDLE_VALUE)
138 // could not open file
141 sizeLow = GetFileSize(fh, &sizeHigh);
142 if ((sizeLow == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) {
143 // could not stat file
147 NSCAssert(sizeHigh == 0, @"cannot handle 64bit filesizes yet");
149 bytes = NSZoneMallocAtomic(NULL, sizeLow + _extraCapacity);
150 if (!ReadFile(fh, bytes, sizeLow, &got, NULL)) {
158 if (len) *len = bytes ? sizeLow : 0;
161 struct stat fstat_buf;
167 plen = [_path cStringLength];
168 path = malloc(plen + 1);
169 [_path getCString:path]; path[plen] = '\0';
171 if ((fd = open(path, O_RDONLY|O_BINARY, 0)) == -1) {
172 //fprintf(stderr, "couldn't open file '%s'\n", path ? path : "<NULL>");
173 if (path) free(path);
177 if (path) free(path);
179 if (fstat(fd, &fstat_buf) == -1) {
180 // NSLog(@"couldn't stat fd %i file '%@'", fd, _path ? _path : nil);
185 bytes = NSZoneMallocAtomic(NULL, fstat_buf.st_size + _extraCapacity);
187 if ((got = read(fd, bytes, fstat_buf.st_size)) != fstat_buf.st_size) {
196 if (len) *len = bytes ? fstat_buf.st_size : 0;
201 /* Non OpenStep useful things */
203 void vaRelease(id obj, ...)
212 next_obj = va_arg(args, id);
217 BOOL writeToFile(NSString *path, NSData *data, BOOL atomically)
219 const void *bytes = [data bytes];
220 int len = [data length];
221 volatile BOOL result = YES;
222 NSString *filename = nil;
224 #if defined(__MINGW32__)
228 filename = atomically ? [path stringByAppendingString:@".tmp"] : path;
230 fh = CreateFile([filename fileSystemRepresentation],
231 GENERIC_WRITE, /* assume write access */
232 0, /* exclusive lock */
233 NULL, /* security attributes */
234 CREATE_ALWAYS, /* create a new file */
235 FILE_ATTRIBUTE_NORMAL, /* access normal file */
236 NULL); /* template file (not used) */
237 if (fh == INVALID_HANDLE_VALUE) {
238 fprintf(stderr, "Could not create file for writing %s: %s\n",
239 [filename fileSystemRepresentation], strerror(errno));
243 if (!WriteFile(fh, bytes, len, &wroteBytes, NULL)) {
245 "Failed to write %i bytes to %s, only wrote %li bytes\n",
246 len, [filename fileSystemRepresentation], wroteBytes);
254 filename = atomically ? [path stringByAppendingString:@"~"] : path;
256 fd = open([filename fileSystemRepresentation],
257 O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
259 fprintf(stderr, "Could not open file for writing %s: %s\n",
260 [filename fileSystemRepresentation], strerror(errno));
264 if (write(fd, bytes, len) != len) {
265 fprintf(stderr, "Failed to write %i bytes to %s: %s\n",
266 len, [filename fileSystemRepresentation], strerror(errno));
274 NSFileManager *fileManager = nil;
276 fileManager = [NSFileManager defaultManager];
279 [fileManager removeFileAtPath:path handler:nil];
280 result = [fileManager movePath:filename toPath:path handler:nil];
283 fprintf(stderr, "Could not move file %s to file %s\n",
284 [filename fileSystemRepresentation],
285 [path fileSystemRepresentation]);
293 char *Ltoa(long nr, char *str, int base)
295 char buff[34], rest, is_negative;
321 Strcpy(str, &buff[ptr+1]);
326 unsigned hashjb(const char* name, int len)
328 register unsigned long hash = 0, i = 0;
329 register unsigned char ch;
331 for (; (ch = *name++); i ^= 1) {
337 hash += ((hash & 0xffff0000) >> 16);
338 hash += ((hash & 0x0000ff00) >> 8);
339 return hash & (len - 1);
342 NSString* Asprintf(NSString* format, ...)
347 va_start(ap, format);
348 string = Avsprintf(format, ap);
353 NSString* Avsprintf(NSString* format, va_list args)
356 static id ofmt = nil;
357 id objectFormat, formatScanner, string;
364 objectFormat = [[FSObjectFormat alloc] init];
366 formatScanner = [[PrintfFormatScanner alloc] init];
368 [formatScanner setFormatScannerHandler:objectFormat];
369 string = [formatScanner stringWithFormat:format arguments:args];
371 if (ofmt == nil) ofmt = objectFormat;
372 else RELEASE(objectFormat);
373 RELEASE(formatScanner);
378 /* Moved the THROW here from common.h to avoid recursion in the definition of
379 memoryExhaustedException. */
380 void __raiseMemoryException (void* pointer, int size)
382 [[memoryExhaustedException setPointer:&pointer memorySize:size] raise];