summaryrefslogtreecommitdiffstats
path: root/source/core
diff options
context:
space:
mode:
Diffstat (limited to 'source/core')
-rw-r--r--source/core/slang-io.cpp4
-rw-r--r--source/core/slang-riff.cpp14
-rw-r--r--source/core/slang-stream.cpp478
-rw-r--r--source/core/slang-stream.h255
-rw-r--r--source/core/slang-text-io.cpp14
-rw-r--r--source/core/slang-text-io.h6
6 files changed, 422 insertions, 349 deletions
diff --git a/source/core/slang-io.cpp b/source/core/slang-io.cpp
index caa45c8f4..6cff8e1c9 100644
--- a/source/core/slang-io.cpp
+++ b/source/core/slang-io.cpp
@@ -660,10 +660,10 @@ namespace Slang
{
RefPtr<FileStream> fs = new FileStream(fileName, FileMode::Open, FileAccess::Read, FileShare::ReadWrite);
List<unsigned char> buffer;
- while (!fs->IsEnd())
+ while (!fs->isEnd())
{
unsigned char ch;
- int read = (int)fs->Read(&ch, 1);
+ int read = (int)fs->read(&ch, 1);
if (read)
buffer.add(ch);
else
diff --git a/source/core/slang-riff.cpp b/source/core/slang-riff.cpp
index df2076013..ce8b7129b 100644
--- a/source/core/slang-riff.cpp
+++ b/source/core/slang-riff.cpp
@@ -20,7 +20,7 @@ namespace Slang
}
// Skip the payload (we don't need to skip the Chunk because that was already read
- stream->Seek(SeekOrigin::Current, chunkSize - sizeof(RiffChunk));
+ stream->seek(SeekOrigin::Current, chunkSize - sizeof(RiffChunk));
return SLANG_OK;
}
@@ -29,7 +29,7 @@ namespace Slang
{
try
{
- stream->Read(&outChunk, sizeof(RiffChunk));
+ stream->read(&outChunk, sizeof(RiffChunk));
}
catch (IOException&)
{
@@ -53,13 +53,13 @@ namespace Slang
try
{
- out->Write(&chunk, sizeof(chunk));
- out->Write(data, size);
+ out->write(&chunk, sizeof(chunk));
+ out->write(data, size);
size_t remaining = size & 3;
if (remaining)
{
uint8_t end[4] = { 0, 0, 0, 0};
- out->Write(end, 4 - remaining);
+ out->write(end, 4 - remaining);
}
}
catch (IOException&)
@@ -79,13 +79,13 @@ namespace Slang
try
{
- stream->Read(data.getBuffer(), outChunk.m_size);
+ stream->read(data.getBuffer(), outChunk.m_size);
// Skip to the alignment
uint32_t remaining = outChunk.m_size & 3;
if (remaining)
{
- stream->Seek(SeekOrigin::Current, 4 - remaining);
+ stream->seek(SeekOrigin::Current, 4 - remaining);
}
}
catch (IOException&)
diff --git a/source/core/slang-stream.cpp b/source/core/slang-stream.cpp
index ee194c451..b5eef1d9b 100644
--- a/source/core/slang-stream.cpp
+++ b/source/core/slang-stream.cpp
@@ -6,289 +6,301 @@
namespace Slang
{
- FileStream::FileStream(const Slang::String & fileName, FileMode fileMode)
- {
- Init(fileName, fileMode, fileMode==FileMode::Open?FileAccess::Read:FileAccess::Write, FileShare::None);
- }
- FileStream::FileStream(const Slang::String & fileName, FileMode fileMode, FileAccess access, FileShare share)
- {
- Init(fileName, fileMode, access, share);
- }
- void FileStream::Init(const Slang::String & fileName, FileMode fileMode, FileAccess access, FileShare share)
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FileStream !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+FileStream::FileStream(const String& fileName, FileMode fileMode)
+{
+ _init(fileName, fileMode, fileMode==FileMode::Open?FileAccess::Read:FileAccess::Write, FileShare::None);
+}
+
+FileStream::FileStream(const String& fileName, FileMode fileMode, FileAccess access, FileShare 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)
{
- 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)
{
- case Slang::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->fileAccess = FileAccess::ReadWrite;
- }
- else
- {
- mode = L"wb";
- modeMBCS = "wb";
- this->fileAccess = FileAccess::Write;
- }
- break;
- case Slang::FileMode::Open:
- if (access == FileAccess::Read)
- {
- mode = L"rb";
- modeMBCS = "rb";
- this->fileAccess = FileAccess::Read;
- }
- else if (access == FileAccess::ReadWrite)
- {
- mode = L"r+b";
- modeMBCS = "r+b";
- this->fileAccess = FileAccess::ReadWrite;
- }
- else
- {
- mode = L"wb";
- modeMBCS = "wb";
- this->fileAccess = FileAccess::Write;
- }
- break;
- case Slang::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->fileAccess = FileAccess::ReadWrite;
- }
- else
- {
- mode = L"wb";
- this->fileAccess = FileAccess::Write;
- }
- break;
- case Slang::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->fileAccess = FileAccess::ReadWrite;
- }
- else
- {
- mode = L"ab";
- this->fileAccess = FileAccess::Write;
- }
- break;
- default:
- break;
+ mode = L"w+b";
+ modeMBCS = "w+b";
+ this->m_fileAccess = FileAccess::ReadWrite;
}
-#ifdef _WIN32
- int shFlag = _SH_DENYRW;
- switch (share)
+ else
{
- case Slang::FileShare::None:
- shFlag = _SH_DENYRW;
- break;
- case Slang::FileShare::ReadOnly:
- shFlag = _SH_DENYWR;
- break;
- case Slang::FileShare::WriteOnly:
- shFlag = _SH_DENYRD;
- break;
- case Slang::FileShare::ReadWrite:
- shFlag = _SH_DENYNO;
- break;
- default:
- throw ArgumentException("Invalid file share mode.");
- break;
+ mode = L"wb";
+ modeMBCS = "wb";
+ this->m_fileAccess = FileAccess::Write;
}
- if (share == Slang::FileShare::None)
-#pragma warning(suppress:4996)
- handle = _wfopen(fileName.toWString(), mode);
- else
- handle = _wfsopen(fileName.toWString(), mode, shFlag);
-#else
- handle = fopen(fileName.getBuffer(), modeMBCS);
-#endif
- if (!handle)
+ 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
{
- throw IOException("Cannot open file '" + fileName + "'");
+ 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;
}
- FileStream::~FileStream()
+#ifdef _WIN32
+ int shFlag = _SH_DENYRW;
+ switch (share)
{
- Close();
+ 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;
}
- Int64 FileStream::GetPosition()
+ if (share == FileShare::None)
+#pragma warning(suppress:4996)
+ m_handle = _wfopen(fileName.toWString(), mode);
+ else
+ m_handle = _wfsopen(fileName.toWString(), mode, shFlag);
+#else
+ m_handle = fopen(fileName.getBuffer(), modeMBCS);
+#endif
+ if (!m_handle)
{
+ throw IOException("Cannot open file '" + fileName + "'");
+ }
+}
+
+FileStream::~FileStream()
+{
+ close();
+}
+
+Int64 FileStream::getPosition()
+{
#if defined(_WIN32) || defined(__CYGWIN__)
- fpos_t pos;
- fgetpos(handle, &pos);
- return pos;
+ fpos_t pos;
+ fgetpos(m_handle, &pos);
+ return pos;
#elif defined(__APPLE__)
- return ftell(handle);
+ return ftell(m_handle);
#else
- fpos64_t pos;
- fgetpos64(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 origin, Int64 offset)
+{
+ int _origin;
+ switch (origin)
{
- int _origin;
- switch (origin)
- {
- case Slang::SeekOrigin::Start:
- _origin = SEEK_SET;
- endReached = false;
- break;
- case Slang::SeekOrigin::End:
- _origin = SEEK_END;
- // JS TODO: This doesn't seem right, the offset can mean it's not at the end
- endReached = true;
- break;
- case Slang::SeekOrigin::Current:
- _origin = SEEK_CUR;
- endReached = false;
- break;
- default:
- throw NotSupportedException("Unsupported seek origin.");
- break;
- }
+ 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;
+ }
#ifdef _WIN32
- int rs = _fseeki64(handle, offset, _origin);
+ int rs = _fseeki64(m_handle, offset, _origin);
#else
- int rs = fseek(handle, (int)offset, _origin);
+ int rs = fseek(m_handle, (int)offset, _origin);
#endif
- if (rs != 0)
- {
- throw IOException("FileStream seek failed.");
- }
- }
- Int64 FileStream::Read(void * buffer, Int64 length)
- {
- auto bytes = fread_s(buffer, (size_t)length, 1, (size_t)length, handle);
- if (bytes == 0 && length > 0)
- {
- if (!feof(handle))
- throw IOException("FileStream read failed.");
- else if (endReached)
- throw EndOfStreamException("End of file is reached.");
- endReached = true;
- }
- return (int)bytes;
- }
- Int64 FileStream::Write(const void * buffer, Int64 length)
- {
- auto bytes = (Int64)fwrite(buffer, 1, (size_t)length, handle);
- if (bytes < length)
- {
- throw IOException("FileStream write failed.");
- }
- return bytes;
- }
- bool FileStream::CanRead()
+ if (rs != 0)
{
- return ((int)fileAccess & (int)FileAccess::Read) != 0;
+ throw IOException("FileStream seek failed.");
}
- bool FileStream::CanWrite()
+}
+Int64 FileStream::read(void* buffer, Int64 length)
+{
+ auto bytes = fread_s(buffer, (size_t)length, 1, (size_t)length, m_handle);
+ if (bytes == 0 && length > 0)
{
- return ((int)fileAccess & (int)FileAccess::Write) != 0;
+ if (!feof(m_handle))
+ throw IOException("FileStream read failed.");
+ else if (m_endReached)
+ throw EndOfStreamException("End of file is reached.");
+ m_endReached = true;
}
- void FileStream::Close()
+ return (int)bytes;
+}
+Int64 FileStream::write(const void* buffer, Int64 length)
+{
+ auto bytes = (Int64)fwrite(buffer, 1, (size_t)length, m_handle);
+ if (bytes < length)
{
- if (handle)
- {
- fclose(handle);
- handle = 0;
- }
+ throw IOException("FileStream write failed.");
}
- bool FileStream::IsEnd()
+ return bytes;
+}
+bool FileStream::canRead()
+{
+ return ((int)m_fileAccess & (int)FileAccess::Read) != 0;
+}
+bool FileStream::canWrite()
+{
+ return ((int)m_fileAccess & (int)FileAccess::Write) != 0;
+}
+void FileStream::close()
+{
+ if (m_handle)
{
- return endReached;
+ fclose(m_handle);
+ m_handle = 0;
}
+}
+bool FileStream::isEnd()
+{
+ return m_endReached;
+}
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MemoryStream !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MemoryStreamBase !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- void MemoryStream::Seek(SeekOrigin origin, Int64 offset)
+void MemoryStreamBase::seek(SeekOrigin origin, Int64 offset)
+{
+ Int64 pos = 0;
+ switch (origin)
{
- Int64 pos = 0;
- switch (origin)
- {
- case Slang::SeekOrigin::Start:
+ case SeekOrigin::Start:
pos = offset;
break;
- case Slang::SeekOrigin::End:
- pos = Int64(m_contents.getCount()) + offset;
+ case SeekOrigin::End:
+ pos = Int64(m_contentsSize) + offset;
break;
- case Slang::SeekOrigin::Current:
+ case SeekOrigin::Current:
pos = Int64(m_position) + offset;
break;
default:
throw NotSupportedException("Unsupported seek origin.");
break;
- }
+ }
- m_atEnd = false;
+ m_atEnd = false;
- // Clamp to the valid range
- pos = (pos < 0) ? 0 : pos;
- pos = (pos > Int64(m_contents.getCount())) ? Int64(m_contents.getCount()) : pos;
+ // Clamp to the valid range
+ pos = (pos < 0) ? 0 : pos;
+ pos = (pos > Int64(m_contentsSize)) ? Int64(m_contentsSize) : pos;
- m_position = UInt(pos);
+ m_position = UInt(pos);
+}
+
+Int64 MemoryStreamBase::read(void* buffer, Int64 length)
+{
+ if (!canRead())
+ {
+ throw IOException("Cannot read this stream.");
}
- Int64 MemoryStream::Read(void * buffer, Int64 length)
+ const Int64 maxRead = Int64(m_contentsSize - m_position);
+
+ if (maxRead == 0 && length > 0)
{
- if (!CanRead())
- {
- throw IOException("Cannot read this stream.");
- }
+ m_atEnd = true;
+ throw EndOfStreamException("End of file is reached.");
+ }
- const Int64 maxRead = Int64(m_contents.getCount() - m_position);
-
- if (maxRead == 0 && length > 0)
- {
- m_atEnd = true;
- throw EndOfStreamException("End of file is reached.");
- }
+ length = length > maxRead ? maxRead : length;
- length = length > maxRead ? maxRead : length;
+ ::memcpy(buffer, m_contents + m_position, size_t(length));
+ m_position += UInt(length);
+ return maxRead;
+}
- ::memcpy(buffer, m_contents.begin() + m_position, size_t(length));
- m_position += UInt(length);
- return maxRead;
- }
-
- Int64 MemoryStream::Write(const void * buffer, Int64 length)
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!! OwnedMemoryStream !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+Int64 OwnedMemoryStream::write(const void * buffer, Int64 length)
+{
+ if (!canWrite())
{
- if (!CanWrite())
- {
- throw IOException("Cannot write this stream.");
- }
+ throw IOException("Cannot write this stream.");
+ }
- if (m_position == m_contents.getCount())
- {
- m_contents.addRange((const uint8_t*)buffer, UInt(length));
- }
- else
- {
- m_contents.insertRange(m_position, (const uint8_t*)buffer, UInt(length));
- }
+ if (m_position == m_ownedContents.getCount())
+ {
+ m_ownedContents.addRange((const uint8_t*)buffer, UInt(length));
+ }
+ else
+ {
+ m_ownedContents.insertRange(m_position, (const uint8_t*)buffer, UInt(length));
+ }
- m_atEnd = false;
+ m_contents = m_ownedContents.getBuffer();
+ m_contentsSize = ptrdiff_t(m_ownedContents.getCount());
- m_position += UInt(length);
- return length;
- }
+ m_atEnd = false;
+ m_position += ptrdiff_t(length);
+ return length;
}
+
+} // namespace Slang
diff --git a/source/core/slang-stream.h b/source/core/slang-stream.h
index 67e04fa6a..8b8a6decf 100644
--- a/source/core/slang-stream.h
+++ b/source/core/slang-stream.h
@@ -5,109 +5,170 @@
namespace Slang
{
- class IOException : public Exception
- {
- public:
- IOException()
- {}
- IOException(const String & message)
- : Slang::Exception(message)
- {
- }
- };
-
- class EndOfStreamException : public IOException
- {
- public:
- EndOfStreamException()
- {}
- EndOfStreamException(const String & message)
- : IOException(message)
- {
- }
- };
-
- enum class SeekOrigin
- {
- Start, End, Current
- };
- class Stream : public RefObject
- {
- public:
- virtual ~Stream() {}
- virtual Int64 GetPosition()=0;
- virtual void Seek(SeekOrigin origin, Int64 offset)=0;
- virtual Int64 Read(void * buffer, Int64 length) = 0;
- virtual Int64 Write(const void * buffer, Int64 length) = 0;
- virtual bool IsEnd() = 0;
- virtual bool CanRead() = 0;
- virtual bool CanWrite() = 0;
- virtual void Close() = 0;
- };
-
- enum class FileMode
+class IOException : public Exception
+{
+public:
+ IOException()
+ {}
+ IOException(const String & message)
+ : Slang::Exception(message)
{
- Create, Open, CreateNew, Append
- };
+ }
+};
- enum class FileAccess
+class EndOfStreamException : public IOException
+{
+public:
+ EndOfStreamException()
+ {}
+ EndOfStreamException(const String & message)
+ : IOException(message)
{
- None = 0, Read = 1, Write = 2, ReadWrite = 3
- };
+ }
+};
- enum class FileShare
- {
- None, ReadOnly, WriteOnly, ReadWrite
- };
+enum class SeekOrigin
+{
+ Start, End, Current
+};
+
+class Stream : public RefObject
+{
+public:
+ virtual ~Stream() {}
+ virtual Int64 getPosition()=0;
+ virtual void seek(SeekOrigin origin, Int64 offset)=0;
+ virtual Int64 read(void * buffer, Int64 length) = 0;
+ virtual Int64 write(const void * buffer, Int64 length) = 0;
+ virtual bool isEnd() = 0;
+ virtual bool canRead() = 0;
+ virtual bool canWrite() = 0;
+ virtual void close() = 0;
+};
+
+enum class FileMode
+{
+ Create, Open, CreateNew, Append
+};
+
+enum class FileAccess
+{
+ None = 0, Read = 1, Write = 2, ReadWrite = 3
+};
- class MemoryStream : public Stream
+enum class FileShare
+{
+ None, ReadOnly, WriteOnly, ReadWrite
+};
+
+/// Base class for memory streams. Only supports reading and does NOT own contained data.
+class MemoryStreamBase : public Stream
+{
+public:
+ typedef Stream Super;
+
+ virtual Int64 getPosition() SLANG_OVERRIDE { return m_position; }
+ virtual void seek(SeekOrigin origin, Int64 offset) SLANG_OVERRIDE;
+ virtual Int64 read(void * buffer, Int64 length) SLANG_OVERRIDE;
+ virtual Int64 write(const void * buffer, Int64 length) SLANG_OVERRIDE { SLANG_UNUSED(buffer); SLANG_UNUSED(length); return 0; }
+ virtual bool isEnd() SLANG_OVERRIDE { return m_atEnd; }
+ virtual bool canRead() SLANG_OVERRIDE { return (int(m_access) & int(FileAccess::Read)) != 0; }
+ virtual bool canWrite() SLANG_OVERRIDE { return (int(m_access) & int(FileAccess::Write)) != 0; }
+ virtual void close() SLANG_OVERRIDE { m_access = FileAccess::None; }
+
+ MemoryStreamBase(FileAccess access = FileAccess::Read, const void* contents = nullptr, size_t contentsSize = 0):
+ m_access(access)
{
- public:
- virtual Int64 GetPosition() SLANG_OVERRIDE { return m_position; }
- virtual void Seek(SeekOrigin origin, Int64 offset) SLANG_OVERRIDE;
- virtual Int64 Read(void * buffer, Int64 length) SLANG_OVERRIDE;
- virtual Int64 Write(const void * buffer, Int64 length) SLANG_OVERRIDE;
- virtual bool IsEnd() SLANG_OVERRIDE { return m_atEnd; }
- virtual bool CanRead() SLANG_OVERRIDE { return (int(m_access) & int(FileAccess::Read)) != 0; }
- virtual bool CanWrite() SLANG_OVERRIDE { return (int(m_access) & int(FileAccess::Write)) != 0; }
- virtual void Close() SLANG_OVERRIDE { m_access = FileAccess::None; }
-
- MemoryStream(FileAccess access) :
- m_access(access),
- m_position(0),
- m_atEnd(false)
- {}
-
- Index m_position;
-
- bool m_atEnd; ///< Happens when a read is done and nothing can be returned because already at end
-
- FileAccess m_access;
- List<uint8_t> m_contents;
- };
-
- class FileStream : public Stream
- {
- private:
- FILE * handle;
- FileAccess fileAccess;
- bool endReached = false;
- void Init(const Slang::String & fileName, FileMode fileMode, FileAccess access, FileShare share);
- public:
- FileStream(const Slang::String & fileName, FileMode fileMode = FileMode::Open);
- FileStream(const Slang::String & fileName, FileMode fileMode, FileAccess access, FileShare share);
- ~FileStream();
- public:
- virtual Int64 GetPosition();
- virtual void Seek(SeekOrigin origin, Int64 offset);
- virtual Int64 Read(void * buffer, Int64 length);
- virtual Int64 Write(const void * buffer, Int64 length);
- virtual bool CanRead();
- virtual bool CanWrite();
- virtual void Close();
- virtual bool IsEnd();
- };
-}
+ _setContents(contents, contentsSize);
+ }
+
+protected:
+ /// Set to replace wholly current content with specified content
+ void _setContents(const void* contents, size_t contentsSize)
+ {
+ m_contents = (const uint8_t*)contents;
+ m_contentsSize = ptrdiff_t(contentsSize);
+ m_position = 0;
+ m_atEnd = false;
+ }
+ /// Update means that the content has changed, but position should be maintained
+ void _updateContents(const void* contents, size_t contentsSize)
+ {
+ const ptrdiff_t newPosition = (m_position > ptrdiff_t(contentsSize)) ? ptrdiff_t(contentsSize) : m_position;
+ _setContents(contents, contentsSize);
+ m_position = newPosition;
+ }
+
+ const uint8_t* m_contents; ///< The content held in the stream
+
+ // Using ptrdiff_t (as opposed to size_t) as makes maths simpler
+ ptrdiff_t m_contentsSize; ///< Total size of the content in bytes
+ ptrdiff_t m_position; ///< The current position within content (valid values can only be between 0 and m_contentSize)
+
+ bool m_atEnd; ///< Happens when a read is done and nothing can be returned because already at end
+
+ FileAccess m_access;
+};
+
+/// Memory stream that owns it's contents
+class OwnedMemoryStream : public MemoryStreamBase
+{
+public:
+ typedef MemoryStreamBase Super;
+
+ virtual Int64 write(const void* buffer, Int64 length) SLANG_OVERRIDE;
+
+ /// Set the contents
+ void setContent(const void* contents, size_t contentsSize)
+ {
+ m_ownedContents.setCount(contentsSize);
+ ::memcpy(m_ownedContents.getBuffer(), contents, contentsSize);
+ _setContents(m_ownedContents.getBuffer(), m_ownedContents.getCount());
+ }
+
+ void swapContents(List<uint8_t>& rhs)
+ {
+ rhs.swapWith(m_ownedContents);
+ _setContents(m_ownedContents.getBuffer(), m_ownedContents.getCount());
+ }
+
+ OwnedMemoryStream(FileAccess access) :
+ Super(access)
+ {}
+
+protected:
+
+ List<uint8_t> m_ownedContents;
+};
+
+class FileStream : public Stream
+{
+public:
+ typedef Stream Super;
+
+ // Stream interface
+ virtual Int64 getPosition();
+ virtual void seek(SeekOrigin origin, Int64 offset);
+ virtual Int64 read(void* buffer, Int64 length);
+ virtual Int64 write(const void* buffer, Int64 length);
+ virtual bool canRead();
+ virtual bool canWrite();
+ virtual void close();
+ virtual bool isEnd();
+
+ FileStream(const String& fileName, FileMode fileMode = FileMode::Open);
+ FileStream(const String& fileName, FileMode fileMode, FileAccess access, FileShare share);
+ ~FileStream();
+
+private:
+ void _init(const String& fileName, FileMode fileMode, FileAccess access, FileShare share);
+
+ FILE* m_handle;
+ FileAccess m_fileAccess;
+ bool m_endReached = false;
+};
+
+} // namespace Slang
#endif
diff --git a/source/core/slang-text-io.cpp b/source/core/slang-text-io.cpp
index 18039e41b..4e989b627 100644
--- a/source/core/slang-text-io.cpp
+++ b/source/core/slang-text-io.cpp
@@ -126,11 +126,11 @@ namespace Slang
this->encoding = encoding;
if (encoding == Encoding::UTF16)
{
- this->stream->Write(&Utf16Header, 2);
+ this->stream->write(&Utf16Header, 2);
}
else if (encoding == Encoding::UTF16Reversed)
{
- this->stream->Write(&Utf16ReversedHeader, 2);
+ this->stream->write(&Utf16ReversedHeader, 2);
}
}
StreamWriter::StreamWriter(RefPtr<Stream> stream, Encoding * encoding)
@@ -139,11 +139,11 @@ namespace Slang
this->encoding = encoding;
if (encoding == Encoding::UTF16)
{
- this->stream->Write(&Utf16Header, 2);
+ this->stream->write(&Utf16Header, 2);
}
else if (encoding == Encoding::UTF16Reversed)
{
- this->stream->Write(&Utf16ReversedHeader, 2);
+ this->stream->write(&Utf16ReversedHeader, 2);
}
}
void StreamWriter::Write(const String & str)
@@ -169,7 +169,7 @@ namespace Slang
sb << str[i];
}
encoding->GetBytes(encodingBuffer, sb.ProduceString());
- stream->Write(encodingBuffer.getBuffer(), encodingBuffer.getCount());
+ stream->write(encodingBuffer.getBuffer(), encodingBuffer.getCount());
}
void StreamWriter::Write(const char * str)
{
@@ -237,7 +237,7 @@ namespace Slang
{
buffer.setCount(4096);
memset(buffer.getBuffer(), 0, buffer.getCount() * sizeof(buffer[0]));
- auto len = stream->Read(buffer.getBuffer(), buffer.getCount());
+ auto len = stream->read(buffer.getBuffer(), buffer.getCount());
buffer.setCount((int)len);
ptr = 0;
}
@@ -248,7 +248,7 @@ namespace Slang
{
return buffer[ptr++];
}
- if (!stream->IsEnd())
+ if (!stream->isEnd())
ReadBuffer();
if (ptr<buffer.getCount())
{
diff --git a/source/core/slang-text-io.h b/source/core/slang-text-io.h
index ac9a4f5dc..b5a9ad0e1 100644
--- a/source/core/slang-text-io.h
+++ b/source/core/slang-text-io.h
@@ -259,7 +259,7 @@ namespace Slang
virtual void Write(const char * str);
virtual void Close()
{
- stream->Close();
+ stream->close();
}
void ReleaseStream()
{
@@ -300,11 +300,11 @@ namespace Slang
virtual String ReadToEnd();
virtual bool IsEnd()
{
- return ptr == buffer.getCount() && stream->IsEnd();
+ return ptr == buffer.getCount() && stream->isEnd();
}
virtual void Close()
{
- stream->Close();
+ stream->close();
}
void ReleaseStream()
{