--- a/FileStream.st Tue Jul 28 12:32:54 2009 +0200
+++ b/FileStream.st Tue Jul 28 13:32:44 2009 +0200
@@ -1011,11 +1011,11 @@
%{
HFILE f;
- HFILE fopen();
+
int pass = 0;
retry:
- if (__isNonNilObject(pathName) && __isString(openmode))
+ if (__isNonNilObject(pathName) && (__isStringLike(openmode) || __isArray(openmode)))
#ifdef __VMS__
if (__qClass(pathName)==String) {
do {
@@ -1140,49 +1140,131 @@
#else /* not VMS */
# ifdef WIN32
-
- if (__qClass(pathName)==String) {
- {
- char _aPathName[MAXPATHLEN];
- char _openMode[64];
+ {
+ DWORD share = 0, access = 0, create = 0, attr = 0;
+ int numAttrib, i;
+ OBJ *ap;
+ char * __openmode;
+ HANDLE handle;
- strncpy(_aPathName, __stringVal(pathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
- strncpy(_openMode, __stringVal(openmode), sizeof(_openMode)-1); _openMode[sizeof(_openMode)-1] = '\0';
- do {
- __threadErrno = 0;
- f = STX_C_CALL2( "fopen", fopen, _aPathName, _openMode);
- if (__threadErrno == EINTR) {
- f = NULL;
- }
- } while ((f == NULL) && (__threadErrno == EINTR));
- }
- } else if (__qClass(pathName)==Unicode16String) {
- {
- wchar_t _aPathName[MAXPATHLEN+1];
- wchar_t _openMode[64];
- int i, l;
+ if (__isStringLike(openmode)) {
+ share = FILE_SHARE_READ|FILE_SHARE_WRITE;
+ __openmode = __stringVal(openmode);
+ if (strcmp(__openmode, "rb") == 0) {
+ access = GENERIC_READ;
+ create = OPEN_EXISTING;
+ } else if (strcmp(__openmode, "rb+") == 0) {
+ access = GENERIC_READ | GENERIC_WRITE;
+ create = OPEN_ALWAYS;
+ } else if (strcmp(__openmode, "wb") == 0) {
+ access = GENERIC_WRITE;
+ create = CREATE_ALWAYS;
+ } else if (strcmp(__openmode, "wb+") == 0) {
+ access = GENERIC_READ | GENERIC_WRITE;
+ create = CREATE_ALWAYS;
+ } else if (strcmp(__openmode, "ab") == 0) {
+ access = FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA|
+ STANDARD_RIGHTS_WRITE|SYNCHRONIZE;
+ create = OPEN_ALWAYS;
+ } else if (strcmp(__openmode, "ab+") == 0) {
+ access = GENERIC_READ |FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA|
+ STANDARD_RIGHTS_WRITE|SYNCHRONIZE;
+ create = OPEN_ALWAYS;
+ } else {
+ console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n");
+ }
+ } else if (__isArrayLike(openmode)) {
+ ap = __ArrayInstPtr(attributeSpec)->a_element;
+ numAttrib = __arraySize(attributeSpec);
+ __openmode = "rb+";
+
+ for (i=0; i<numAttrib; i++) {
+ OBJ attrSym = ap[i];
+
+ if (attrSym == @symbol(FILE_SHARE_READ)) {
+ share |= FILE_SHARE_READ;
+ } else if (attrSym == @symbol(FILE_SHARE_WRITE)) {
+ share |= FILE_SHARE_WRITE;
+
+ } else if (attrSym == @symbol(GENERIC_READ)) {
+ access |= GENERIC_READ;
+ } else if (attrSym == @symbol(GENERIC_WRITE)) {
+ access |= GENERIC_WRITE;
+
+ } else if (attrSym == @symbol(CREATE_NEW)) {
+ create |= CREATE_NEW;
+ } else if (attrSym == @symbol(CREATE_ALWAYS)) {
+ create |= CREATE_ALWAYS;
+ } else if (attrSym == @symbol(OPEN_EXISTING)) {
+ create |= OPEN_EXISTING;
+ } else if (attrSym == @symbol(OPEN_ALWAYS)) {
+ create |= OPEN_ALWAYS;
+ } else if (attrSym == @symbol(TRUNCATE_EXISTING)) {
+ create |= TRUNCATE_EXISTING;
- l = __unicode16StringSize(pathName);
- if (l > MAXPATHLEN) l = MAXPATHLEN;
- for (i=0; i<l; i++) {
- _aPathName[i] = __unicode16StringVal(pathName)[i];
- }
- _aPathName[i] = 0;
+ } else if (attrSym == @symbol(FILE_ATTRIBUTE_HIDDEN)) {
+ attr |= FILE_ATTRIBUTE_HIDDEN;
+ } else if (attrSym == @symbol(FILE_ATTRIBUTE_READONLY)) {
+ attr |= FILE_ATTRIBUTE_READONLY;
+ } else if (attrSym == @symbol(FILE_FLAG_WRITE_THROUGH)) {
+ attr |= FILE_FLAG_WRITE_THROUGH;
+ } else if (attrSym == @symbol(FILE_FLAG_SEQUENTIAL_SCAN)) {
+ attr |= FILE_FLAG_SEQUENTIAL_SCAN;
+ } else if (attrSym == @symbol(FILE_FLAG_DELETE_ON_CLOSE)) {
+ attr |= FILE_FLAG_DELETE_ON_CLOSE;
+ } else {
+ console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n");
+ }
+ }
+ } else {
+ f = NULL;
+// argumentError = @symbol(badAttributeSpec);
+ goto badArgument;
+ }
+ if (create == 0) {
+ f = NULL;
+// argumentError = @symbol(missingCreateMode);
+ goto badArgument;
+ }
+ if (attr == 0) {
+ attr = FILE_ATTRIBUTE_NORMAL;
+ }
+
+ if (__isString(pathName)) {
+ char _aPathName[MAXPATHLEN];
- l = __stringSize(openmode);
- if (l > 64) l = 64;
- for (i=0; i<l; i++) {
- _openMode[i] = ((unsigned char *)__stringVal(openmode))[i];
- }
- _openMode[i] = 0;
- do {
- __threadErrno = 0;
- f = STX_C_CALL2( "_wfopen", _wfopen, _aPathName, _openMode);
- if (__threadErrno == EINTR) {
- f = NULL;
+ strncpy(_aPathName, __stringVal(pathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
+ do {
+ __threadErrno = 0;
+ handle = STX_API_CALL7( "CreateFileA", CreateFileA, _aPathName, access, share, 0 /* sa */, create, attr, 0 /* hTempl */);
+ if (__threadErrno == EINTR) {
+ handle = INVALID_HANDLE_VALUE;
+ }
+ } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR));
+ } else if (__isUnicode16String(pathName)) {
+ wchar_t _aPathName[MAXPATHLEN+1];
+ int i, l;
+
+ l = __unicode16StringSize(pathName);
+ if (l > MAXPATHLEN) l = MAXPATHLEN;
+ for (i=0; i<l; i++) {
+ _aPathName[i] = __unicode16StringVal(pathName)[i];
}
- } while ((f == NULL) && (__threadErrno == EINTR));
- }
+ _aPathName[i] = 0;
+
+ do {
+ __threadErrno = 0;
+ handle = STX_API_CALL7( "CreateFileW", CreateFileW, _aPathName, access, share, 0 /* sa */, create, attr, 0 /* hTempl */);
+ if (__threadErrno == EINTR) {
+ handle = INVALID_HANDLE_VALUE;
+ }
+ } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR));
+ }
+ if (handle != INVALID_HANDLE_VALUE) {
+ f = fdopen(_open_osfhandle((long)handle, O_BINARY), __openmode);
+ } else {
+ f = NULL;
+ }
}
# else /* not WIN32 */
@@ -1218,7 +1300,8 @@
__SSEND0(@global(ObjectMemory), @symbol(finalize), 0);
goto retry;
}
- getOutOfHere: ;
+ badArgument:
+ getOutOfHere:
__INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
__INST(position) = nil;
} else {
@@ -1252,7 +1335,7 @@
# endif
#else /* not VMS */
__INST(canPosition) = true;
-#endif /* poor VMS */
+#endif /* not VMS */
if (@global(FileOpenTrace) == true) {
console_fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f);
@@ -1558,7 +1641,7 @@
!FileStream class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.131 2009-01-14 20:01:21 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.132 2009-07-28 11:32:44 stefan Exp $'
! !
FileStream initialize!