diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2020-10-19 14:35:20 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-19 14:35:20 -0400 |
| commit | 9b25d4aa0b6219ce4e4429f9749c7c493531a3cd (patch) | |
| tree | c12b90f47d6edda5eb202b68074485bb7fff9808 /source/core | |
| parent | acf94e79250c258e1969be7ece9cb7ccdecbe099 (diff) | |
Fix saving Repro files on Linux (#1581)
* #include an absolute path didn't work - because paths were taken to always be relative.
* Ascii mode not always set on FileStream.
Remove this-> if not needed.
Simplify setting of m_fileAccess.
* Fix typo.
* Fix typo.
* Clear up default FileAccess calculation.
* Convert tabs to spaces.
* Small naming improvements in FileStream::seek.
Diffstat (limited to 'source/core')
| -rw-r--r-- | source/core/slang-stream.cpp | 337 | ||||
| -rw-r--r-- | source/core/slang-stream.h | 2 |
2 files changed, 178 insertions, 161 deletions
diff --git a/source/core/slang-stream.cpp b/source/core/slang-stream.cpp index bfbe43b0c..c4ba27927 100644 --- a/source/core/slang-stream.cpp +++ b/source/core/slang-stream.cpp @@ -11,223 +11,240 @@ namespace Slang FileStream::FileStream(const String& fileName, FileMode fileMode) { - _init(fileName, fileMode, fileMode==FileMode::Open?FileAccess::Read:FileAccess::Write, FileShare::None); + const FileAccess access = (fileMode == FileMode::Open) ? FileAccess::Read : FileAccess::Write; + _init(fileName, fileMode, access, FileShare::None); } FileStream::FileStream(const String& fileName, FileMode fileMode, FileAccess access, FileShare share) { - _init(fileName, fileMode, access, share); + _init(fileName, fileMode, access, share); } void FileStream::_init(const String& fileName, FileMode fileMode, FileAccess access, FileShare share) { - const wchar_t * mode = L"rt"; - const char* modeMBCS = "rt"; - switch (fileMode) - { - case FileMode::Create: - if (access == FileAccess::Read) - throw ArgumentException("Read-only access is incompatible with Create mode."); - else if (access == FileAccess::ReadWrite) - { - mode = L"w+b"; - modeMBCS = "w+b"; - this->m_fileAccess = FileAccess::ReadWrite; - } - else - { - mode = L"wb"; - modeMBCS = "wb"; - this->m_fileAccess = FileAccess::Write; - } - break; - case FileMode::Open: - if (access == FileAccess::Read) - { - mode = L"rb"; - modeMBCS = "rb"; - this->m_fileAccess = FileAccess::Read; - } - else if (access == FileAccess::ReadWrite) - { - mode = L"r+b"; - modeMBCS = "r+b"; - this->m_fileAccess = FileAccess::ReadWrite; - } - else - { - mode = L"wb"; - modeMBCS = "wb"; - this->m_fileAccess = FileAccess::Write; - } - break; - case FileMode::CreateNew: - if (File::exists(fileName)) - { - throw IOException("Failed opening '" + fileName + "', file already exists."); - } - if (access == FileAccess::Read) - throw ArgumentException("Read-only access is incompatible with Create mode."); - else if (access == FileAccess::ReadWrite) - { - mode = L"w+b"; - this->m_fileAccess = FileAccess::ReadWrite; - } - else - { - mode = L"wb"; - this->m_fileAccess = FileAccess::Write; - } - break; - case FileMode::Append: - if (access == FileAccess::Read) - throw ArgumentException("Read-only access is incompatible with Append mode."); - else if (access == FileAccess::ReadWrite) - { - mode = L"a+b"; - this->m_fileAccess = FileAccess::ReadWrite; - } - else - { - mode = L"ab"; - this->m_fileAccess = FileAccess::Write; - } - break; - default: - break; - } + if (access == FileAccess::None) + { + throw ArgumentException("FileAccess::None not valid to create a FileStream."); + } + + // Default to no access, until stream is fully constructed + m_fileAccess = FileAccess::None; + + const char* mode = "rt"; + switch (fileMode) + { + case FileMode::Create: + if (access == FileAccess::Read) + throw ArgumentException("Read-only access is incompatible with Create mode."); + else if (access == FileAccess::ReadWrite) + { + mode = "w+b"; + } + else + { + mode = "wb"; + } + break; + case FileMode::Open: + if (access == FileAccess::Read) + { + mode = "rb"; + } + else if (access == FileAccess::ReadWrite) + { + mode = "r+b"; + } + else + { + mode = "wb"; + } + break; + case FileMode::CreateNew: + if (File::exists(fileName)) + { + throw IOException("Failed opening '" + fileName + "', file already exists."); + } + if (access == FileAccess::Read) + throw ArgumentException("Read-only access is incompatible with Create mode."); + else if (access == FileAccess::ReadWrite) + { + mode = "w+b"; + } + else + { + mode = "wb"; + } + break; + case FileMode::Append: + if (access == FileAccess::Read) + throw ArgumentException("Read-only access is incompatible with Append mode."); + else if (access == FileAccess::ReadWrite) + { + mode = "a+b"; + } + else + { + mode = "ab"; + } + break; + default: + break; + } #ifdef _WIN32 + + // NOTE! This works because we know all the characters in the mode + // are encoded directly as the same value in a wchar_t. + // + // Work out the length *including* terminating 0 + const Index modeLength = Index(::strlen(mode)) + 1; + wchar_t wideMode[8]; + SLANG_ASSERT(modeLength <= SLANG_COUNT_OF(wideMode)); + + // Copy to wchar_t + for (Index i = 0; i < modeLength ; ++i) + { + wideMode[i] = wchar_t(mode[i]); + } + int shFlag = _SH_DENYRW; switch (share) - { - case FileShare::None: - shFlag = _SH_DENYRW; - break; - case FileShare::ReadOnly: - shFlag = _SH_DENYWR; - break; - case FileShare::WriteOnly: - shFlag = _SH_DENYRD; - break; - case FileShare::ReadWrite: - shFlag = _SH_DENYNO; - break; - default: - throw ArgumentException("Invalid file share mode."); - break; - } + { + case FileShare::None: + shFlag = _SH_DENYRW; + break; + case FileShare::ReadOnly: + shFlag = _SH_DENYWR; + break; + case FileShare::WriteOnly: + shFlag = _SH_DENYRD; + break; + case FileShare::ReadWrite: + shFlag = _SH_DENYNO; + break; + default: + throw ArgumentException("Invalid file share mode."); + break; + } if (share == FileShare::None) #pragma warning(suppress:4996) - m_handle = _wfopen(fileName.toWString(), mode); + m_handle = _wfopen(fileName.toWString(), wideMode); else - m_handle = _wfsopen(fileName.toWString(), mode, shFlag); + m_handle = _wfsopen(fileName.toWString(), wideMode, shFlag); #else - m_handle = fopen(fileName.getBuffer(), modeMBCS); + m_handle = fopen(fileName.getBuffer(), mode); #endif - if (!m_handle) - { - throw IOException("Cannot open file '" + fileName + "'"); - } + if (!m_handle) + { + throw IOException("Cannot open file '" + fileName + "'"); + } + + // Just set the access specified + m_fileAccess = access; } FileStream::~FileStream() { - close(); + close(); } Int64 FileStream::getPosition() { #if defined(_WIN32) || defined(__CYGWIN__) - fpos_t pos; - fgetpos(m_handle, &pos); - return pos; + fpos_t pos; + fgetpos(m_handle, &pos); + return pos; #elif defined(__APPLE__) - return ftell(m_handle); + return ftell(m_handle); #else - fpos64_t pos; - fgetpos64(m_handle, &pos); - return *(Int64*)(&pos); + fpos64_t pos; + fgetpos64(m_handle, &pos); + return *(Int64*)(&pos); #endif } -void FileStream::seek(SeekOrigin origin, Int64 offset) + +void FileStream::seek(SeekOrigin seekOrigin, Int64 offset) { - int _origin; - switch (origin) - { - case SeekOrigin::Start: - _origin = SEEK_SET; - m_endReached = false; - break; - case SeekOrigin::End: - _origin = SEEK_END; - // JS TODO: This doesn't seem right, the offset can mean it's not at the end - m_endReached = true; - break; - case SeekOrigin::Current: - _origin = SEEK_CUR; - m_endReached = false; - break; - default: - throw NotSupportedException("Unsupported seek origin."); - break; - } + int fseekOrigin; + switch (seekOrigin) + { + case SeekOrigin::Start: + fseekOrigin = SEEK_SET; + break; + case SeekOrigin::End: + fseekOrigin = SEEK_END; + break; + case SeekOrigin::Current: + fseekOrigin = SEEK_CUR; + break; + default: + throw NotSupportedException("Unsupported seek origin."); + break; + } + + // If endReached is intended to be like feof - then doing a seek will reset it + m_endReached = false; + #ifdef _WIN32 - int rs = _fseeki64(m_handle, offset, _origin); + int rs = _fseeki64(m_handle, offset, fseekOrigin); #else - int rs = fseek(m_handle, (int)offset, _origin); + int rs = fseek(m_handle, (long int)offset, fseekOrigin); #endif - if (rs != 0) - { - throw IOException("FileStream seek failed."); - } + + if (rs != 0) + { + throw IOException("FileStream seek failed."); + } } size_t FileStream::read(void* buffer, size_t length) { - auto bytes = fread_s(buffer, length, 1, length, m_handle); - if (bytes == 0 && length > 0) - { - if (!feof(m_handle)) - throw IOException("FileStream read failed."); - else if (m_endReached) - throw EndOfStreamException("End of file is reached."); - m_endReached = true; - } - return bytes; + auto bytes = fread_s(buffer, length, 1, length, m_handle); + if (bytes == 0 && length > 0) + { + if (!feof(m_handle)) + throw IOException("FileStream read failed."); + else if (m_endReached) + throw EndOfStreamException("End of file is reached."); + m_endReached = true; + } + return bytes; } size_t FileStream::write(const void* buffer, size_t length) { - auto bytes = fwrite(buffer, 1, length, m_handle); - if (bytes < length) - { - throw IOException("FileStream write failed."); - } - return bytes; + auto bytes = fwrite(buffer, 1, length, m_handle); + if (bytes < length) + { + throw IOException("FileStream write failed."); + } + return bytes; } bool FileStream::canRead() { - return ((int)m_fileAccess & (int)FileAccess::Read) != 0; + return ((int)m_fileAccess & (int)FileAccess::Read) != 0; } bool FileStream::canWrite() { - return ((int)m_fileAccess & (int)FileAccess::Write) != 0; + return ((int)m_fileAccess & (int)FileAccess::Write) != 0; } void FileStream::close() { - if (m_handle) - { - fclose(m_handle); - m_handle = 0; - } + if (m_handle) + { + fclose(m_handle); + m_handle = 0; + + // If closed, can neither read or write + m_fileAccess = FileAccess::None; + } } bool FileStream::isEnd() { - return m_endReached; + return m_endReached; } // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MemoryStreamBase !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/source/core/slang-stream.h b/source/core/slang-stream.h index 212437ab5..c4064871b 100644 --- a/source/core/slang-stream.h +++ b/source/core/slang-stream.h @@ -165,7 +165,7 @@ private: void _init(const String& fileName, FileMode fileMode, FileAccess access, FileShare share); FILE* m_handle; - FileAccess m_fileAccess; + FileAccess m_fileAccess; bool m_endReached = false; }; |
