diff options
Diffstat (limited to 'source/core')
| -rw-r--r-- | source/core/slang-string-slice-pool.h | 2 | ||||
| -rw-r--r-- | source/core/stream.cpp | 76 | ||||
| -rw-r--r-- | source/core/stream.h | 28 |
3 files changed, 105 insertions, 1 deletions
diff --git a/source/core/slang-string-slice-pool.h b/source/core/slang-string-slice-pool.h index c9c8b8db9..08cd819ab 100644 --- a/source/core/slang-string-slice-pool.h +++ b/source/core/slang-string-slice-pool.h @@ -50,6 +50,8 @@ public: /// Convert a handle to and index. (A handle is just an index!) static int asIndex(Handle handle) { return int(handle); } + /// Returns true if the handle is to a slice that contains characters (ie not null or empty) + static bool hasContents(Handle handle) { return int(handle) >= kNumDefaultHandles; } /// Ctor StringSlicePool(); diff --git a/source/core/stream.cpp b/source/core/stream.cpp index 949ce718c..19ae3cdea 100644 --- a/source/core/stream.cpp +++ b/source/core/stream.cpp @@ -153,6 +153,7 @@ namespace Slang 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: @@ -215,4 +216,79 @@ namespace Slang { return endReached; } + + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MemoryStream !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + void MemoryStream::Seek(SeekOrigin origin, Int64 offset) + { + Int64 pos = 0; + switch (origin) + { + case Slang::SeekOrigin::Start: + pos = offset; + break; + case Slang::SeekOrigin::End: + pos = Int64(m_contents.Count()) + offset; + break; + case Slang::SeekOrigin::Current: + pos = Int64(m_position) + offset; + break; + default: + throw NotSupportedException("Unsupported seek origin."); + break; + } + + m_atEnd = false; + + // Clamp to the valid range + pos = (pos < 0) ? 0 : pos; + pos = (pos > Int64(m_contents.Count())) ? Int64(m_contents.Count()) : pos; + + m_position = UInt(pos); + } + + Int64 MemoryStream::Read(void * buffer, Int64 length) + { + if (!CanRead()) + { + throw IOException("Cannot read this stream."); + } + + const Int64 maxRead = Int64(m_contents.Count() - m_position); + + if (maxRead == 0 && length > 0) + { + m_atEnd = true; + throw EndOfStreamException("End of file is reached."); + } + + length = length > maxRead ? maxRead : length; + + ::memcpy(buffer, m_contents.begin() + m_position, size_t(length)); + m_position += UInt(length); + return maxRead; + } + + Int64 MemoryStream::Write(const void * buffer, Int64 length) + { + if (!CanWrite()) + { + throw IOException("Cannot write this stream."); + } + + if (m_position == m_contents.Count()) + { + m_contents.AddRange((const uint8_t*)buffer, UInt(length)); + } + else + { + m_contents.InsertRange(m_position, (const uint8_t*)buffer, UInt(length)); + } + + m_atEnd = false; + + m_position += UInt(length); + return length; + } + } diff --git a/source/core/stream.h b/source/core/stream.h index 4eea6a909..67a3549e9 100644 --- a/source/core/stream.h +++ b/source/core/stream.h @@ -53,7 +53,7 @@ namespace Slang enum class FileAccess { - Read = 1, Write = 2, ReadWrite = 3 + None = 0, Read = 1, Write = 2, ReadWrite = 3 }; enum class FileShare @@ -61,6 +61,32 @@ namespace Slang None, ReadOnly, WriteOnly, ReadWrite }; + class MemoryStream : public Stream + { + 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) + {} + + UInt 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: |
