summaryrefslogtreecommitdiffstats
path: root/source/core
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-10-19 14:35:20 -0400
committerGitHub <noreply@github.com>2020-10-19 14:35:20 -0400
commit9b25d4aa0b6219ce4e4429f9749c7c493531a3cd (patch)
treec12b90f47d6edda5eb202b68074485bb7fff9808 /source/core
parentacf94e79250c258e1969be7ece9cb7ccdecbe099 (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.cpp337
-rw-r--r--source/core/slang-stream.h2
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;
};