@@ -106,10 +106,12 @@ } #else static int parseMode(const char *mode, bool *append) { + *append = false; + if (strcmp(mode, "r") == 0) return MODE_OLDFILE; if (strcmp(mode, "w") == 0) return MODE_NEWFILE; if (strcmp(mode, "wx") == 0) @@ -175,148 +177,136 @@ { return [[[self alloc] initWithPath: path mode: mode] autorelease]; } -#if !defined(OF_MORPHOS) || defined(OF_IXEMUL) -+ (instancetype)fileWithFileDescriptor: (int)fd -{ - return [[[self alloc] initWithFileDescriptor: fd] autorelease]; -} -#else -+ (instancetype)fileWithHandle: (BPTR)handle ++ (instancetype)fileWithHandle: (of_file_handle_t)handle { return [[[self alloc] initWithHandle: handle] autorelease]; } -#endif - init { OF_INVALID_INIT_METHOD } - initWithPath: (OFString *)path mode: (OFString *)mode { - self = [super init]; + of_file_handle_t handle; @try { + void *pool = objc_autoreleasePoolPush(); int flags; #if !defined(OF_MORPHOS) || defined(OF_IXEMUL) if ((flags = parseMode([mode UTF8String])) == -1) @throw [OFInvalidArgumentException exception]; flags |= O_CLOEXEC; # if defined(OF_WINDOWS) - if ((_fd = _wopen([path UTF16String], flags, + if ((handle = _wopen([path UTF16String], flags, _S_IREAD | _S_IWRITE)) == -1) # elif defined(OF_HAVE_OFF64_T) - if ((_fd = open64([path cStringWithEncoding: + if ((handle = open64([path cStringWithEncoding: [OFLocalization encoding]], flags, 0666)) == -1) # else - if ((_fd = open([path cStringWithEncoding: + if ((handle = open([path cStringWithEncoding: [OFLocalization encoding]], flags, 0666)) == -1) # endif @throw [OFOpenItemFailedException exceptionWithPath: path mode: mode errNo: errno]; #else - if ((flags = parseMode([mode UTF8String], &_append)) == -1) + if ((flags = parseMode([mode UTF8String], + &handle.append)) == -1) @throw [OFInvalidArgumentException exception]; - if ((_handle = Open([path cStringWithEncoding: + if ((handle.handle = Open([path cStringWithEncoding: [OFLocalization encoding]], flags)) == 0) @throw [OFOpenItemFailedException exceptionWithPath: path mode: mode]; - if (_append) { - if (Seek64(_handle, 0, OFFSET_END) == -1) + if (handle.append) { + if (Seek64(handle.handle, 0, OFFSET_END) == -1) { + Close(handle.handle); @throw [OFOpenItemFailedException exceptionWithPath: path mode: mode]; + } } #endif + + objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } + + @try { + self = [self initWithHandle: handle]; + } @catch (id e) { +#if !defined(OF_MORPHOS) || defined(OF_IXEMUL) + close(handle); +#else + Close(handle.handle); +#endif + @throw e; + } return self; } -#if !defined(OF_MORPHOS) || defined(OF_IXEMUL) -- initWithFileDescriptor: (int)fd -{ - self = [super init]; - - _fd = fd; - - return self; -} -#else -- initWithHandle: (BPTR)handle +- initWithHandle: (of_file_handle_t)handle { self = [super init]; _handle = handle; return self; } -#endif - (bool)lowlevelIsAtEndOfStream { -#if !defined(OF_MORPHOS) || defined(OF_IXEMUL) - if (_fd == -1) + if (!OF_FILE_HANDLE_IS_VALID(_handle)) return true; -#else - if (_handle == 0) - return true; -#endif return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { ssize_t ret; -#if !defined(OF_MORPHOS) || defined(OF_IXEMUL) - if (_fd == -1 || _atEndOfStream) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length]; - -# ifndef OF_WINDOWS - if ((ret = read(_fd, buffer, length)) < 0) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length - errNo: errno]; -# else - if (length > UINT_MAX) - @throw [OFOutOfRangeException exception]; - - if ((ret = read(_fd, buffer, (unsigned int)length)) < 0) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length - errNo: errno]; -# endif -#else - if (_handle == 0 || _atEndOfStream) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length]; - - if (length > LONG_MAX) - @throw [OFOutOfRangeException exception]; - - if ((ret = Read(_handle, buffer, length)) < 0) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length]; + if (!OF_FILE_HANDLE_IS_VALID(_handle) || _atEndOfStream) + @throw [OFReadFailedException exceptionWithObject: self + requestedLength: length]; + +#if defined(OF_WINDOWS) + if (length > UINT_MAX) + @throw [OFOutOfRangeException exception]; + + if ((ret = read(_handle, buffer, (unsigned int)length)) < 0) + @throw [OFReadFailedException exceptionWithObject: self + requestedLength: length + errNo: errno]; +#elif defined(OF_MORPHOS) && !defined(OF_IXEMUL) + if (length > LONG_MAX) + @throw [OFOutOfRangeException exception]; + + if ((ret = Read(_handle.handle, buffer, length)) < 0) + @throw [OFReadFailedException exceptionWithObject: self + requestedLength: length]; +#else + if ((ret = read(_handle, buffer, length)) < 0) + @throw [OFReadFailedException exceptionWithObject: self + requestedLength: length + errNo: errno]; #endif if (ret == 0) _atEndOfStream = true; @@ -324,90 +314,81 @@ } - (void)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { -#if !defined(OF_MORPHOS) || defined(OF_IXEMUL) - if (_fd == -1 || _atEndOfStream) - @throw [OFWriteFailedException exceptionWithObject: self - requestedLength: length]; -# ifndef OF_WINDOWS - if (length > SSIZE_MAX) - @throw [OFOutOfRangeException exception]; - - if (write(_fd, buffer, length) != (ssize_t)length) - @throw [OFWriteFailedException exceptionWithObject: self - requestedLength: length - errNo: errno]; -# else - if (length > INT_MAX) - @throw [OFOutOfRangeException exception]; - - if (write(_fd, buffer, (int)length) != (int)length) - @throw [OFWriteFailedException exceptionWithObject: self - requestedLength: length - errNo: errno]; -# endif -#else - if (_handle == 0 || _atEndOfStream) - @throw [OFWriteFailedException exceptionWithObject: self - requestedLength: length]; - if (length > LONG_MAX) - @throw [OFOutOfRangeException exception]; - - if (_append) { - if (Seek64(_handle, 0, OFFSET_END) == -1) + if (!OF_FILE_HANDLE_IS_VALID(_handle) || _atEndOfStream) + @throw [OFWriteFailedException exceptionWithObject: self + requestedLength: length]; + +#if defined(OF_WINDOWS) + if (length > INT_MAX) + @throw [OFOutOfRangeException exception]; + + if (write(_handle, buffer, (int)length) != (int)length) + @throw [OFWriteFailedException exceptionWithObject: self + requestedLength: length + errNo: errno]; +#elif defined(OF_MORPHOS) && !defined(OF_IXEMUL) + if (length > LONG_MAX) + @throw [OFOutOfRangeException exception]; + + if (_handle.append) { + if (Seek64(_handle.handle, 0, OFFSET_END) == -1) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length]; } - if (Write(_handle, (void *)buffer, length) != (LONG)length) + if (Write(_handle.handle, (void *)buffer, length) != (LONG)length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length]; +#else + if (length > SSIZE_MAX) + @throw [OFOutOfRangeException exception]; + + if (write(_handle, buffer, length) != (ssize_t)length) + @throw [OFWriteFailedException exceptionWithObject: self + requestedLength: length + errNo: errno]; #endif } - (of_offset_t)lowlevelSeekToOffset: (of_offset_t)offset whence: (int)whence { of_offset_t ret; -#if !defined(OF_MORPHOS) || defined(OF_IXEMUL) - if (_fd == -1) + if (!OF_FILE_HANDLE_IS_VALID(_handle)) @throw [OFSeekFailedException exceptionWithStream: self offset: offset whence: whence]; +#if !defined(OF_MORPHOS) || defined(OF_IXEMUL) # if defined(OF_WINDOWS) - ret = _lseeki64(_fd, offset, whence); + ret = _lseeki64(_handle, offset, whence); # elif defined(OF_HAVE_OFF64_T) - ret = lseek64(_fd, offset, whence); + ret = lseek64(_handle, offset, whence); # else - ret = lseek(_fd, offset, whence); + ret = lseek(_handle, offset, whence); # endif if (ret == -1) @throw [OFSeekFailedException exceptionWithStream: self offset: offset whence: whence errNo: errno]; #else - if (_handle == 0) - @throw [OFSeekFailedException exceptionWithStream: self - offset: offset - whence: whence]; - switch (whence) { case SEEK_SET: - ret = Seek64(_handle, offset, OFFSET_BEGINNING); + ret = Seek64(_handle.handle, offset, OFFSET_BEGINNING); break; case SEEK_CUR: - ret = Seek64(_handle, offset, OFFSET_CURRENT); + ret = Seek64(_handle.handle, offset, OFFSET_CURRENT); break; case SEEK_END: - ret = Seek64(_handle, offset, OFFSET_END); + ret = Seek64(_handle.handle, offset, OFFSET_END); break; default: ret = -1; break; } @@ -421,35 +402,32 @@ _atEndOfStream = false; return ret; } -#if !defined(OF_WINDOWS) && (!defined(OF_MORPHOS) || defined(OF_IXEMUL)) +#ifdef OF_FILE_HANDLE_IS_FD - (int)fileDescriptorForReading { - return _fd; + return _handle; } - (int)fileDescriptorForWriting { - return _fd; + return _handle; } #endif - (void)close { + if (OF_FILE_HANDLE_IS_VALID(_handle)) #if !defined(OF_MORPHOS) || defined(OF_IXEMUL) - if (_fd != -1) - close(_fd); - - _fd = -1; + close(_handle); #else - if (_handle != 0) - Close(_handle); + Close(_handle.handle); +#endif - _handle = 0; -#endif + _handle = OF_INVALID_FILE_HANDLE; [super close]; } - (void)dealloc